diff --git a/Bootstrap.go b/Bootstrap.go index 77c3ce1..7f1fc5f 100644 --- a/Bootstrap.go +++ b/Bootstrap.go @@ -226,12 +226,24 @@ func (peer *PeerInfo) cmdResponseBootstrapFindSelf(msg *MessageResponse, closest } for _, closePeer := range closest { + // Use the self-reported external port if available. + port := closePeer.Port + if closePeer.PortReportedExternal > 0 { + port = closePeer.PortReportedExternal + } + // Initiate contact. Once a response comes back, the peer is actually added to the list. - if contactArbitraryPeer(closePeer.PublicKey, []*net.UDPAddr{{IP: closePeer.IP, Port: int(closePeer.Port)}}) { + if contactArbitraryPeer(closePeer.PublicKey, []*net.UDPAddr{{IP: closePeer.IP, Port: int(port)}}) { // Blacklist the target Peer ID, IP:Port for contact in the next 10 minutes. // TODO } + // If NAT is detected and the port is not forwarded, send a Traverse message. + // NAT detection is the same algorithm as peer.IsBehindNAT. + if closePeer.PortReportedExternal == 0 && closePeer.Port != closePeer.PortReportedInternal { + // TODO send traverse message + } + } } diff --git a/Peer ID.go b/Peer ID.go index 6e99aed..e8ff223 100644 --- a/Peer ID.go +++ b/Peer ID.go @@ -196,7 +196,14 @@ func record2Peer(record PeerRecord, network *Network) (peerN *PeerInfo) { } // Create temporary peer which is not added to the global list and not added to Kademlia. - connection := &Connection{Network: network, Address: &net.UDPAddr{IP: record.IP, Port: int(record.Port)}, Status: ConnectionActive} + port := record.Port + if record.PortReportedExternal > 0 { // Use the external port if available + port = record.PortReportedExternal + } + + // TODO: Traverse message needs to be considered here + + connection := &Connection{Network: network, Address: &net.UDPAddr{IP: record.IP, Port: int(port)}, Status: ConnectionActive, PortInternal: record.PortReportedInternal, PortExternal: record.PortReportedExternal} return &PeerInfo{PublicKey: record.PublicKey, connectionActive: []*Connection{connection}, connectionLatest: connection, NodeID: publicKey2NodeID(record.PublicKey), messageSequence: rand.Uint32()} }