From 3595b18793a94a0cdfe64b5e0cfc0260e19661fe Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 28 Aug 2012 17:55:52 -0400 Subject: [PATCH 1/2] Don't force IRC off if not listening, do force it off if IPv4 is off. Previously Bitcoin would refuse to use IRC if it was either not accepting inbound connections or not making outbound. Instead this changes it to not use IRC only if it's not doing either or if IPv4 is off completely. If Bitcoin is not listening this will use the default random nicks rather than the IP based ones. --- src/irc.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/irc.cpp b/src/irc.cpp index 50c6a5b4d..9e88541c2 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -207,10 +207,15 @@ void ThreadIRCSeed(void* parg) void ThreadIRCSeed2(void* parg) { - /* Don't advertise on IRC if we don't allow incoming connections */ - if (mapArgs.count("-connect") || fNoListen) + // Don't connect to IRC if we won't use IPv4 connections. + if (IsLimited(NET_IPV4)) return; + // ... or if we won't make outbound connections and won't accept inbound ones. + if (mapArgs.count("-connect") && fNoListen) + return; + + // ... or if IRC is not enabled. if (!GetBoolArg("-irc", false)) return; @@ -251,7 +256,8 @@ void ThreadIRCSeed2(void* parg) CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses CService addrLocal; string strMyName; - if (GetLocal(addrLocal, &addrIPv4)) + // Don't use our IP as our nick if we're not listening + if (!fNoListen && GetLocal(addrLocal, &addrIPv4)) strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); if (strMyName == "") strMyName = strprintf("x%u", GetRand(1000000000)); @@ -283,7 +289,8 @@ void ThreadIRCSeed2(void* parg) if (GetIPFromIRC(hSocket, strMyName, addrFromIRC)) { printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str()); - if (addrFromIRC.IsRoutable()) + // Don't use our IP as our nick if we're not listening + if (!fNoListen && addrFromIRC.IsRoutable()) { // IRC lets you to re-nick AddLocal(addrFromIRC, LOCAL_IRC); @@ -291,7 +298,7 @@ void ThreadIRCSeed2(void* parg) Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); } } - + if (fTestNet) { Send(hSocket, "JOIN #bitcoinTEST3\r"); Send(hSocket, "WHO #bitcoinTEST3\r"); From 6a60c64c6b4c6a8095e12b515fc7e30eedfab5ab Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 28 Aug 2012 22:04:38 -0400 Subject: [PATCH 2/2] Don't retry a failing IRC nickname forever. If our IRC nick is in use (because some other node thinks it has the same address we think we have) don't fruitlessly try to reconnect using that name forever. After three tries, give up and use a random nick. Either we'll learn a new local address from IRC and switch to that, or it was right and the other guy is advertising for us. This avoids a pessimal case where a second testnet node behind a nat is unable to get any peers because he can't get on IRC. --- src/irc.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/irc.cpp b/src/irc.cpp index 9e88541c2..6991e6ee7 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -222,6 +222,7 @@ void ThreadIRCSeed2(void* parg) printf("ThreadIRCSeed started\n"); int nErrorWait = 10; int nRetryWait = 10; + int nNameRetry = 0; while (!fShutdown) { @@ -257,7 +258,8 @@ void ThreadIRCSeed2(void* parg) CService addrLocal; string strMyName; // Don't use our IP as our nick if we're not listening - if (!fNoListen && GetLocal(addrLocal, &addrIPv4)) + // or if it keeps failing because the nick is already in use. + if (!fNoListen && GetLocal(addrLocal, &addrIPv4) && nNameRetry<3) strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); if (strMyName == "") strMyName = strprintf("x%u", GetRand(1000000000)); @@ -273,6 +275,7 @@ void ThreadIRCSeed2(void* parg) if (nRet == 2) { printf("IRC name already in use\n"); + nNameRetry++; Wait(10); continue; } @@ -282,6 +285,7 @@ void ThreadIRCSeed2(void* parg) else return; } + nNameRetry = 0; Sleep(500); // Get our external IP from the IRC server and re-nick before joining the channel