Example #1
0
void ConsumeLines( size_t lineCount )
{
	char szMaxLineLen[2048];

	// Limitation -- only 2048 bytes until line is cgc_read!
	for ( size_t count = 0; count < lineCount; count++ )
		RecvUntil( 0, '\n', szMaxLineLen, 2048 );
}
Example #2
0
void ThreadIRCSeed()
{
    // 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;
    
    int nErrorWait = 10;
    int nRetryWait = 10;
    int nNameRetry = 0;

    for(;;)
    {
        boost::this_thread::interruption_point();
        CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org

        CService addrIRC("irc.lfnet.org", 6667, true);
        if (addrIRC.IsValid())
            addrConnect = addrIRC;

        SOCKET hSocket;
        if (!ConnectSocket(addrConnect, hSocket, nConnectTimeout))
        {
            LogPrintf("IRC connect failed\n");
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        };

        if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        };

        CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
        CService addrLocal;
        std::string strMyName;
        // Don't use our IP as our nick if we're not listening
        // 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));

        Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
        Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());

        int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
        if (nRet != 1)
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            if (nRet == 2)
            {
                LogPrintf("IRC name already in use\n");
                nNameRetry++;
                Wait(10);
                continue;
            };
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        };
        
        nNameRetry = 0;
        MilliSleep(500);

        // Get our external IP from the IRC server and re-nick before joining the channel
        CNetAddr addrFromIRC;
        if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
        {
            LogPrintf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
            // 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);
                strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
                Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
            };
        };

        if (fTestNet)
        {
            Send(hSocket, "JOIN #sdcoinTEST\r");
            Send(hSocket, "WHO #sdcoinTEST\r");
        } else
        {
            // randomly join #StealthCash00-#StealthCash05
            //int channel_number = GetRandInt(5);

            // Channel number is always 0 for initial release
            int channel_number = 0;
            Send(hSocket, strprintf("JOIN #sdcoin%02d\r", channel_number).c_str());
            Send(hSocket, strprintf("WHO #sdcoin%02d\r", channel_number).c_str());
        };

        int64_t nStart = GetTime();
        std::string strLine;
        strLine.reserve(10000);
        while (RecvLineIRC(hSocket, strLine))
        {
            boost::this_thread::interruption_point();
            if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
                continue;

            std::vector<std::string> vWords;
            ParseString(strLine, ' ', vWords);
            if (vWords.size() < 2)
                continue;

            char pszName[10000];
            pszName[0] = '\0';

            if (vWords[1] == "352" && vWords.size() >= 8)
            {
                // index 7 is limited to 16 characters
                // could get full length name at index 10, but would be different from join messages
                strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
                LogPrintf("IRC got who\n");
            };

            if (vWords[1] == "JOIN" && vWords[0].size() > 1)
            {
                // :[email protected] JOIN :#channelname
                strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
                if (strchr(pszName, '!'))
                    *strchr(pszName, '!') = '\0';
                LogPrintf("IRC got join\n");
            };

            if (pszName[0] == 'u')
            {
                CAddress addr;
                if (DecodeAddress(pszName, addr))
                {
                    addr.nTime = GetAdjustedTime();
                    if (addrman.Add(addr, addrConnect, 51 * 60))
                        LogPrintf("IRC got new address: %s\n", addr.ToString().c_str());
                    nGotIRCAddresses++;
                } else
                {
                    LogPrintf("IRC decode failed\n");
                };
            };
        };
        closesocket(hSocket);
        hSocket = INVALID_SOCKET;

        if (GetTime() - nStart > 20 * 60)
        {
            nErrorWait /= 3;
            nRetryWait /= 3;
        };

        nRetryWait = nRetryWait * 11 / 10;
        if (!Wait(nRetryWait += 60))
            return;
    };
}