diff --git a/config.go b/config.go index 0a6b07a5..a005ee76 100644 --- a/config.go +++ b/config.go @@ -191,7 +191,7 @@ type config struct { Alias string `long:"alias" description:"The node alias. Used as a moniker by peers and intelligence services"` Color string `long:"color" description:"The color of the node in hex format (i.e. '#3399FF'). Used to customize node appearance in intelligence services"` - net *torsvc.MultiNet + net torsvc.Net } // loadConfig initializes and parses the config using a config file and command @@ -301,7 +301,7 @@ func loadConfig() (*config, error) { // functions. When Tor's proxy is specified, the dial function is set to // the proxy specific dial function and the DNS resolution functions use // Tor. - cfg.net = &torsvc.MultiNet{Tor: false} + cfg.net = &torsvc.RegularNet{} if cfg.Tor.Socks != "" && cfg.Tor.DNS != "" { // Validate Tor port number torport, err := strconv.Atoi(cfg.Tor.Socks) @@ -323,8 +323,10 @@ func loadConfig() (*config, error) { return nil, err } - cfg.net.TorDNS = cfg.Tor.DNS - cfg.net.TorSocks = cfg.Tor.Socks + cfg.net = &torsvc.TorProxyNet{ + TorDNS: cfg.Tor.DNS, + TorSocks: cfg.Tor.Socks, + } // If we are using Tor, since we only want connections routed // through Tor, listening is disabled. diff --git a/torsvc/interface.go b/torsvc/interface.go index 6853c1ff..451615d9 100644 --- a/torsvc/interface.go +++ b/torsvc/interface.go @@ -4,10 +4,21 @@ import ( "net" ) -// Net is an interface housing a Dial function and several DNS functions. +// Net is an interface housing a Dial function and several DNS functions, to +// abstract the implementation of these functions over both Regular and Tor type Net interface { + // Dial accepts a network and address and returns a connection to a remote + // peer. Dial(string, string) (net.Conn, error) + + // LookupHost performs DNS resolution on a given hostname and returns + // addresses of that hostname LookupHost(string) ([]string, error) + + // LookupSRV allows a service and network to be specified and makes queries + // to a given DNS server for SRV queries. LookupSRV(string, string, string) (string, []*net.SRV, error) + + // ResolveTCPAddr is a used to resolve publicly advertised TCP addresses. ResolveTCPAddr(string, string) (*net.TCPAddr, error) } diff --git a/torsvc/net.go b/torsvc/net.go index de528ce9..0a5576fd 100644 --- a/torsvc/net.go +++ b/torsvc/net.go @@ -5,54 +5,66 @@ import ( "net" ) -// MultiNet is an implementation of the Net interface that abstracts away the -// "net" and "torsvc" functions from the user. This can be used to "switch" -// Tor functionality on/off based on the MultiNet.Tor boolean. MultiNet allows -// for callers to call net functions when necessary and torsvc functions when -// necessary -type MultiNet struct { - Tor bool - TorDNS string - TorSocks string -} +// RegularNet is an implementation of the Net interface that defines behaviour +// for Regular network connections +type RegularNet struct{} -// A compile time check to ensure MultiNet implements the Net interface. -var _ Net = (*MultiNet)(nil) - -// Dial uses either the "net" or "torsvc" dial function. -func (m *MultiNet) Dial(network, address string) (net.Conn, error) { - if m.Tor { - if network != "tcp" { - return nil, fmt.Errorf("Cannot dial non-tcp network via Tor") - } - return TorDial(address, m.TorSocks) - } +// Dial on the regular network uses net.Dial +func (r *RegularNet) Dial(network, address string) (net.Conn, error) { return net.Dial(network, address) } -// LookupHost uses either the "net" or "torsvc LookupHost function. -func (m *MultiNet) LookupHost(host string) ([]string, error) { - if m.Tor { - return TorLookupHost(host, m.TorSocks) - } +// LookupHost for regular network uses the net.LookupHost function +func (r *RegularNet) LookupHost(host string) ([]string, error) { return net.LookupHost(host) } -// LookupSRV uses either the "net" or "torsvc" LookupSRV function. -func (m *MultiNet) LookupSRV(service, proto, name string) (string, []*net.SRV, error) { - if m.Tor { - return TorLookupSRV(service, proto, name, m.TorSocks, m.TorDNS) - } +// LookupSRV for regular network uses net.LookupSRV function +func (r *RegularNet) LookupSRV(service, proto, name string) (string, []*net.SRV, error) { return net.LookupSRV(service, proto, name) } -// ResolveTCPAddr uses either the "net" or "torsvc" ResolveTCP function. -func (m *MultiNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { - if m.Tor { - if network != "tcp" { - return nil, fmt.Errorf("Cannot dial non-tcp network via Tor") - } - return TorResolveTCP(address, m.TorSocks) - } +// ResolveTCPAddr for regular network uses net.ResolveTCPAddr function +func (r *RegularNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { return net.ResolveTCPAddr(network, address) } + +// TorProxyNet is an implementation of the Net interface that defines behaviour +// for Tor network connections +type TorProxyNet struct { + // TorDNS is the IP:PORT of the DNS server for Tor to use for SRV queries + TorDNS string + + // TorSocks is the port which Tor's exposed SOCKS5 proxy is listening on. + // This is used for an outbound-only mode, so the node will not listen for + // incoming connections + TorSocks string +} + +// Dial on the Tor network uses the torsvc TorDial() function, and requires +// that network specified be tcp because only that is supported +func (t *TorProxyNet) Dial(network, address string) (net.Conn, error) { + if network != "tcp" { + return nil, fmt.Errorf("Cannot dial non-tcp network via Tor") + } + return TorDial(address, t.TorSocks) +} + +// LookupHost on Tor network uses the torsvc TorLookupHost function. +func (t *TorProxyNet) LookupHost(host string) ([]string, error) { + return TorLookupHost(host, t.TorSocks) +} + +// LookupSRV on Tor network uses the torsvc TorLookupHost function. +func (t *TorProxyNet) LookupSRV(service, proto, name string) (string, []*net.SRV, error) { + return TorLookupSRV(service, proto, name, t.TorSocks, t.TorDNS) +} + +// ResolveTCPAddr on Tor network uses the towsvc TorResolveTCP function, and +// requires network to be "tcp" because only "tcp" is supported +func (t *TorProxyNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { + if network != "tcp" { + return nil, fmt.Errorf("Cannot dial non-tcp network via Tor") + } + return TorResolveTCP(address, t.TorSocks) +}