@@ -92,6 +92,35 @@ def __init__(self, address=None, sock=None):
9292 self .bm_proto_reset ()
9393 self .set_state ("bm_header" , expectBytes = protocol .Header .size )
9494
95+ def _host_is_global (self ):
96+ """Is this connection's address useful for knownnodes?
97+
98+ Returns True if the peer address is a real, globally routable
99+ address that is worth sharing with the network.
100+ """
101+ # SOCKS proxy IP: not the real peer address
102+ if protocol .checkSocksIP (self .destination .host ):
103+ return False
104+ # Local/private IP: not useful to announce to the network
105+ if self .local :
106+ return False
107+ return True
108+
109+ def _getPeer (self ):
110+ """Return the peer address suitable for knownnodes.
111+
112+ For outbound connections, use destination as-is.
113+ For inbound connections, use the advertised listening port
114+ from the version message instead of the ephemeral source port.
115+ Falls back to destination if version was not yet received.
116+ """
117+ if self .isOutbound :
118+ return self .destination
119+ try :
120+ return Peer (self .destination .host , self .peerNode .port )
121+ except AttributeError :
122+ return self .destination
123+
95124 def antiIntersectionDelay (self , initial = False ):
96125 """
97126 This is a defense against the so called intersection attacks.
@@ -162,18 +191,25 @@ def set_connection_fully_established(self):
162191 ))
163192 self .antiIntersectionDelay (True )
164193 self .fullyEstablished = True
194+ peer = self ._getPeer ()
165195 # The connection having host suitable for knownnodes
166- if self .isOutbound or not self .local and not state .socksIP :
167- knownnodes .increaseRating (self .destination )
196+ if self ._host_is_global ():
197+ if self .isOutbound :
198+ knownnodes .increaseRating (peer )
199+ lastseen = time .time ()
200+ elif config .safeGetBoolean ('bootstrap' , 'commands' ):
201+ lastseen = time .time () - knownnodes .BOOTSTRAP_INSERT_AGE
202+ else :
203+ lastseen = time .time ()
168204 knownnodes .addKnownNode (
169- self .streams , self . destination , time . time () )
205+ self .streams , peer , lastseen )
170206 dandelion_ins .maybeAddStem (self , invQueue )
171207 if not config .safeGetBoolean ('bootstrap' , 'addr' ):
172208 self .sendAddr ()
173209 if not config .safeGetBoolean ('bootstrap' , 'inv' ):
174210 self .sendBigInv ()
175211
176- def sendAddr (self ):
212+ def sendAddr (self ): # pylint: disable=too-many-locals
177213 """Send a partial list of known addresses to peer."""
178214 # We are going to share a maximum number of 1000 addrs (per overlapping
179215 # stream) with our peer. 500 from overlapping streams, 250 from the
@@ -191,11 +227,14 @@ def sendAddr(self):
191227 continue
192228 # only if more recent than 3 hours
193229 # and having positive or neutral rating
230+ is_bootstrap = config .safeGetBoolean (
231+ 'bootstrap' , 'commands' )
194232 filtered = [
195233 (k , v ) for k , v in nodes .items ()
196234 if v ["lastseen" ] > int (time .time ())
197235 - maximumAgeOfNodesThatIAdvertiseToOthers
198- and v ["rating" ] >= 0 and not k .host .endswith ('.onion' )
236+ and (is_bootstrap or v ["rating" ] >= 0 )
237+ and not k .host .endswith ('.onion' )
199238 ]
200239 # sent 250 only if the remote isn't interested in it
201240 elemCount = min (
@@ -285,20 +324,21 @@ def handle_write(self):
285324
286325 def handle_close (self ):
287326 """Callback for connection being closed."""
288- host_is_global = self .isOutbound or not self . local and not state . socksIP
327+ host_is_global = self ._host_is_global ()
289328 if self .fullyEstablished :
290329 UISignalQueue .put ((
291330 'updateNetworkStatusTab' ,
292331 (self .isOutbound , False , self .destination )
293332 ))
294333 if host_is_global :
295- knownnodes .addKnownNode (
296- self .streams , self .destination , time .time ())
334+ if self .isOutbound :
335+ knownnodes .addKnownNode (
336+ self .streams , self ._getPeer (), time .time ())
297337 dandelion_ins .maybeRemoveStem (self )
298338 else :
299339 self .checkTimeOffsetNotification ()
300- if host_is_global :
301- knownnodes .decreaseRating (self .destination )
340+ if host_is_global and self . isOutbound :
341+ knownnodes .decreaseRating (self ._getPeer () )
302342 BMProto .handle_close (self )
303343
304344
0 commit comments