@@ -142,16 +142,19 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
142
142
}
143
143
144
144
// get best local address for a particular peer as a CAddress
145
+ // Otherwise, return the unroutable 0.0.0.0 but filled in with
146
+ // the normal parameters, since the IP may be changed to a useful
147
+ // one by discovery.
145
148
CAddress GetLocalAddress (const CNetAddr *paddrPeer)
146
149
{
147
- CAddress ret (CService (" 0.0.0.0" ,0 ),0 );
150
+ CAddress ret (CService (" 0.0.0.0" ,GetListenPort () ),0 );
148
151
CService addr;
149
152
if (GetLocal (addr, paddrPeer))
150
153
{
151
154
ret = CAddress (addr);
152
- ret.nServices = nLocalServices;
153
- ret.nTime = GetAdjustedTime ();
154
155
}
156
+ ret.nServices = nLocalServices;
157
+ ret.nTime = GetAdjustedTime ();
155
158
return ret;
156
159
}
157
160
@@ -205,21 +208,38 @@ bool RecvLine(SOCKET hSocket, string& strLine)
205
208
}
206
209
}
207
210
208
- // used when scores of local addresses may have changed
209
- // pushes better local address to peers
210
- void static AdvertizeLocal ()
211
+ int GetnScore (const CService& addr)
211
212
{
212
- LOCK (cs_vNodes);
213
- BOOST_FOREACH (CNode* pnode, vNodes)
213
+ LOCK (cs_mapLocalHost);
214
+ if (mapLocalHost.count (addr) == LOCAL_NONE)
215
+ return 0 ;
216
+ return mapLocalHost[addr].nScore ;
217
+ }
218
+
219
+ // Is our peer's addrLocal potentially useful as an external IP source?
220
+ bool IsPeerAddrLocalGood (CNode *pnode)
221
+ {
222
+ return fDiscover && pnode->addr .IsRoutable () && pnode->addrLocal .IsRoutable () &&
223
+ !IsLimited (pnode->addrLocal .GetNetwork ());
224
+ }
225
+
226
+ // pushes our own address to a peer
227
+ void AdvertizeLocal (CNode *pnode)
228
+ {
229
+ if (fListen && pnode->fSuccessfullyConnected )
214
230
{
215
- if (pnode->fSuccessfullyConnected )
231
+ CAddress addrLocal = GetLocalAddress (&pnode->addr );
232
+ // If discovery is enabled, sometimes give our peer the address it
233
+ // tells us that it sees us as in case it has a better idea of our
234
+ // address than we do.
235
+ if (IsPeerAddrLocalGood (pnode) && (!addrLocal.IsRoutable () ||
236
+ GetRand ((GetnScore (addrLocal) > LOCAL_MANUAL) ? 8 :2 ) == 0 ))
216
237
{
217
- CAddress addrLocal = GetLocalAddress (&pnode->addr );
218
- if (addrLocal.IsRoutable () && (CService)addrLocal != (CService)pnode->addrLocal )
219
- {
220
- pnode->PushAddress (addrLocal);
221
- pnode->addrLocal = addrLocal;
222
- }
238
+ addrLocal.SetIP (pnode->addrLocal );
239
+ }
240
+ if (addrLocal.IsRoutable ())
241
+ {
242
+ pnode->PushAddress (addrLocal);
223
243
}
224
244
}
225
245
}
@@ -257,8 +277,6 @@ bool AddLocal(const CService& addr, int nScore)
257
277
SetReachable (addr.GetNetwork ());
258
278
}
259
279
260
- AdvertizeLocal ();
261
-
262
280
return true ;
263
281
}
264
282
@@ -296,12 +314,10 @@ bool SeenLocal(const CService& addr)
296
314
return false ;
297
315
mapLocalHost[addr].nScore ++;
298
316
}
299
-
300
- AdvertizeLocal ();
301
-
302
317
return true ;
303
318
}
304
319
320
+
305
321
/* * check whether a given address is potentially local */
306
322
bool IsLocal (const CService& addr)
307
323
{
@@ -323,114 +339,12 @@ bool IsReachable(const CNetAddr& addr)
323
339
return IsReachable (net);
324
340
}
325
341
326
- bool GetMyExternalIP2 (const CService& addrConnect, const char * pszGet, const char * pszKeyword, CNetAddr& ipRet)
327
- {
328
- SOCKET hSocket;
329
- if (!ConnectSocket (addrConnect, hSocket))
330
- return error (" GetMyExternalIP() : connection to %s failed" , addrConnect.ToString ());
331
-
332
- send (hSocket, pszGet, strlen (pszGet), MSG_NOSIGNAL);
333
-
334
- string strLine;
335
- while (RecvLine (hSocket, strLine))
336
- {
337
- if (strLine.empty ()) // HTTP response is separated from headers by blank line
338
- {
339
- while (true )
340
- {
341
- if (!RecvLine (hSocket, strLine))
342
- {
343
- CloseSocket (hSocket);
344
- return false ;
345
- }
346
- if (pszKeyword == NULL )
347
- break ;
348
- if (strLine.find (pszKeyword) != string::npos)
349
- {
350
- strLine = strLine.substr (strLine.find (pszKeyword) + strlen (pszKeyword));
351
- break ;
352
- }
353
- }
354
- CloseSocket (hSocket);
355
- if (strLine.find (" <" ) != string::npos)
356
- strLine = strLine.substr (0 , strLine.find (" <" ));
357
- strLine = strLine.substr (strspn (strLine.c_str (), " \t\n\r " ));
358
- while (strLine.size () > 0 && isspace (strLine[strLine.size ()-1 ]))
359
- strLine.resize (strLine.size ()-1 );
360
- CService addr (strLine,0 ,true );
361
- LogPrintf (" GetMyExternalIP() received [%s] %s\n " , strLine, addr.ToString ());
362
- if (!addr.IsValid () || !addr.IsRoutable ())
363
- return false ;
364
- ipRet.SetIP (addr);
365
- return true ;
366
- }
367
- }
368
- CloseSocket (hSocket);
369
- return error (" GetMyExternalIP() : connection closed" );
370
- }
371
-
372
- bool GetMyExternalIP (CNetAddr& ipRet)
373
- {
374
- CService addrConnect;
375
- const char * pszGet;
376
- const char * pszKeyword;
377
-
378
- for (int nLookup = 0 ; nLookup <= 1 ; nLookup++)
379
- for (int nHost = 1 ; nHost <= 1 ; nHost++)
380
- {
381
- // We should be phasing out our use of sites like these. If we need
382
- // replacements, we should ask for volunteers to put this simple
383
- // php file on their web server that prints the client IP:
384
- // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
385
- if (nHost == 1 )
386
- {
387
- addrConnect = CService (" 91.198.22.70" , 80 ); // checkip.dyndns.org
388
-
389
- if (nLookup == 1 )
390
- {
391
- CService addrIP (" checkip.dyndns.org" , 80 , true );
392
- if (addrIP.IsValid ())
393
- addrConnect = addrIP;
394
- }
395
-
396
- pszGet = " GET / HTTP/1.1\r\n "
397
- " Host: checkip.dyndns.org\r\n "
398
- " User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n "
399
- " Connection: close\r\n "
400
- " \r\n " ;
401
-
402
- pszKeyword = " Address:" ;
403
- }
404
-
405
- if (GetMyExternalIP2 (addrConnect, pszGet, pszKeyword, ipRet))
406
- return true ;
407
- }
408
-
409
- return false ;
410
- }
411
-
412
- void ThreadGetMyExternalIP ()
413
- {
414
- CNetAddr addrLocalHost;
415
- if (GetMyExternalIP (addrLocalHost))
416
- {
417
- LogPrintf (" GetMyExternalIP() returned %s\n " , addrLocalHost.ToStringIP ());
418
- AddLocal (addrLocalHost, LOCAL_HTTP);
419
- }
420
- }
421
-
422
-
423
-
424
-
425
-
426
342
void AddressCurrentlyConnected (const CService& addr)
427
343
{
428
344
addrman.Connected (addr);
429
345
}
430
346
431
347
432
-
433
-
434
348
uint64_t CNode::nTotalBytesRecv = 0 ;
435
349
uint64_t CNode::nTotalBytesSent = 0 ;
436
350
CCriticalSection CNode::cs_totalBytesRecv;
@@ -1687,9 +1601,6 @@ void static Discover(boost::thread_group& threadGroup)
1687
1601
}
1688
1602
#endif
1689
1603
1690
- // Don't use external IPv4 discovery, when -onlynet="IPv6"
1691
- if (!IsLimited (NET_IPV4))
1692
- threadGroup.create_thread (boost::bind (&TraceThread<void (*)()>, " ext-ip" , &ThreadGetMyExternalIP));
1693
1604
}
1694
1605
1695
1606
void StartNode (boost::thread_group& threadGroup)
0 commit comments