server: use advertised address when reestablishing inbound connections

In this commit, we update the way we reestablish inbound connections if
we lose connectivity to a node we have an open channel with. Rather than
fetching the node's advertised port, we'll fetch one of their advertised
addresses instead. This ensure that if the remote node is running behind
a proxy, we do not see the proxy's address.
This commit is contained in:
Wilmer Paulino 2018-05-02 02:30:56 -04:00
parent 5b58d24f78
commit 08f80b6cf3
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

View File

@ -1542,17 +1542,18 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq,
addr := conn.RemoteAddr() addr := conn.RemoteAddr()
pubKey := brontideConn.RemotePub() pubKey := brontideConn.RemotePub()
// We'll ensure that we locate the proper port to use within the peer's // We'll ensure that we locate an advertised address to use within the
// address for reconnecting purposes. // peer's address for reconnection purposes.
if tcpAddr, ok := addr.(*net.TCPAddr); ok && !inbound { //
targetPort := s.fetchNodeAdvertisedPort(pubKey, tcpAddr) // TODO: leave the address field empty if there aren't any?
if !inbound {
// Once we have the correct port, we'll make a new copy of the advertisedAddr, err := s.fetchNodeAdvertisedAddr(pubKey)
// address so we don't modify the underlying pointer directly. if err != nil {
addr = &net.TCPAddr{ srvrLog.Errorf("Unable to retrieve advertised address "+
IP: tcpAddr.IP, "for node %x: %v", pubKey.SerializeCompressed(),
Port: targetPort, err)
Zone: tcpAddr.Zone, } else {
addr = advertisedAddr
} }
} }
@ -2231,42 +2232,16 @@ func computeNextBackoff(currBackoff time.Duration) time.Duration {
return nextBackoff + (time.Duration(wiggle.Uint64()) - margin/2) return nextBackoff + (time.Duration(wiggle.Uint64()) - margin/2)
} }
// fetchNodeAdvertisedPort attempts to fetch the advertised port of the target // fetchNodeAdvertisedAddr attempts to fetch an advertised address of a node.
// node. If a port isn't found, then the default port will be used. func (s *server) fetchNodeAdvertisedAddr(pub *btcec.PublicKey) (net.Addr, error) {
func (s *server) fetchNodeAdvertisedPort(pub *btcec.PublicKey,
targetAddr *net.TCPAddr) int {
// If the target port is already the default peer port, then we'll
// return that.
if targetAddr.Port == defaultPeerPort {
return defaultPeerPort
}
node, err := s.chanDB.ChannelGraph().FetchLightningNode(pub) node, err := s.chanDB.ChannelGraph().FetchLightningNode(pub)
// If the node wasn't found, then we'll just return the current default
// port.
if err != nil { if err != nil {
return defaultPeerPort return nil, err
} }
// Otherwise, we'll attempt to find a matching advertised IP, and will if len(node.Addresses) == 0 {
// then use the port for that. return nil, errors.New("no advertised addresses found")
for _, addr := range node.Addresses {
// We'll only examine an address if it's a TCP address.
tcpAddr, ok := addr.(*net.TCPAddr)
if !ok {
continue
}
// If this is the matching IP, then we'll return the port that
// it has been advertised with.
if tcpAddr.IP.Equal(targetAddr.IP) {
return tcpAddr.Port
}
} }
// If we couldn't find a matching IP, then we'll just return the return node.Addresses[0], nil
// default port.
return defaultPeerPort
} }