Пример #1
0
bool EndpointPool::addEndpoint(Endpoint endpoint, int64_t penalty)
{
    if (!endpoint.isRoutable())
        return false;
    if (endpoint.getIP() == _localhost.getIP())
        return false;
    endpoint.setTime(max((int64_t)0, (int64_t)endpoint.getTime() - penalty));
    Endpoint found = endpoint;
    
    query("INSERT OR REPLACE INTO Endpoints VALUES (?, ?, ?, ?)", (int64_t)endpoint.getIP(), (int64_t)endpoint.getPort(), (int64_t)endpoint.getTime(), 0);
    
    return true;
}
Пример #2
0
void ChatClient::handle_read_line(const boost::system::error_code& err, size_t bytes_transferred) {
    if (!err) {
        istream is(&_recv);
        string rx;
        do {
            char c;
            is >> noskipws >> c;
            if(c == '\r' || c == '\n') 
                bytes_transferred--;
            else
                rx.push_back(c);
        } while (rx.size() < bytes_transferred);
        //        cout << rx << endl;
        //        _recv.consume(bytes_transferred);
        switch (_mode) {
            case wait_for_notice: {
                // look for "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname" in the line
                if (rx.find("Found your hostname") != string::npos ||
                    rx.find("using your IP address instead") != string::npos ||
                    rx.find("Couldn't look up your hostname") != string::npos ||
                    rx.find("ignoring hostname") != string::npos) {
                    _mode = wait_for_motd;
                    
                    if (_endpointPool.getLocal().isRoutable() && !_proxy && !_name_in_use)
                        _my_name = encodeAddress(_endpointPool.getLocal());
                    else
                        _my_name = cformat("x%u", GetRand(1000000000)).text();
                    
                    std::ostream txstream(&_send);
                    txstream << "NICK " << _my_name << "\r";
                    txstream << "USER " << _my_name << " 8 * : " << _my_name << "\r";

                    async_write(_socket, _send, boost::bind(&ChatClient::handle_write_request, this, boost::asio::placeholders::error));
                }
                break;
            }
            case wait_for_motd: {
                if (rx.find(" 004 ") != string::npos) {
                    _mode = wait_for_ip;
                    
                    std::ostream txstream(&_send);
                    txstream << "USERHOST " << _my_name << "\r";

                    async_write(_socket, _send, boost::bind(&ChatClient::handle_write_request, this, boost::asio::placeholders::error));
                }
                else if (rx.find(" 433 ") != string::npos) { // 
                    log_debug("IRC name already in use\n");
                    _name_in_use = true;
                    // close and rejoin
                    _socket.close();
                    _mode = wait_for_notice;
                    tcp::resolver::query query(_server, "irc"); // should we remove irc as service type ?
                    _resolver.async_resolve(query, boost::bind(&ChatClient::handle_resolve, this, asio::placeholders::error, asio::placeholders::iterator));
                    return;
                }
                break;
            }
            case wait_for_ip: {
                if (rx.find(" 302 ") != string::npos) {
                    _mode = in_chat_room;
                    std::ostream txstream(&_send);                
                    // set my IP:
                    vector<string> words;
                    split(words, rx, is_any_of(" "));
                    if (words.size() > 3) {
                        string str = words[3];
                        if (str.rfind("@") != string::npos) {
                            string host = str.substr(str.rfind("@")+1);
                            
                            // Hybrid IRC used by lfnet always returns IP when you userhost yourself,
                            // but in case another IRC is ever used this should work.
                            log_debug("GetIPFromIRC() got userhost %s\n", host.c_str());
                            Endpoint endpoint(host, 0, true);
                            if (endpoint.isValid()) {
                                _endpointPool.setLocal(endpoint);
                                _my_name = encodeAddress(endpoint);
                                _notifier(); // this will start the Node...
                            }
                            if (_proxy)
                                // re nick
                                txstream << "NICK " << _my_name << "\r";
                            // now join the chat room
                            if (_channels > 1) {
                                // randomly join e.g. #bitcoin00-#bitcoin99
                                int channel_number = GetRandInt(_channels);
                                stringstream ss;
                                ss << setfill('0') << setw(2) << channel_number;
                                txstream << "JOIN #" << _channel << ss.str() << "\r";
                                txstream <<  "WHO #" << _channel << ss.str() <<  "\r";
                            }
                            else {
                                txstream << "JOIN #" << _channel << "00\r";
                                txstream <<  "WHO #" << _channel << "00\r";
                            }                
                            async_write(_socket, _send, boost::bind(&ChatClient::handle_write_request, this, asio::placeholders::error));
                            break;
                        }
                    }
                }
            }    
            case in_chat_room: {
                if (rx.empty() || rx.size() > 900)
                    break;
                
                vector<string> words;
                split(words, rx, is_any_of(" "));
                if (words.size() < 2)
                    break;
                
                string name;
                
                if (words[0] == "PING") {
                    string tx = rx;
                    ostream txstream(&_send);
                    tx[1] = 'O'; // change line to PONG
                    tx += '\r';
                    txstream << tx;
                    async_write(_socket, _send, boost::bind(&ChatClient::handle_write_request, this, asio::placeholders::error));
                    break;
                }
                
                if (words[1] == "352" && words.size() >= 8) {
                    // index 7 is limited to 16 characters
                    // could get full length name at index 10, but would be different from join messages
                    name = words[7];
                    log_debug("IRC got who\n");
                }
                
                if (words[1] == "JOIN" && words[0].size() > 1) {
                    // :[email protected] JOIN :#channelname
                    name = words[0].substr(1);
                    size_t exclamation_pos = words[0].find("!");
                    if(exclamation_pos != string::npos)
                        name = words[0].substr(1, exclamation_pos-1); // the 1, -1 is due to the colon
                                                                      //                    if (strchr(pszName, '!'))
                                                                      //                        *strchr(pszName, '!') = '\0';
                    log_debug("IRC got join\n");
                }
                
                if (name[0] == 'u') {
                    Endpoint endpoint;
                    if (decodeAddress(name, endpoint)) {
                        endpoint.setTime(GetAdjustedTime());
                        if (_endpointPool.addEndpoint(endpoint, 51 * 60)) {
                            log_debug("IRC got new address: %s\n", endpoint.toString().c_str());
                            _notifier();
                        }
                        //                        nGotIREndpointes++;
                    }
                    else {
                        log_debug("IRC decode failed\n");
                    }
                }
                break;
            }
                
            default:
                break;
        }
        async_read_until(_socket, _recv, "\r\n", boost::bind(&ChatClient::handle_read_line, this, asio::placeholders::error, asio::placeholders::bytes_transferred));
    }