config: Refactor tor config options.

* Remove unnecessary onionlookup func.
* Disallow --noonion and --onion flag combination.
* Tor isolation flag - prefer onion proxy.
* Proper argument names in cfg.oniondial closure.
* btcdLookup - error on onion address.
* Bridge mode - use onion for lookup
This commit is contained in:
Javed Khan 2016-12-06 23:05:55 +05:30
parent 0efea24aa6
commit 91b7f5c1c8

View file

@ -147,7 +147,6 @@ type config struct {
DropAddrIndex bool `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."` DropAddrIndex bool `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."`
RelayNonStd bool `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."` RelayNonStd bool `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."`
RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."` RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."`
onionlookup func(string) ([]net.IP, error)
lookup func(string) ([]net.IP, error) lookup func(string) ([]net.IP, error)
oniondial func(string, string, time.Duration) (net.Conn, error) oniondial func(string, string, time.Duration) (net.Conn, error)
dial func(string, string, time.Duration) (net.Conn, error) dial func(string, string, time.Duration) (net.Conn, error)
@ -796,6 +795,15 @@ func loadConfig() (*config, []string, error) {
cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers, cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers,
activeNetParams.DefaultPort) activeNetParams.DefaultPort)
// --noonion and --onion do not mix.
if cfg.NoOnion && cfg.OnionProxy != "" {
err := fmt.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. // Tor stream isolation requires either proxy or onion proxy to be set.
if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" { if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" {
str := "%s: Tor stream isolation requires either proxy or " + str := "%s: Tor stream isolation requires either proxy or " +
@ -824,8 +832,14 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err return nil, nil, err
} }
if cfg.TorIsolation && // 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 cfg.TorIsolation && cfg.OnionProxy == "" &&
(cfg.ProxyUser != "" || cfg.ProxyPass != "") { (cfg.ProxyUser != "" || cfg.ProxyPass != "") {
torIsolation = true
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+ fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
"overriding specified proxy user credentials") "overriding specified proxy user credentials")
} }
@ -834,24 +848,26 @@ func loadConfig() (*config, []string, error) {
Addr: cfg.Proxy, Addr: cfg.Proxy,
Username: cfg.ProxyUser, Username: cfg.ProxyUser,
Password: cfg.ProxyPass, Password: cfg.ProxyPass,
TorIsolation: cfg.TorIsolation, TorIsolation: torIsolation,
} }
cfg.dial = proxy.DialTimeout cfg.dial = proxy.DialTimeout
if !cfg.NoOnion {
// 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 !cfg.NoOnion && cfg.OnionProxy == "" {
cfg.lookup = func(host string) ([]net.IP, error) { cfg.lookup = func(host string) ([]net.IP, error) {
return connmgr.TorLookupIP(host, cfg.Proxy) return connmgr.TorLookupIP(host, cfg.Proxy)
} }
} }
} }
// Setup onion address dial and DNS resolution (lookup) functions // Setup onion address dial function depending on the specified options.
// depending on the specified options. The default is to use the // The default is to use the same dial function selected above. However,
// same dial and lookup functions selected above. However, when an // when an onion-specific proxy is specified, the onion address dial
// onion-specific proxy is specified, the onion address dial and // function is set to use the onion-specific proxy while leaving the
// lookup functions are set to use the onion-specific proxy while // normal dial function as selected above. This allows .onion address
// leaving the normal dial and lookup functions as selected above. // traffic to be routed through a different proxy than normal traffic.
// This allows .onion address traffic to be routed through a different
// proxy than normal traffic.
if cfg.OnionProxy != "" { if cfg.OnionProxy != "" {
_, _, err := net.SplitHostPort(cfg.OnionProxy) _, _, err := net.SplitHostPort(cfg.OnionProxy)
if err != nil { if err != nil {
@ -862,6 +878,8 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err return nil, nil, err
} }
// Tor isolation flag means onion proxy credentials will be
// overridden.
if cfg.TorIsolation && if cfg.TorIsolation &&
(cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") { (cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") {
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+ fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
@ -869,32 +887,35 @@ func loadConfig() (*config, []string, error) {
"credentials ") "credentials ")
} }
cfg.oniondial = func(a, b string, t time.Duration) (net.Conn, error) { cfg.oniondial = func(network, addr string, timeout time.Duration) (net.Conn, error) {
proxy := &socks.Proxy{ proxy := &socks.Proxy{
Addr: cfg.OnionProxy, Addr: cfg.OnionProxy,
Username: cfg.OnionProxyUser, Username: cfg.OnionProxyUser,
Password: cfg.OnionProxyPass, Password: cfg.OnionProxyPass,
TorIsolation: cfg.TorIsolation, TorIsolation: cfg.TorIsolation,
} }
return proxy.DialTimeout(a, b, t) return proxy.DialTimeout(network, addr, timeout)
} }
cfg.onionlookup = func(host string) ([]net.IP, error) {
// 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 cfg.Proxy != "" {
cfg.lookup = func(host string) ([]net.IP, error) {
return connmgr.TorLookupIP(host, cfg.OnionProxy) return connmgr.TorLookupIP(host, cfg.OnionProxy)
} }
}
} else { } else {
cfg.oniondial = cfg.dial cfg.oniondial = cfg.dial
cfg.onionlookup = cfg.lookup
} }
// Specifying --noonion means the onion address dial and DNS resolution // Specifying --noonion means the onion address dial function results in
// (lookup) functions result in an error. // an error.
if cfg.NoOnion { if cfg.NoOnion {
cfg.oniondial = func(a, b string, t time.Duration) (net.Conn, error) { cfg.oniondial = func(a, b string, t time.Duration) (net.Conn, error) {
return nil, errors.New("tor has been disabled") return nil, errors.New("tor has been disabled")
} }
cfg.onionlookup = func(a string) ([]net.IP, error) {
return nil, errors.New("tor has been disabled")
}
} }
// Warn about missing config file only after all other configuration is // Warn about missing config file only after all other configuration is
@ -987,16 +1008,17 @@ func btcdDial(addr net.Addr) (net.Conn, error) {
return cfg.dial(addr.Network(), addr.String(), defaultConnectTimeout) return cfg.dial(addr.Network(), addr.String(), defaultConnectTimeout)
} }
// btcdLookup returns the correct DNS lookup function to use depending on the // btcdLookup resolves the IP of the given host using the correct DNS lookup
// passed host and configuration options. For example, .onion addresses will be // function depending on the configuration options. For example, addresses will
// resolved using the onion specific proxy if one was specified, but will // be resolved using tor when the --proxy flag was specified unless --noonion
// otherwise treat the normal proxy as tor unless --noonion was specified in // was also specified in which case the normal system DNS resolver will be used.
// which case the lookup will fail. Meanwhile, normal IP addresses will be //
// resolved using tor if a proxy was specified unless --noonion was also // Any attempt to resolve a tor address (.onion) will return an error since they
// specified in which case the normal system DNS resolver will be used. // are not intended to be resolved outside of the tor proxy.
func btcdLookup(host string) ([]net.IP, error) { func btcdLookup(host string) ([]net.IP, error) {
if strings.HasSuffix(host, ".onion") { if strings.HasSuffix(host, ".onion") {
return cfg.onionlookup(host) return nil, fmt.Errorf("attempt to resolve tor address %s", host)
} }
return cfg.lookup(host) return cfg.lookup(host)
} }