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."`
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."`
onionlookup func(string) ([]net.IP, error)
lookup func(string) ([]net.IP, error)
oniondial 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,
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.
if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" {
str := "%s: Tor stream isolation requires either proxy or " +
@ -824,8 +832,14 @@ func loadConfig() (*config, []string, error) {
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 != "") {
torIsolation = true
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
"overriding specified proxy user credentials")
}
@ -834,24 +848,26 @@ func loadConfig() (*config, []string, error) {
Addr: cfg.Proxy,
Username: cfg.ProxyUser,
Password: cfg.ProxyPass,
TorIsolation: cfg.TorIsolation,
TorIsolation: torIsolation,
}
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) {
return connmgr.TorLookupIP(host, cfg.Proxy)
}
}
}
// Setup onion address dial and DNS resolution (lookup) functions
// depending on the specified options. The default is to use the
// same dial and lookup functions selected above. However, when an
// onion-specific proxy is specified, the onion address dial and
// lookup functions are set to use the onion-specific proxy while
// leaving the normal dial and lookup functions as selected above.
// This allows .onion address traffic to be routed through a different
// proxy than normal traffic.
// 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 cfg.OnionProxy != "" {
_, _, err := net.SplitHostPort(cfg.OnionProxy)
if err != nil {
@ -862,6 +878,8 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err
}
// Tor isolation flag means onion proxy credentials will be
// overridden.
if cfg.TorIsolation &&
(cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") {
fmt.Fprintln(os.Stderr, "Tor isolation set -- "+
@ -869,32 +887,35 @@ func loadConfig() (*config, []string, error) {
"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{
Addr: cfg.OnionProxy,
Username: cfg.OnionProxyUser,
Password: cfg.OnionProxyPass,
TorIsolation: cfg.TorIsolation,
}
return proxy.DialTimeout(a, b, t)
return proxy.DialTimeout(network, addr, timeout)
}
cfg.onionlookup = func(host string) ([]net.IP, error) {
return connmgr.TorLookupIP(host, cfg.OnionProxy)
// 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)
}
}
} else {
cfg.oniondial = cfg.dial
cfg.onionlookup = cfg.lookup
}
// Specifying --noonion means the onion address dial and DNS resolution
// (lookup) functions result in an error.
// Specifying --noonion means the onion address dial function results in
// an error.
if cfg.NoOnion {
cfg.oniondial = func(a, b string, t time.Duration) (net.Conn, error) {
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
@ -987,16 +1008,17 @@ func btcdDial(addr net.Addr) (net.Conn, error) {
return cfg.dial(addr.Network(), addr.String(), defaultConnectTimeout)
}
// btcdLookup returns the correct DNS lookup function to use depending on the
// passed host and configuration options. For example, .onion addresses will be
// resolved using the onion specific proxy if one was specified, but will
// otherwise treat the normal proxy as tor unless --noonion was specified in
// which case the lookup will fail. Meanwhile, normal IP addresses will be
// resolved using tor if a proxy was specified unless --noonion was also
// specified in which case the normal system DNS resolver will be used.
// btcdLookup 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.
func btcdLookup(host string) ([]net.IP, error) {
if strings.HasSuffix(host, ".onion") {
return cfg.onionlookup(host)
return nil, fmt.Errorf("attempt to resolve tor address %s", host)
}
return cfg.lookup(host)
}