-
Notifications
You must be signed in to change notification settings - Fork 21
/
ext_btcd.go
48 lines (42 loc) · 1.54 KB
/
ext_btcd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Things borrowed from https://github.com/btcsuite/btcd/blob/master/addrmanager.go
// because "github.com/btcsuite/btcd" wouldn't import for some reason.
package main
import (
"encoding/base32"
"github.com/btcsuite/btcd/wire"
"net"
"strconv"
"strings"
)
var onioncatrange = net.IPNet{IP: net.ParseIP("FD87:d87e:eb43::"),
Mask: net.CIDRMask(48, 128)}
func Tor(na *wire.NetAddress) bool {
// bitcoind encodes a .onion address as a 16 byte number by decoding the
// address prior to the .onion (i.e. the key hash) base32 into a ten
// byte number. it then stores the first 6 bytes of the address as
// 0xfD, 0x87, 0xD8, 0x7e, 0xeb, 0x43
// this is the same range used by onioncat, part of the
// RFC4193 Unique local IPv6 range.
// In summary the format is:
// { magic 6 bytes, 10 bytes base32 decode of key hash }
return onioncatrange.Contains(na.IP)
}
// ipString returns a string for the ip from the provided NetAddress. If the
// ip is in the range used for tor addresses then it will be transformed into
// the relavent .onion address.
func ipString(na *wire.NetAddress) string {
if Tor(na) {
// We know now that na.IP is long enogh.
base32 := base32.StdEncoding.EncodeToString(na.IP[6:])
return strings.ToLower(base32) + ".onion"
} else {
return na.IP.String()
}
}
// NetAddressKey returns a string key in the form of ip:port for IPv4 addresses
// or [ip]:port for IPv6 addresses.
func NetAddressKey(na *wire.NetAddress) string {
port := strconv.FormatUint(uint64(na.Port), 10)
addr := net.JoinHostPort(ipString(na), port)
return addr
}