server: Fix connections to onion nodes.
A DNS lookup was being attempted on onion addresses causing connections to fail. This has been fixed by introducing type onionAddr (which implements a net.Addr interface) and passing it to btcdDial. Also, the following onion related fixes have been made: * getaddednodeinfo - updated to handle onion addrs. * TorLookupIP - fixed err being shadowed. * newServer - rename tcpAddr to netAddr * addrStringToNetAddr - skip if host is already an IP addr. * addrStringToNetAddr - err if tor is disabled * getaddednodeinfo - check if host is already an IP addr.
This commit is contained in:
parent
91b7f5c1c8
commit
8caa921ac3
3 changed files with 63 additions and 18 deletions
|
@ -102,7 +102,7 @@ func TorLookupIP(host, proxy string) ([]net.IP, error) {
|
||||||
if int(buf[1]) > len(torStatusErrors) {
|
if int(buf[1]) > len(torStatusErrors) {
|
||||||
err = ErrTorInvalidProxyResponse
|
err = ErrTorInvalidProxyResponse
|
||||||
} else {
|
} else {
|
||||||
err := torStatusErrors[buf[1]]
|
err = torStatusErrors[buf[1]]
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = ErrTorInvalidProxyResponse
|
err = ErrTorInvalidProxyResponse
|
||||||
}
|
}
|
||||||
|
|
16
rpcserver.go
16
rpcserver.go
|
@ -919,18 +919,24 @@ func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan stru
|
||||||
host = peer.Addr()
|
host = peer.Addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ipList []string
|
||||||
|
switch {
|
||||||
|
case net.ParseIP(host) != nil, strings.HasSuffix(host, ".onion"):
|
||||||
|
ipList = make([]string, 1)
|
||||||
|
ipList[0] = host
|
||||||
|
default:
|
||||||
// Do a DNS lookup for the address. If the lookup fails, just
|
// Do a DNS lookup for the address. If the lookup fails, just
|
||||||
// use the host.
|
// use the host.
|
||||||
var ipList []string
|
|
||||||
ips, err := btcdLookup(host)
|
ips, err := btcdLookup(host)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
|
ipList = make([]string, 1)
|
||||||
|
ipList[0] = host
|
||||||
|
break
|
||||||
|
}
|
||||||
ipList = make([]string, 0, len(ips))
|
ipList = make([]string, 0, len(ips))
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
ipList = append(ipList, ip.String())
|
ipList = append(ipList, ip.String())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ipList = make([]string, 1)
|
|
||||||
ipList[0] = host
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the addresses and connection info to the result.
|
// Add the addresses and connection info to the result.
|
||||||
|
|
59
server.go
59
server.go
|
@ -65,6 +65,28 @@ var (
|
||||||
userAgentVersion = fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
|
userAgentVersion = fmt.Sprintf("%d.%d.%d", appMajor, appMinor, appPatch)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
// broadcastMsg provides the ability to house a bitcoin message to be broadcast
|
// broadcastMsg provides the ability to house a bitcoin message to be broadcast
|
||||||
// to all connected peers except specified excluded peers.
|
// to all connected peers except specified excluded peers.
|
||||||
type broadcastMsg struct {
|
type broadcastMsg struct {
|
||||||
|
@ -2469,13 +2491,13 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||||
permanentPeers = cfg.AddPeers
|
permanentPeers = cfg.AddPeers
|
||||||
}
|
}
|
||||||
for _, addr := range permanentPeers {
|
for _, addr := range permanentPeers {
|
||||||
tcpAddr, err := addrStringToNetAddr(addr)
|
netAddr, err := addrStringToNetAddr(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go s.connManager.Connect(&connmgr.ConnReq{
|
go s.connManager.Connect(&connmgr.ConnReq{
|
||||||
Addr: tcpAddr,
|
Addr: netAddr,
|
||||||
Permanent: true,
|
Permanent: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2499,16 +2521,38 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||||
|
|
||||||
// addrStringToNetAddr takes an address in the form of 'host:port' and returns
|
// addrStringToNetAddr takes an address in the form of 'host:port' and returns
|
||||||
// a net.Addr which maps to the original address with any host names resolved
|
// a net.Addr which maps to the original address with any host names resolved
|
||||||
// to IP addresses.
|
// to IP addresses. It also handles tor addresses properly by returning a
|
||||||
|
// net.Addr that encapsulates the address.
|
||||||
func addrStringToNetAddr(addr string) (net.Addr, error) {
|
func addrStringToNetAddr(addr string) (net.Addr, error) {
|
||||||
host, strPort, err := net.SplitHostPort(addr)
|
host, strPort, err := net.SplitHostPort(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port, err := strconv.Atoi(strPort)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if host is already an IP address.
|
||||||
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
|
return &net.TCPAddr{
|
||||||
|
IP: ip,
|
||||||
|
Port: port,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tor addresses cannot be resolved to an IP, so just return an onion
|
||||||
|
// address instead.
|
||||||
|
if strings.HasSuffix(host, ".onion") {
|
||||||
|
if cfg.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.
|
// Attempt to look up an IP address associated with the parsed host.
|
||||||
// The btcdLookup function will transparently handle performing the
|
|
||||||
// lookup over Tor if necessary.
|
|
||||||
ips, err := btcdLookup(host)
|
ips, err := btcdLookup(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -2517,11 +2561,6 @@ func addrStringToNetAddr(addr string) (net.Addr, error) {
|
||||||
return nil, fmt.Errorf("no addresses found for %s", host)
|
return nil, fmt.Errorf("no addresses found for %s", host)
|
||||||
}
|
}
|
||||||
|
|
||||||
port, err := strconv.Atoi(strPort)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &net.TCPAddr{
|
return &net.TCPAddr{
|
||||||
IP: ips[0],
|
IP: ips[0],
|
||||||
Port: port,
|
Port: port,
|
||||||
|
|
Loading…
Reference in a new issue