btc-crawl/ext_btcd.go

49 lines
1.5 KiB
Go

// Things borrowed from https://github.com/conformal/btcd/blob/master/addrmanager.go
// because "github.com/conformal/btcd" wouldn't import for some reason.
package main
import (
"encoding/base32"
"github.com/conformal/btcwire"
"net"
"strconv"
"strings"
)
var onioncatrange = net.IPNet{IP: net.ParseIP("FD87:d87e:eb43::"),
Mask: net.CIDRMask(48, 128)}
func Tor(na *btcwire.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 *btcwire.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 *btcwire.NetAddress) string {
port := strconv.FormatUint(uint64(na.Port), 10)
addr := net.JoinHostPort(ipString(na), port)
return addr
}