Exemple #1
0
void Peer::handle_read(const system::error_code& e, std::size_t bytes_transferred) {
    log_trace("args error: %s, bytes: %d", e.message(), bytes_transferred);
    if (!e) {
        _activity = true;
        string rx;
        for(int i = 0; i < bytes_transferred; i++)
            rx.push_back(_buffer[i]);
        
        vRecv += rx;
        
        // Now call the parser:
        bool fRet = false;
        loop {
            boost::tuple<boost::tribool, CDataStream::iterator> parser_result = _msgParser.parse(_chain, _message, vRecv.begin(), vRecv.end());
            tribool result = get<0>(parser_result);
            vRecv.erase(vRecv.begin(), get<1>(parser_result));
            if (result) {
                if (_messageHandler.handleMessage(this, _message) ) fRet = true;
            }
            else if (!result) {
                log_warn("Peer %s sending bogus - disconnecting", addr.toString());
                _peerManager.post_stop(shared_from_this());
            }//                continue; // basically, if we get a false result, we should consider to disconnect from the Peer!
            else
                break;
        }

        // now if fRet is true, something were processed by the filters - we want to send to the peers / we check for which vSends cointains stuff and the we run
        
        if (fRet && nVersion > 0) {
            // first reply
            reply();
            
            // then trickle
            Peers peers = _peerManager.getAllPeers();
            size_t rand = GetRand(peers.size());
            for (Peers::iterator peer = peers.begin(); peer != peers.end(); ++peer)
                if(rand-- == 0) {
                    (*peer)->trickle();
                    break;
                }
            
            // then broadcast
            for (Peers::iterator peer = peers.begin(); peer != peers.end(); ++peer)
                (*peer)->broadcast();
            
            // now write to the peers with non-empty vSend buffers
            for (Peers::iterator peer = peers.begin(); peer != peers.end(); ++peer) {
                (*peer)->flush();
            }
        }
        
        // then wait for more data
        _socket.async_read_some(buffer(_buffer), boost::bind(&Peer::handle_read, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred));
        //        async_read(_socket, _recv, boost::bind(&Peer::handle_read, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred));
    }
int UpdatePeerData(PTorrentInfo torrent)
{
    PPeerInfo pi;
	Peers *p = torrent->peers;
	time_t curr = time(NULL);
	torrent->seed_count = 0;
	torrent->leech_count = 0;
    Peers::iterator it =  p->begin();
    while (it != p->end()) {
        pi = *it;
        if ((time_t)(pi->last_announce + INACTIVE_TIMEOUT) < curr) {
        	it = p->erase(it);
        } else {
	        if (pi->bytesleft == 0) { torrent->seed_count++; }
        	 else { torrent->leech_count++; }
	        ++it;
        }
    }//for
	return TRUE;
}
Exemple #3
0
void MainWindow::SwitchToPeerList(const Peers &peers)
{
    //connectUI_->hide();
    //streamUI_->hide();
    ui_ = LIST_PEERS;
    //peerListUI_->setVisible(true);
    //this->setCentralWidget(peerListUI_);

    peerListUI_->clear();
    QTreeWidgetItem * top0 = new QTreeWidgetItem(peerListUI_);
    top0->setText(0,"List of currently connected peers:");

    Peers::const_iterator i = peers.begin();
    for (; i != peers.end(); ++i){
        QTreeWidgetItem *child = new QTreeWidgetItem(top0);
        child->setText(0, i->second.c_str());
        child->setData(0,Qt::UserRole,QVariant(i->first));
    }
    top0->setExpanded(true);


}
bool EndpointFilter::operator()(Peer* origin, Message& msg) {
    log_trace("args: origin: %s, msg: %s", origin->endpoint().toString(), msg.command());
    if (origin->version() == 0) {
        throw OriginNotReady();
    }
    if (msg.command() == "addr") {
        vector<Endpoint> endpoints;

        istringstream is(msg.payload());
        is >> endpoints;
        
        // Don't want addr from older versions unless seeding
        if (origin->version() < 209)
            return true;
        if (origin->version() < 31402 && _endpointPool.getPoolSize() > 1000)
            return true;
        if (endpoints.size() > 1000) {
            log_error("message addr size() = %d", endpoints.size());
            return false;
        }
        
        log_debug("PEERS: %d addresses received from %s", endpoints.size(), origin->endpoint().toString());
        
        // Store the new addresses
        //        CAddrDB addrDB;
        //addrDB.TxnBegin();
        int64_t now = GetAdjustedTime();
        int64_t since = now - 10 * 60;
        BOOST_FOREACH(Endpoint& ep, endpoints) {
            log_trace("adding endpoint: %s", ep.toString());
            // ignore IPv6 for now, since it isn't implemented anyway
            if (!ep.isIPv4())
                continue;
            if (ep.getTime() <= 100000000 || ep.getTime() > now + 10 * 60)
                ep.setTime(now - 5 * 24 * 60 * 60);
            _endpointPool.addEndpoint(ep, 2 * 60 * 60);
            origin->AddAddressKnown(ep);
            
            // TODO: Rewrite this to instead query the Node for the proper set of peers, and send the addresses to them using peer->sendMessage("command", payload);
            
            if (ep.getTime() > since && !origin->fGetAddr && endpoints.size() <= 10 && ep.isRoutable()) {
                // Relay to a limited number of other nodes
                // Use deterministic randomness to send to the same nodes for 24 hours
                // at a time so the setAddrKnowns of the chosen nodes prevent repeats
                static uint256 hashSalt; // belongs to the Handler/Node...
                if (hashSalt == 0)
                    RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
                uint256 hashRand = hashSalt ^ uint256(((int64_t)ep.getIP())<<32) ^ uint256((UnixTime::s() + ep.getIP())/(24*60*60));
                hashRand = Hash(BEGIN(hashRand), END(hashRand));
                multimap<uint256, Peer*> mapMix;
                Peers peers = origin->getAllPeers();
                for(Peers::iterator peer = peers.begin(); peer != peers.end(); ++peer) { // vNodes is a list kept in the peerManager - the peerManager is referenced by the Node and the Peer - but we could query it - e.g. from the Node ??
                    if ((*peer)->version() < 31402)
                        continue;
                    unsigned int nPointer;
                    memcpy(&nPointer, &(*peer), sizeof(nPointer));
                    uint256 hashKey = hashRand ^ uint256(nPointer);
                    hashKey = Hash(BEGIN(hashKey), END(hashKey));
                    mapMix.insert(make_pair(hashKey, peer->get()));
                }
                int nRelayNodes = 2;
                for (multimap<uint256, Peer*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
                    ((*mi).second)->PushAddress(ep);
            }
        }
Exemple #5
0
            /** accepts and keeps track of connections. reads data
              from connected peers and notifies through virtual methods
              if packets can be deserialized 
             \param tls use GnuTLS for encryption 
             \param port listen for incoming connections at this port
             \param maxPeers maximum number of connected peers */
            void serve(bool tls, int port, int maxPeers) {
                if (tls)
                    sock.reset(new TLSSocket());
                else
                    sock.reset(new Socket());
                sock->setNonBlocking();
                sock->bind(port);
                sock->listen(maxPeers);
                Select select;
                /* Wait for a peer, send data and term */
                while (!closed)
                {
                    select.reset();
                    if (peers.size() < maxPeers)
                        select.input(sock->getFd());
                    for (typename Peers::iterator i = peers.begin(); i != peers.end(); i++) {
                        select.input((*i)->getFd());
                    }
                    if (select.select(100) == -1)
                        continue;
                    if (select.canRead(sock->getFd()) 
                            && peers.size() < maxPeers) {
                        try {
                            Socket* csock = sock->accept();

                            if (tls)  {
                                boost::threadpool::schedule(pool, 
                                        boost::bind(&Server::handshake, this, csock));
                            } else {
                                peers.push_back(boost::shared_ptr<PeerT>(new PeerT()));
                                csock->setNonBlocking();
                                peers.back()->setup(csock);
                                onJoin(*peers.back());

                            }
                        } catch (SocketExcept& e) {
                            std::cerr << e.what() << std::endl;
                        }
                    }
                    if (tls)  {
                        Socket* sock = NULL;
                        socketsReady.try_pop_front(sock);
                        if (sock) {
                            sock->setNonBlocking();
                            peers.push_back(boost::shared_ptr<PeerT>(new PeerT()));
                            peers.back()->setup(sock);
                            onJoin(*peers.back());
                        }
                    }
                    for (size_t i = 0; i < peers.size(); i++) {
                        boost::shared_ptr<PeerT>& p = peers[i];
                        if (select.canRead(p->getFd()))
                            p->onInput();
                        while (p->hasPacket()) {
                            onPacket(*p);
                        }
                    }
                    // collect dead peers
                    size_t count = peers.size();
                    for (size_t i = 0; i < count; ) {
                        if (!peers[i]->isActive()) {
                            onLeave(*peers[i]);

                            peers[i] = peers[peers.size() - 1];
                            count--;
                        } else
                            i++;
                    }
                    if (count < peers.size()) {
                        peers.resize(count);
                    }

                }
            }