mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-503] Remove Tor functionality (#573)
This commit is contained in:
parent
cd719b1d5b
commit
d46857677f
@ -7,7 +7,6 @@ package addrmgr
|
||||
import (
|
||||
"container/list"
|
||||
crand "crypto/rand" // for seeding
|
||||
"encoding/base32"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"github.com/pkg/errors"
|
||||
@ -17,7 +16,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -894,24 +892,11 @@ func (a *AddrManager) reset() {
|
||||
a.addrTrying = make(map[*KnownAddress]bool)
|
||||
}
|
||||
|
||||
// HostToNetAddress returns a netaddress given a host address. If the address
|
||||
// is a Tor .onion address this will be taken care of. Else if the host is
|
||||
// not an IP address it will be resolved (via Tor if required).
|
||||
// HostToNetAddress returns a netaddress given a host address. If
|
||||
// the host is not an IP address it will be resolved.
|
||||
func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.ServiceFlag) (*wire.NetAddress, error) {
|
||||
// Tor address is 16 char base32 + ".onion"
|
||||
var ip net.IP
|
||||
if len(host) == 22 && host[16:] == ".onion" {
|
||||
// go base32 encoding uses capitals (as does the rfc
|
||||
// but Tor tend to user lowercase, so we switch
|
||||
// case here.
|
||||
data, err := base32.StdEncoding.DecodeString(
|
||||
strings.ToUpper(host[:16]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefix := []byte{0xfd, 0x87, 0xd8, 0x7e, 0xeb, 0x43}
|
||||
ip = net.IP(append(prefix, data...))
|
||||
} else if ip = net.ParseIP(host); ip == nil {
|
||||
ip := net.ParseIP(host)
|
||||
if ip == nil {
|
||||
ips, err := a.lookupFunc(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -925,25 +910,12 @@ func (a *AddrManager) HostToNetAddress(host string, port uint16, services wire.S
|
||||
return wire.NewNetAddressIPPort(ip, port, services), nil
|
||||
}
|
||||
|
||||
// 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 relevant .onion address.
|
||||
func ipString(na *wire.NetAddress) string {
|
||||
if IsOnionCatTor(na) {
|
||||
// We know now that na.IP is long enough.
|
||||
base32 := base32.StdEncoding.EncodeToString(na.IP[6:])
|
||||
return strings.ToLower(base32) + ".onion"
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
return net.JoinHostPort(ipString(na), port)
|
||||
return net.JoinHostPort(na.IP.String(), port)
|
||||
}
|
||||
|
||||
// GetAddress returns a single address that should be routable. It picks a
|
||||
@ -1287,18 +1259,6 @@ func getReachabilityFrom(localAddr, remoteAddr *wire.NetAddress) int {
|
||||
return Unreachable
|
||||
}
|
||||
|
||||
if IsOnionCatTor(remoteAddr) {
|
||||
if IsOnionCatTor(localAddr) {
|
||||
return Private
|
||||
}
|
||||
|
||||
if IsRoutable(localAddr) && IsIPv4(localAddr) {
|
||||
return Ipv4
|
||||
}
|
||||
|
||||
return Default
|
||||
}
|
||||
|
||||
if IsRFC4380(remoteAddr) {
|
||||
if !IsRoutable(localAddr) {
|
||||
return Default
|
||||
@ -1376,7 +1336,7 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net
|
||||
|
||||
// Send something unroutable if nothing suitable.
|
||||
var ip net.IP
|
||||
if !IsIPv4(remoteAddr) && !IsOnionCatTor(remoteAddr) {
|
||||
if !IsIPv4(remoteAddr) {
|
||||
ip = net.IPv6zero
|
||||
} else {
|
||||
ip = net.IPv4zero
|
||||
|
@ -24,11 +24,11 @@ generally helps provide greater peer diversity, and perhaps more importantly,
|
||||
drastically reduces the chances an attacker is able to coerce your peer into
|
||||
only connecting to nodes they control.
|
||||
|
||||
The address manager also understands routability and Tor addresses and tries
|
||||
hard to only return routable addresses. In addition, it uses the information
|
||||
provided by the caller about connected, known good, and attempted addresses to
|
||||
periodically purge peers which no longer appear to be good peers as well as
|
||||
bias the selection toward known good peers. The general idea is to make a best
|
||||
effort at only providing usable addresses.
|
||||
The address manager also understands routability and tries hard to only return
|
||||
routable addresses. In addition, it uses the information provided by the caller
|
||||
about connected, known good, and attempted addresses to periodically purge
|
||||
peers which no longer appear to be good peers as well as bias the selection
|
||||
toward known good peers. The general idea is to make a best effort at only
|
||||
providing usable addresses.
|
||||
*/
|
||||
package addrmgr
|
||||
|
@ -5,7 +5,6 @@
|
||||
package addrmgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/kaspanet/kaspad/config"
|
||||
@ -73,19 +72,6 @@ var (
|
||||
// rfc6598Net specifies the IPv4 block as defined by RFC6598 (100.64.0.0/10)
|
||||
rfc6598Net = ipNet("100.64.0.0", 10, 32)
|
||||
|
||||
// onionCatNet defines the IPv6 address block used to support Tor.
|
||||
// We encode 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, which is part part of the
|
||||
// RFC4193 unique local IPv6 range.
|
||||
//
|
||||
// In summary the format is:
|
||||
// { magic 6 bytes, 10 bytes base32 decode of key hash }
|
||||
onionCatNet = ipNet("fd87:d87e:eb43::", 48, 128)
|
||||
|
||||
// zero4Net defines the IPv4 address block for address staring with 0
|
||||
// (0.0.0.0/8).
|
||||
zero4Net = ipNet("0.0.0.0", 8, 32)
|
||||
@ -111,14 +97,6 @@ func IsLocal(na *wire.NetAddress) bool {
|
||||
return na.IP.IsLoopback() || zero4Net.Contains(na.IP)
|
||||
}
|
||||
|
||||
// IsOnionCatTor returns whether or not the passed address is in the IPv6 range
|
||||
// used by Kaspa to support Tor (fd87:d87e:eb43::/48). Note that this range
|
||||
// is the same range used by OnionCat, which is part of the RFC4193 unique local
|
||||
// IPv6 range.
|
||||
func IsOnionCatTor(na *wire.NetAddress) bool {
|
||||
return onionCatNet.Contains(na.IP)
|
||||
}
|
||||
|
||||
// IsRFC1918 returns whether or not the passed address is part of the IPv4
|
||||
// private network address space as defined by RFC1918 (10.0.0.0/8,
|
||||
// 172.16.0.0/12, or 192.168.0.0/16).
|
||||
@ -232,13 +210,12 @@ func IsRoutable(na *wire.NetAddress) bool {
|
||||
return IsValid(na) && !(IsRFC1918(na) || IsRFC2544(na) ||
|
||||
IsRFC3927(na) || IsRFC4862(na) || IsRFC3849(na) ||
|
||||
IsRFC4843(na) || IsRFC5737(na) || IsRFC6598(na) ||
|
||||
IsLocal(na) || (IsRFC4193(na) && !IsOnionCatTor(na)))
|
||||
IsLocal(na) || (IsRFC4193(na)))
|
||||
}
|
||||
|
||||
// GroupKey returns a string representing the network group an address is part
|
||||
// of. This is the /16 for IPv4, the /32 (/36 for he.net) for IPv6, the string
|
||||
// "local" for a local address, the string "tor:key" where key is the /4 of the
|
||||
// onion address for Tor address, and the string "unroutable" for an unroutable
|
||||
// "local" for a local address, and the string "unroutable" for an unroutable
|
||||
// address.
|
||||
func GroupKey(na *wire.NetAddress) string {
|
||||
if IsLocal(na) {
|
||||
@ -270,10 +247,6 @@ func GroupKey(na *wire.NetAddress) string {
|
||||
}
|
||||
return ip.Mask(net.CIDRMask(16, 32)).String()
|
||||
}
|
||||
if IsOnionCatTor(na) {
|
||||
// group is keyed off the first 4 bits of the actual onion key.
|
||||
return fmt.Sprintf("tor:%d", na.IP[6]&((1<<4)-1))
|
||||
}
|
||||
|
||||
// OK, so now we know ourselves to be a IPv6 address.
|
||||
// We use /32 for everything, except for Hurricane Electric's
|
||||
|
@ -202,9 +202,9 @@ func TestGroupKey(t *testing.T) {
|
||||
{name: "ipv6 rfc6145 translated ipv4", ip: "::ffff:0:0c01:0203", expected: "12.1.0.0"},
|
||||
|
||||
// Tor.
|
||||
{name: "ipv6 tor onioncat", ip: "fd87:d87e:eb43:1234::5678", expected: "tor:2"},
|
||||
{name: "ipv6 tor onioncat 2", ip: "fd87:d87e:eb43:1245::6789", expected: "tor:2"},
|
||||
{name: "ipv6 tor onioncat 3", ip: "fd87:d87e:eb43:1345::6789", expected: "tor:3"},
|
||||
{name: "ipv6 tor onioncat", ip: "fd87:d87e:eb43:1234::5678", expected: "unroutable"},
|
||||
{name: "ipv6 tor onioncat 2", ip: "fd87:d87e:eb43:1245::6789", expected: "unroutable"},
|
||||
{name: "ipv6 tor onioncat 3", ip: "fd87:d87e:eb43:1345::6789", expected: "unroutable"},
|
||||
|
||||
// IPv6 normal.
|
||||
{name: "ipv6 normal", ip: "2602:100::1", expected: "2602:100::"},
|
||||
|
112
config/config.go
112
config/config.go
@ -125,11 +125,6 @@ type Flags struct {
|
||||
Proxy string `long:"proxy" description:"Connect via SOCKS5 proxy (eg. 127.0.0.1:9050)"`
|
||||
ProxyUser string `long:"proxyuser" description:"Username for proxy server"`
|
||||
ProxyPass string `long:"proxypass" default-mask:"-" description:"Password for proxy server"`
|
||||
OnionProxy string // DISABLED UNTIL DECISION ABOUT TOR `long:"onion" description:"Connect to tor hidden services via SOCKS5 proxy (eg. 127.0.0.1:9050)"`
|
||||
OnionProxyUser string // DISABLED UNTIL DECISION ABOUT TOR `long:"onionuser" description:"Username for onion proxy server"`
|
||||
OnionProxyPass string // DISABLED UNTIL DECISION ABOUT TOR `long:"onionpass" default-mask:"-" description:"Password for onion proxy server"`
|
||||
NoOnion bool // DISABLED UNTIL DECISION ABOUT TOR `long:"noonion" description:"Disable connecting to tor hidden services"`
|
||||
TorIsolation bool // DISABLED UNTIL DECISION ABOUT TOR `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
|
||||
DbType string `long:"dbtype" description:"Database backend to use for the Block DAG"`
|
||||
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
|
||||
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
|
||||
@ -163,7 +158,6 @@ type Flags struct {
|
||||
type Config struct {
|
||||
*Flags
|
||||
Lookup func(string) ([]net.IP, error)
|
||||
OnionDial func(string, string, time.Duration) (net.Conn, error)
|
||||
Dial func(string, string, time.Duration) (net.Conn, error)
|
||||
MiningAddrs []util.Address
|
||||
MinRelayTxFee util.Amount
|
||||
@ -779,31 +773,11 @@ func loadConfig() (*Config, []string, error) {
|
||||
activeConfig.ConnectPeers = network.NormalizeAddresses(activeConfig.ConnectPeers,
|
||||
activeConfig.NetParams().DefaultPort)
|
||||
|
||||
// --noonion and --onion do not mix.
|
||||
if activeConfig.NoOnion && activeConfig.OnionProxy != "" {
|
||||
err := errors.Errorf("%s: the --noonion and --onion options may "+
|
||||
"not be activated at the same time", funcName)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Tor stream isolation requires either proxy or onion proxy to be set.
|
||||
if activeConfig.TorIsolation && activeConfig.Proxy == "" && activeConfig.OnionProxy == "" {
|
||||
str := "%s: Tor stream isolation requires either proxy or " +
|
||||
"onionproxy to be set"
|
||||
err := errors.Errorf(str, funcName)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Setup dial and DNS resolution (lookup) functions depending on the
|
||||
// specified options. The default is to use the standard
|
||||
// net.DialTimeout function as well as the system DNS resolver. When a
|
||||
// proxy is specified, the dial function is set to the proxy specific
|
||||
// dial function and the lookup is set to use tor (unless --noonion is
|
||||
// specified in which case the system DNS resolver is used).
|
||||
// dial function.
|
||||
activeConfig.Dial = net.DialTimeout
|
||||
activeConfig.Lookup = net.LookupIP
|
||||
if activeConfig.Proxy != "" {
|
||||
@ -816,90 +790,12 @@ func loadConfig() (*Config, []string, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Tor isolation flag means proxy credentials will be overridden
|
||||
// unless there is also an onion proxy configured in which case
|
||||
// that one will be overridden.
|
||||
torIsolation := false
|
||||
if activeConfig.TorIsolation && activeConfig.OnionProxy == "" &&
|
||||
(activeConfig.ProxyUser != "" || activeConfig.ProxyPass != "") {
|
||||
|
||||
torIsolation = true
|
||||
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
|
||||
"overriding specified proxy user credentials")
|
||||
}
|
||||
|
||||
proxy := &socks.Proxy{
|
||||
Addr: activeConfig.Proxy,
|
||||
Username: activeConfig.ProxyUser,
|
||||
Password: activeConfig.ProxyPass,
|
||||
TorIsolation: torIsolation,
|
||||
Addr: activeConfig.Proxy,
|
||||
Username: activeConfig.ProxyUser,
|
||||
Password: activeConfig.ProxyPass,
|
||||
}
|
||||
activeConfig.Dial = proxy.DialTimeout
|
||||
|
||||
// Treat the proxy as tor and perform DNS resolution through it
|
||||
// unless the --noonion flag is set or there is an
|
||||
// onion-specific proxy configured.
|
||||
if !activeConfig.NoOnion && activeConfig.OnionProxy == "" {
|
||||
activeConfig.Lookup = func(host string) ([]net.IP, error) {
|
||||
return network.TorLookupIP(host, activeConfig.Proxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup onion address dial function depending on the specified options.
|
||||
// The default is to use the same dial function selected above. However,
|
||||
// when an onion-specific proxy is specified, the onion address dial
|
||||
// function is set to use the onion-specific proxy while leaving the
|
||||
// normal dial function as selected above. This allows .onion address
|
||||
// traffic to be routed through a different proxy than normal traffic.
|
||||
if activeConfig.OnionProxy != "" {
|
||||
_, _, err := net.SplitHostPort(activeConfig.OnionProxy)
|
||||
if err != nil {
|
||||
str := "%s: Onion proxy address '%s' is invalid: %s"
|
||||
err := errors.Errorf(str, funcName, activeConfig.OnionProxy, err)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Tor isolation flag means onion proxy credentials will be
|
||||
// overridden.
|
||||
if activeConfig.TorIsolation &&
|
||||
(activeConfig.OnionProxyUser != "" || activeConfig.OnionProxyPass != "") {
|
||||
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
|
||||
"overriding specified onionproxy user "+
|
||||
"credentials ")
|
||||
}
|
||||
|
||||
activeConfig.OnionDial = func(network, addr string, timeout time.Duration) (net.Conn, error) {
|
||||
proxy := &socks.Proxy{
|
||||
Addr: activeConfig.OnionProxy,
|
||||
Username: activeConfig.OnionProxyUser,
|
||||
Password: activeConfig.OnionProxyPass,
|
||||
TorIsolation: activeConfig.TorIsolation,
|
||||
}
|
||||
return proxy.DialTimeout(network, addr, timeout)
|
||||
}
|
||||
|
||||
// When configured in bridge mode (both --onion and --proxy are
|
||||
// configured), it means that the proxy configured by --proxy is
|
||||
// not a tor proxy, so override the DNS resolution to use the
|
||||
// onion-specific proxy.
|
||||
if activeConfig.Proxy != "" {
|
||||
activeConfig.Lookup = func(host string) ([]net.IP, error) {
|
||||
return network.TorLookupIP(host, activeConfig.OnionProxy)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
activeConfig.OnionDial = activeConfig.Dial
|
||||
}
|
||||
|
||||
// Specifying --noonion means the onion address dial function results in
|
||||
// an error.
|
||||
if activeConfig.NoOnion {
|
||||
activeConfig.OnionDial = func(a, b string, t time.Duration) (net.Conn, error) {
|
||||
return nil, errors.New("tor has been disabled")
|
||||
}
|
||||
}
|
||||
|
||||
// Warn about missing config file only after all other configuration is
|
||||
|
@ -10,7 +10,7 @@ Package connmgr implements a generic Kaspa network connection manager.
|
||||
|
||||
Connection Manager handles all the general connection concerns such as
|
||||
maintaining a set number of outbound connections, sourcing peers, banning,
|
||||
limiting max connections, tor lookup, etc.
|
||||
limiting max connections, etc.
|
||||
|
||||
The package provides a generic connection manager which is able to accept
|
||||
connection requests from a source or a set of given addresses, dial them and
|
||||
|
@ -5,7 +5,7 @@ Connection Manager Overview
|
||||
|
||||
Connection Manager handles all the general connection concerns such as
|
||||
maintaining a set number of outbound connections, sourcing peers, banning,
|
||||
limiting max connections, tor lookup, etc.
|
||||
limiting max connections, etc.
|
||||
|
||||
The package provides a generic connection manager which is able to accept
|
||||
connection requests from a source or a set of given addresses, dial them and
|
||||
|
@ -28,24 +28,6 @@
|
||||
; proxyuser=
|
||||
; proxypass=
|
||||
|
||||
; The SOCKS5 proxy above is assumed to be Tor (https://www.torproject.org).
|
||||
; If the proxy is not tor the following may be used to prevent using tor
|
||||
; specific SOCKS queries to lookup addresses (this increases anonymity when tor
|
||||
; is used by preventing your IP being leaked via DNS).
|
||||
; noonion=1
|
||||
|
||||
; Use an alternative proxy to connect to .onion addresses. The proxy is assumed
|
||||
; to be a Tor node. Non .onion addresses will be contacted with the main proxy
|
||||
; or without a proxy if none is set.
|
||||
; onion=127.0.0.1:9051
|
||||
; onionuser=
|
||||
; onionpass=
|
||||
|
||||
; Enable Tor stream isolation by randomizing proxy user credentials resulting in
|
||||
; Tor creating a new circuit for each connection. This makes it more difficult
|
||||
; to correlate connections.
|
||||
; torisolation=1
|
||||
|
||||
; Use Universal Plug and Play (UPnP) to automatically open the listen port
|
||||
; and obtain the external IP address from supported devices. NOTE: This option
|
||||
; will have no effect if exernal IP addresses are specified.
|
||||
|
@ -68,28 +68,6 @@ var (
|
||||
userAgentVersion = version.Version()
|
||||
)
|
||||
|
||||
// onionAddr implements the net.Addr interface and represents a tor address.
|
||||
type onionAddr struct {
|
||||
addr string
|
||||
}
|
||||
|
||||
// String returns the onion address.
|
||||
//
|
||||
// This is part of the net.Addr interface.
|
||||
func (oa *onionAddr) String() string {
|
||||
return oa.addr
|
||||
}
|
||||
|
||||
// Network returns "onion".
|
||||
//
|
||||
// This is part of the net.Addr interface.
|
||||
func (oa *onionAddr) Network() string {
|
||||
return "onion"
|
||||
}
|
||||
|
||||
// Ensure onionAddr implements the net.Addr interface.
|
||||
var _ net.Addr = (*onionAddr)(nil)
|
||||
|
||||
// simpleAddr implements the net.Addr interface with two struct fields
|
||||
type simpleAddr struct {
|
||||
net, addr string
|
||||
@ -1899,16 +1877,6 @@ func addrStringToNetAddr(addr string) (net.Addr, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Tor addresses cannot be resolved to an IP, so just return an onion
|
||||
// address instead.
|
||||
if strings.HasSuffix(host, ".onion") {
|
||||
if config.ActiveConfig().NoOnion {
|
||||
return nil, errors.New("tor has been disabled")
|
||||
}
|
||||
|
||||
return &onionAddr{addr: addr}, nil
|
||||
}
|
||||
|
||||
// Attempt to look up an IP address associated with the parsed host.
|
||||
ips, err := serverutils.KaspadLookup(host)
|
||||
if err != nil {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/kaspanet/kaspad/rpcmodel"
|
||||
"github.com/kaspanet/kaspad/server/serverutils"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// handleGetManualNodeInfo handles getManualNodeInfo commands.
|
||||
@ -77,7 +76,7 @@ func getManualNodesInfo(s *Server, detailsArg *bool, node string) (interface{},
|
||||
|
||||
var ipList []string
|
||||
switch {
|
||||
case net.ParseIP(host) != nil, strings.HasSuffix(host, ".onion"):
|
||||
case net.ParseIP(host) != nil:
|
||||
ipList = make([]string, 1)
|
||||
ipList[0] = host
|
||||
default:
|
||||
|
@ -1,11 +1,9 @@
|
||||
package serverutils
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -34,17 +32,8 @@ type Peer struct {
|
||||
}
|
||||
|
||||
// KaspadLookup resolves the IP of the given host using the correct DNS lookup
|
||||
// function depending on the configuration options. For example, addresses will
|
||||
// be resolved using tor when the --proxy flag was specified unless --noonion
|
||||
// was also specified in which case the normal system DNS resolver will be used.
|
||||
//
|
||||
// Any attempt to resolve a tor address (.onion) will return an error since they
|
||||
// are not intended to be resolved outside of the tor proxy.
|
||||
// function depending on the configuration options.
|
||||
func KaspadLookup(host string) ([]net.IP, error) {
|
||||
if strings.HasSuffix(host, ".onion") {
|
||||
return nil, errors.Errorf("attempt to resolve tor address %s", host)
|
||||
}
|
||||
|
||||
return config.ActiveConfig().Lookup(host)
|
||||
}
|
||||
|
||||
@ -73,14 +62,7 @@ func GenCertPair(certFile, keyFile string) error {
|
||||
}
|
||||
|
||||
// KaspadDial connects to the address on the named network using the appropriate
|
||||
// dial function depending on the address and configuration options. For
|
||||
// example, .onion addresses will be dialed using the onion specific proxy if
|
||||
// one was specified, but will otherwise use the normal dial function (which
|
||||
// could itself use a proxy or not).
|
||||
// dial function depending on the address and configuration options.
|
||||
func KaspadDial(addr net.Addr) (net.Conn, error) {
|
||||
if strings.Contains(addr.String(), ".onion:") {
|
||||
return config.ActiveConfig().OnionDial(addr.Network(), addr.String(),
|
||||
config.DefaultConnectTimeout)
|
||||
}
|
||||
return config.ActiveConfig().Dial(addr.Network(), addr.String(), config.DefaultConnectTimeout)
|
||||
}
|
||||
|
@ -1,129 +0,0 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package network
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"github.com/pkg/errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
const (
|
||||
torSucceeded = 0x00
|
||||
torGeneralError = 0x01
|
||||
torNotAllowed = 0x02
|
||||
torNetUnreachable = 0x03
|
||||
torHostUnreachable = 0x04
|
||||
torConnectionRefused = 0x05
|
||||
torTTLExpired = 0x06
|
||||
torCmdNotSupported = 0x07
|
||||
torAddrNotSupported = 0x08
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTorInvalidAddressResponse indicates an invalid address was
|
||||
// returned by the Tor DNS resolver.
|
||||
ErrTorInvalidAddressResponse = errors.New("invalid address response")
|
||||
|
||||
// ErrTorInvalidProxyResponse indicates the Tor proxy returned a
|
||||
// response in an unexpected format.
|
||||
ErrTorInvalidProxyResponse = errors.New("invalid proxy response")
|
||||
|
||||
// ErrTorUnrecognizedAuthMethod indicates the authentication method
|
||||
// provided is not recognized.
|
||||
ErrTorUnrecognizedAuthMethod = errors.New("invalid proxy authentication method")
|
||||
|
||||
torStatusErrors = map[byte]error{
|
||||
torSucceeded: errors.New("tor succeeded"),
|
||||
torGeneralError: errors.New("tor general error"),
|
||||
torNotAllowed: errors.New("tor not allowed"),
|
||||
torNetUnreachable: errors.New("tor network is unreachable"),
|
||||
torHostUnreachable: errors.New("tor host is unreachable"),
|
||||
torConnectionRefused: errors.New("tor connection refused"),
|
||||
torTTLExpired: errors.New("tor TTL expired"),
|
||||
torCmdNotSupported: errors.New("tor command not supported"),
|
||||
torAddrNotSupported: errors.New("tor address type not supported"),
|
||||
}
|
||||
)
|
||||
|
||||
// TorLookupIP uses Tor to resolve DNS via the SOCKS extension they provide for
|
||||
// resolution over the Tor network. Tor itself doesn't support ipv6 so this
|
||||
// doesn't either.
|
||||
func TorLookupIP(host, proxy string) ([]net.IP, error) {
|
||||
conn, err := net.Dial("tcp", proxy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
buf := []byte{'\x05', '\x01', '\x00'}
|
||||
_, err = conn.Write(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf = make([]byte, 2)
|
||||
_, err = conn.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf[0] != '\x05' {
|
||||
return nil, ErrTorInvalidProxyResponse
|
||||
}
|
||||
if buf[1] != '\x00' {
|
||||
return nil, ErrTorUnrecognizedAuthMethod
|
||||
}
|
||||
|
||||
buf = make([]byte, 7+len(host))
|
||||
buf[0] = 5 // protocol version
|
||||
buf[1] = '\xF0' // Tor Resolve
|
||||
buf[2] = 0 // reserved
|
||||
buf[3] = 3 // Tor Resolve
|
||||
buf[4] = byte(len(host))
|
||||
copy(buf[5:], host)
|
||||
buf[5+len(host)] = 0 // Port 0
|
||||
|
||||
_, err = conn.Write(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf = make([]byte, 4)
|
||||
_, err = conn.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf[0] != 5 {
|
||||
return nil, ErrTorInvalidProxyResponse
|
||||
}
|
||||
if buf[1] != 0 {
|
||||
if int(buf[1]) >= len(torStatusErrors) {
|
||||
return nil, ErrTorInvalidProxyResponse
|
||||
} else if err := torStatusErrors[buf[1]]; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, ErrTorInvalidProxyResponse
|
||||
}
|
||||
if buf[3] != 1 {
|
||||
err := torStatusErrors[torGeneralError]
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf = make([]byte, 4)
|
||||
bytes, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if bytes != 4 {
|
||||
return nil, ErrTorInvalidAddressResponse
|
||||
}
|
||||
|
||||
r := binary.BigEndian.Uint32(buf)
|
||||
|
||||
addr := make([]net.IP, 1)
|
||||
addr[0] = net.IPv4(byte(r>>24), byte(r>>16), byte(r>>8), byte(r))
|
||||
|
||||
return addr, nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user