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; }
void ChannelServerApp::disconnect( const Mercury::Address & srcAddr, const ServerInterface::disconnectArgs & args ) { Peers::iterator peerIter = peers_.find( srcAddr ); if (peerIter != peers_.end()) { peerIter->second->disconnect( args.seq ); peers_.erase( peerIter ); if (peers_.empty()) { this->nub().breakProcessing(); } } else { ERROR_MSG( "ChannelServerApp::disconnectArgs: " "Got message from unknown peer at %s\n", srcAddr.c_str() ); } }
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); } }
/** 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); } } }