Skip to content

Commit 0c7862e

Browse files
committed
Merge pull request #5161
845c86d Do not use third party services for IP detection. (Gregory Maxwell)
2 parents 7ffb880 + 845c86d commit 0c7862e

File tree

4 files changed

+61
-148
lines changed

4 files changed

+61
-148
lines changed

src/init.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@ bool AppInit2(boost::thread_group& threadGroup)
574574
// to protect privacy, do not listen by default if a default proxy server is specified
575575
if (SoftSetBoolArg("-listen", false))
576576
LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n");
577+
// to protect privacy, do not discover addresses by default
578+
if (SoftSetBoolArg("-discover", false))
579+
LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n");
577580
}
578581

579582
if (!GetBoolArg("-listen", true)) {

src/main.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3478,12 +3478,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
34783478
else
34793479
pfrom->fRelayTxes = true;
34803480

3481-
if (pfrom->fInbound && addrMe.IsRoutable())
3482-
{
3483-
pfrom->addrLocal = addrMe;
3484-
SeenLocal(addrMe);
3485-
}
3486-
34873481
// Disconnect if we connected to ourself
34883482
if (nNonce == nLocalHostNonce && nNonce > 1)
34893483
{
@@ -3492,6 +3486,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
34923486
return true;
34933487
}
34943488

3489+
pfrom->addrLocal = addrMe;
3490+
if (pfrom->fInbound && addrMe.IsRoutable())
3491+
{
3492+
SeenLocal(addrMe);
3493+
}
3494+
34953495
// Be shy and don't send version until we hear
34963496
if (pfrom->fInbound)
34973497
pfrom->PushVersion();
@@ -3512,7 +3512,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
35123512
{
35133513
CAddress addr = GetLocalAddress(&pfrom->addr);
35143514
if (addr.IsRoutable())
3515+
{
3516+
pfrom->PushAddress(addr);
3517+
} else if (IsPeerAddrLocalGood(pfrom)) {
3518+
addr.SetIP(pfrom->addrLocal);
35153519
pfrom->PushAddress(addr);
3520+
}
35163521
}
35173522

35183523
// Get recent addresses
@@ -4375,24 +4380,18 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
43754380
static int64_t nLastRebroadcast;
43764381
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
43774382
{
4383+
LOCK(cs_vNodes);
4384+
BOOST_FOREACH(CNode* pnode, vNodes)
43784385
{
4379-
LOCK(cs_vNodes);
4380-
BOOST_FOREACH(CNode* pnode, vNodes)
4381-
{
4382-
// Periodically clear setAddrKnown to allow refresh broadcasts
4383-
if (nLastRebroadcast)
4384-
pnode->setAddrKnown.clear();
4386+
// Periodically clear setAddrKnown to allow refresh broadcasts
4387+
if (nLastRebroadcast)
4388+
pnode->setAddrKnown.clear();
43854389

4386-
// Rebroadcast our address
4387-
if (fListen)
4388-
{
4389-
CAddress addr = GetLocalAddress(&pnode->addr);
4390-
if (addr.IsRoutable())
4391-
pnode->PushAddress(addr);
4392-
}
4393-
}
4390+
// Rebroadcast our address
4391+
AdvertizeLocal(pnode);
43944392
}
4395-
nLastRebroadcast = GetTime();
4393+
if (!vNodes.empty())
4394+
nLastRebroadcast = GetTime();
43964395
}
43974396

43984397
//

src/net.cpp

Lines changed: 36 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,19 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
142142
}
143143

144144
// 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.
145148
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
146149
{
147-
CAddress ret(CService("0.0.0.0",0),0);
150+
CAddress ret(CService("0.0.0.0",GetListenPort()),0);
148151
CService addr;
149152
if (GetLocal(addr, paddrPeer))
150153
{
151154
ret = CAddress(addr);
152-
ret.nServices = nLocalServices;
153-
ret.nTime = GetAdjustedTime();
154155
}
156+
ret.nServices = nLocalServices;
157+
ret.nTime = GetAdjustedTime();
155158
return ret;
156159
}
157160

@@ -205,21 +208,38 @@ bool RecvLine(SOCKET hSocket, string& strLine)
205208
}
206209
}
207210

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)
211212
{
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)
214230
{
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))
216237
{
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);
223243
}
224244
}
225245
}
@@ -257,8 +277,6 @@ bool AddLocal(const CService& addr, int nScore)
257277
SetReachable(addr.GetNetwork());
258278
}
259279

260-
AdvertizeLocal();
261-
262280
return true;
263281
}
264282

@@ -296,12 +314,10 @@ bool SeenLocal(const CService& addr)
296314
return false;
297315
mapLocalHost[addr].nScore++;
298316
}
299-
300-
AdvertizeLocal();
301-
302317
return true;
303318
}
304319

320+
305321
/** check whether a given address is potentially local */
306322
bool IsLocal(const CService& addr)
307323
{
@@ -323,114 +339,12 @@ bool IsReachable(const CNetAddr& addr)
323339
return IsReachable(net);
324340
}
325341

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-
426342
void AddressCurrentlyConnected(const CService& addr)
427343
{
428344
addrman.Connected(addr);
429345
}
430346

431347

432-
433-
434348
uint64_t CNode::nTotalBytesRecv = 0;
435349
uint64_t CNode::nTotalBytesSent = 0;
436350
CCriticalSection CNode::cs_totalBytesRecv;
@@ -1687,9 +1601,6 @@ void static Discover(boost::thread_group& threadGroup)
16871601
}
16881602
#endif
16891603

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));
16931604
}
16941605

16951606
void StartNode(boost::thread_group& threadGroup)

src/net.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ unsigned int SendBufferSize();
6060

6161
void AddOneShot(std::string strDest);
6262
bool RecvLine(SOCKET hSocket, std::string& strLine);
63-
bool GetMyExternalIP(CNetAddr& ipRet);
6463
void AddressCurrentlyConnected(const CService& addr);
6564
CNode* FindNode(const CNetAddr& ip);
6665
CNode* FindNode(const std::string& addrName);
@@ -96,12 +95,13 @@ enum
9695
LOCAL_IF, // address a local interface listens on
9796
LOCAL_BIND, // address explicit bound to
9897
LOCAL_UPNP, // address reported by UPnP
99-
LOCAL_HTTP, // address reported by whatismyip.com and similar
10098
LOCAL_MANUAL, // address explicitly specified (-externalip=)
10199

102100
LOCAL_MAX
103101
};
104102

103+
bool IsPeerAddrLocalGood(CNode *pnode);
104+
void AdvertizeLocal(CNode *pnode);
105105
void SetLimited(enum Network net, bool fLimited = true);
106106
bool IsLimited(enum Network net);
107107
bool IsLimited(const CNetAddr& addr);

0 commit comments

Comments
 (0)