torsvc: Replace MultiNet with polymorphic Net interface

This commit is contained in:
MeshCollider 2018-01-23 16:59:15 +13:00 committed by Olaoluwa Osuntokun
parent 4affab7bd7
commit 69f207e23f
3 changed files with 69 additions and 44 deletions

@ -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.

@ -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)
}

@ -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)
}