# Fixes an interoperability issue in the get_peers handling, now it # behaves according to the clarified BEP-0005. Also fixes a minor # issue of not being able to generate error packets. Index: libtorrent/src/dht/dht_tracker.h =================================================================== --- libtorrent/src/dht/dht_tracker.h (revision 1063) +++ libtorrent/src/dht/dht_tracker.h (working copy) @@ -65,7 +65,7 @@ size_t size() const { return m_peers.size(); } void add_peer(uint32_t addr, uint16_t port); - std::string get_peers(unsigned int maxPeers = max_peers); + Object get_peers(unsigned int maxPeers = max_peers); // Remove old announces from the tracker that have not reannounced for // more than the given number of seconds. Index: libtorrent/src/dht/dht_transaction.cc =================================================================== --- libtorrent/src/dht/dht_transaction.cc (revision 1063) +++ libtorrent/src/dht/dht_transaction.cc (working copy) @@ -252,7 +252,7 @@ } void -DhtAnnounce::receive_peers(const std::string& peers) { +DhtAnnounce::receive_peers(const Object& peers) { m_tracker->receive_peers(peers); } Index: libtorrent/src/dht/dht_server.cc =================================================================== --- libtorrent/src/dht/dht_server.cc (revision 1063) +++ libtorrent/src/dht/dht_server.cc (working copy) @@ -302,8 +302,7 @@ reply.insert_key("nodes", std::string(compact, end)); } else { - Object& values = reply.insert_key("values", Object::create_list()); - values.insert_back(tracker->get_peers()); + reply.insert_key("values", Object::create_list()).as_list().swap(tracker->get_peers().as_list()); } } @@ -417,7 +416,7 @@ transaction->complete(true); if (response.has_key_list("values")) - announce->receive_peers((*response.get_key_list("values").begin()).as_string()); + announce->receive_peers(response.get_key("values")); if (response.has_key_string("token")) add_transaction(new DhtTransactionAnnouncePeer(transaction->id(), transaction->address(), announce->target(), response.get_key_string("token")), packet_prio_low); @@ -641,6 +640,7 @@ sstream.imbue(std::locale::classic()); while (true) { + Object request; rak::socket_address sa; int type = '?'; const Object* transactionId = NULL; @@ -656,7 +656,6 @@ total += read; sstream.str(std::string(buffer, read)); - Object request; sstream >> request; // If it's not a valid bencode dictionary at all, it's probably not a DHT Index: libtorrent/src/dht/dht_transaction.h =================================================================== --- libtorrent/src/dht/dht_transaction.h (revision 1063) +++ libtorrent/src/dht/dht_transaction.h (working copy) @@ -178,7 +178,7 @@ // counts announces instead. const_accessor start_announce(); - void receive_peers(const std::string& peers); + void receive_peers(const Object& peer_list); void update_status(); private: Index: libtorrent/src/dht/dht_tracker.cc =================================================================== --- libtorrent/src/dht/dht_tracker.cc (revision 1063) +++ libtorrent/src/dht/dht_tracker.cc (working copy) @@ -79,7 +79,7 @@ // Return compact info (6 bytes) for up to 30 peers, returning different // peers for each call if there are more. -std::string +Object DhtTracker::get_peers(unsigned int maxPeers) { PeerList::iterator first = m_peers.begin(); PeerList::iterator last = m_peers.end(); @@ -94,7 +94,11 @@ last = first + maxPeers; } - return std::string(first->c_str(), last->c_str()); + Object peers = Object::create_list(); + for (; first != last; ++first) + peers.insert_back(std::string(first->c_str(), sizeof(*first))); + + return peers; } // Remove old announces. Index: libtorrent/src/tracker/tracker_dht.h =================================================================== --- libtorrent/src/tracker/tracker_dht.h (revision 1063) +++ libtorrent/src/tracker/tracker_dht.h (working copy) @@ -71,7 +71,7 @@ bool has_peers() const { return !m_peers.empty(); } - void receive_peers(const std::string& peers); + void receive_peers(const Object& peer_list); void receive_success(); void receive_failed(const char* msg); void receive_progress(int replied, int contacted); Index: libtorrent/src/tracker/tracker_dht.cc =================================================================== --- libtorrent/src/tracker/tracker_dht.cc (revision 1063) +++ libtorrent/src/tracker/tracker_dht.cc (working copy) @@ -114,11 +114,13 @@ } void -TrackerDht::receive_peers(const std::string& peers) { +TrackerDht::receive_peers(const Object& peer_list) { if (!is_busy()) throw internal_error("TrackerDht::receive_peers called while not busy."); - m_peers.parse_address_compact(peers); + Object::list_type peers = peer_list.as_list(); + for (Object::list_type::const_iterator itr = peers.begin(); itr != peers.end(); ++itr) + m_peers.parse_address_compact(itr->as_string()); } void