From 629e37dde1fa93f6ce31544d1ebb5ee5c19052cb Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 15 Dec 2010 22:43:51 +0000 Subject: [PATCH] get external ip from irc git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@202 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- irc.cpp | 10 +++++++--- irc.h | 1 + main.h | 2 ++ net.cpp | 49 +++++++++++++++++++++++++++++++++++++------------ serialize.h | 2 +- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/irc.cpp b/irc.cpp index 1734d76fa..aad9beb76 100644 --- a/irc.cpp +++ b/irc.cpp @@ -5,6 +5,7 @@ #include "headers.h" int nGotIRCAddresses = 0; +bool fGotExternalIP = false; void ThreadIRCSeed2(void* parg); @@ -223,6 +224,8 @@ bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet) } else { + // Hybrid IRC used by lfnet always returns IP when you userhost yourself, + // but in case another IRC is ever used this should work. printf("GetIPFromIRC() got userhost %s\n", strHost.c_str()); if (fUseProxy) return false; @@ -327,14 +330,15 @@ void ThreadIRCSeed2(void* parg) } Sleep(500); - // Get my external IP from IRC server + // Get our external IP from the IRC server and re-nick before joining the channel CAddress addrFromIRC; if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip)) { - // Just using it as a backup for now printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str()); - if (addrFromIRC.IsRoutable() && !fUseProxy && !addrLocalHost.IsRoutable()) + if (!fUseProxy && addrFromIRC.IsRoutable()) { + // IRC lets you to re-nick + fGotExternalIP = true; addrLocalHost.ip = addrFromIRC.ip; strMyName = EncodeAddress(addrLocalHost); Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); diff --git a/irc.h b/irc.h index 9cf964a6e..4bc812902 100644 --- a/irc.h +++ b/irc.h @@ -6,3 +6,4 @@ bool RecvLine(SOCKET hSocket, string& strLine); void ThreadIRCSeed(void* parg); extern int nGotIRCAddresses; +extern bool fGotExternalIP; diff --git a/main.h b/main.h index 088e2860c..5934350f2 100644 --- a/main.h +++ b/main.h @@ -1733,6 +1733,8 @@ public: // +// Alerts are for notifying old versions if they become too obsolete and +// need to upgrade. The message is displayed in the status bar. // Alert messages are broadcast as a vector of signed data. Unserializing may // not read the entire buffer if the alert is for a newer version, but older // versions can still relay the original data. diff --git a/net.cpp b/net.cpp index 3c80644a4..da7661962 100644 --- a/net.cpp +++ b/net.cpp @@ -163,7 +163,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha return error("GetMyExternalIP() : connection closed"); } - +// We now get our external IP from the IRC server first and only use this as a backup bool GetMyExternalIP(unsigned int& ipRet) { CAddress addrConnect; @@ -176,6 +176,10 @@ bool GetMyExternalIP(unsigned int& ipRet) for (int nLookup = 0; nLookup <= 1; nLookup++) for (int nHost = 1; nHost <= 2; nHost++) { + // We should be phasing out our use of sites like these. If we need + // replacements, we should ask for volunteers to put this simple + // php file on their webserver that prints the client IP: + // if (nHost == 1) { addrConnect = CAddress("91.198.22.70:80"); // checkip.dyndns.org @@ -222,6 +226,36 @@ bool GetMyExternalIP(unsigned int& ipRet) return false; } +void ThreadGetMyExternalIP(void* parg) +{ + // Wait for IRC to get it first + if (!GetBoolArg("-noirc")) + { + for (int i = 0; i < 2 * 60; i++) + { + Sleep(1000); + if (fGotExternalIP || fShutdown) + return; + } + } + + // Fallback in case IRC fails to get it + if (GetMyExternalIP(addrLocalHost.ip)) + { + printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str()); + if (addrLocalHost.IsRoutable()) + { + // If we already connected to a few before we had our IP, go back and addr them. + // setAddrKnown automatically filters any duplicate sends. + CAddress addr(addrLocalHost); + addr.nTime = GetAdjustedTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->PushAddress(addr); + } + } +} + @@ -1310,8 +1344,7 @@ void StartNode(void* parg) #endif printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); - // Get our external IP address for incoming connections - if (fUseProxy) + if (fUseProxy || mapArgs.count("-connect")) { // Proxies can't take incoming connections addrLocalHost.ip = CAddress("0.0.0.0").ip; @@ -1319,15 +1352,7 @@ void StartNode(void* parg) } else { - if (addrIncoming.IsValid()) - addrLocalHost.ip = addrIncoming.ip; - - if (GetMyExternalIP(addrLocalHost.ip)) - { - addrIncoming = addrLocalHost; - CWalletDB().WriteSetting("addrIncoming", addrIncoming); - printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); - } + CreateThread(ThreadGetMyExternalIP, NULL); } // diff --git a/serialize.h b/serialize.h index e4c3bb0dd..34a339f77 100644 --- a/serialize.h +++ b/serialize.h @@ -25,7 +25,7 @@ class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 31900; +static const int VERSION = 31901; static const char* pszSubVer = "";