diff --git a/include/opendht/dht.h b/include/opendht/dht.h index d11b5b895e4f56a815dcf9a6fad6cf3a18791526..676c3bbc471f9c6b6d21ee8f413c6ec26dfd7031 100644 --- a/include/opendht/dht.h +++ b/include/opendht/dht.h @@ -812,8 +812,8 @@ private: int sendPing(const sockaddr*, socklen_t, TransId tid); int sendPong(const sockaddr*, socklen_t, TransId tid); - int sendFindNode(const sockaddr*, socklen_t, TransId tid, - const InfoHash& target, want_t want, int confirm); + int sendFindNode (const sockaddr*, socklen_t, TransId tid, const InfoHash& target, want_t want, int confirm); + int sendGetValues(const sockaddr*, socklen_t, TransId tid, const InfoHash& target, want_t want, int confirm); int sendNodesValues(const sockaddr*, socklen_t, TransId tid, const uint8_t *nodes, unsigned nodes_len, @@ -824,8 +824,6 @@ private: const InfoHash& id, want_t want, const Blob& token={}, const std::vector<ValueStorage>& st = {}); - int sendGetValues(const sockaddr*, socklen_t, TransId tid, - const InfoHash& infohash, want_t want, int confirm); int sendListen(const sockaddr*, socklen_t, TransId, const InfoHash&, const Blob& token, int confirm); diff --git a/src/dht.cpp b/src/dht.cpp index b5ded203ff849de19a9406df3f38bde5f20fb7a1..fbfe88f6e42faf458ae7a419203eef317677a2e9 100644 --- a/src/dht.cpp +++ b/src/dht.cpp @@ -919,7 +919,10 @@ Dht::searchSendGetValues(Search& sr, SearchNode* pn, bool update) print_addr(n->node->ss, n->node->sslen).c_str(), n->node->pinged, print_dt(now-n->getStatus.request_time)); - sendGetValues((sockaddr*)&n->node->ss, n->node->sslen, TransId {TransPrefix::GET_VALUES, sr.tid}, sr.id, -1, n->node->reply_time >= now - UDP_REPLY_TIME); + if (sr.callbacks.empty() and sr.listeners.empty()) + sendFindNode((sockaddr*)&n->node->ss, n->node->sslen, TransId {TransPrefix::FIND_NODE, sr.tid}, sr.id, -1, n->node->reply_time >= now - UDP_REPLY_TIME); + else + sendGetValues((sockaddr*)&n->node->ss, n->node->sslen, TransId {TransPrefix::GET_VALUES, sr.tid}, sr.id, -1, n->node->reply_time >= now - UDP_REPLY_TIME); n->getStatus.request_time = now; pinged(*n->node); if (n->node->pinged > 1 and not n->candidate) { @@ -1388,6 +1391,8 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallba sr->nodes.clear(); sr->nodes.reserve(SEARCH_NODES+1); DHT_WARN("[search %s IPv%c] new search", id.toString().c_str(), (af == AF_INET) ? '4' : '6'); + if (search_id == 0) + search_id++; } if (callback) @@ -2424,7 +2429,7 @@ Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, soc bool gp = false; Search *sr = nullptr; std::shared_ptr<Node> n; - if (msg.tid.matches(TransPrefix::GET_VALUES, &ttid)) { + if (msg.tid.matches(TransPrefix::GET_VALUES, &ttid) or msg.tid.matches(TransPrefix::FIND_NODE, &ttid)) { gp = true; sr = findSearch(ttid, from->sa_family); } @@ -2576,13 +2581,15 @@ Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, soc //DHT_DEBUG("Sending pong."); sendPong(from, fromlen, msg.tid); break; - case MessageType::FindNode: + case MessageType::FindNode: { in_stats.find++; newNode(msg.id, from, fromlen, 1); DHT_DEBUG("[node %s %s] got 'find' request (%d).", msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.want); - sendClosestNodes(from, fromlen, msg.tid, msg.target, msg.want); + Blob ntoken = makeToken(from, false); + sendClosestNodes(from, fromlen, msg.tid, msg.target, msg.want, ntoken); break; - case MessageType::GetValues: + } + case MessageType::GetValues: { in_stats.get++; DHT_DEBUG("[node %s %s] got 'get' request for %s.", msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.info_hash.toString().c_str()); newNode(msg.id, from, fromlen, 1); @@ -2602,6 +2609,7 @@ Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, soc } } break; + } case MessageType::AnnounceValue: in_stats.put++; DHT_DEBUG("[node %s %s] got 'put' request for %s.", @@ -2988,6 +2996,36 @@ Dht::sendFindNode(const sockaddr *sa, socklen_t salen, TransId tid, return send(buffer.data(), buffer.size(), confirm ? 0 : MSG_CONFIRM, sa, salen); } +int +Dht::sendGetValues(const sockaddr *sa, socklen_t salen, + TransId tid, const InfoHash& infohash, + want_t want, int confirm) +{ + msgpack::sbuffer buffer; + msgpack::packer<msgpack::sbuffer> pk(&buffer); + pk.pack_map(5); + + pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0)); + pk.pack(std::string("id")); pk.pack(myid); + pk.pack(std::string("h")); pk.pack(infohash); + if (want > 0) { + pk.pack(std::string("w")); + pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0)); + if (want & WANT4) pk.pack(AF_INET); + if (want & WANT6) pk.pack(AF_INET6); + } + + pk.pack(std::string("q")); pk.pack(std::string("get")); + pk.pack(std::string("t")); pk.pack_bin(tid.size()); + pk.pack_bin_body((const char*)tid.data(), tid.size()); + pk.pack(std::string("y")); pk.pack(std::string("q")); + pk.pack(std::string("v")); pk.pack(my_v); + + out_stats.get++; + + return send(buffer.data(), buffer.size(), confirm ? 0 : MSG_CONFIRM, sa, salen); +} + void packToken(msgpack::packer<msgpack::sbuffer>& pk, Blob token) { @@ -3149,36 +3187,6 @@ Dht::sendClosestNodes(const sockaddr *sa, socklen_t salen, TransId tid, } } -int -Dht::sendGetValues(const sockaddr *sa, socklen_t salen, - TransId tid, const InfoHash& infohash, - want_t want, int confirm) -{ - msgpack::sbuffer buffer; - msgpack::packer<msgpack::sbuffer> pk(&buffer); - pk.pack_map(5); - - pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0)); - pk.pack(std::string("id")); pk.pack(myid); - pk.pack(std::string("h")); pk.pack(infohash); - if (want > 0) { - pk.pack(std::string("w")); - pk.pack_array(((want & WANT4)?1:0) + ((want & WANT6)?1:0)); - if (want & WANT4) pk.pack(AF_INET); - if (want & WANT6) pk.pack(AF_INET6); - } - - pk.pack(std::string("q")); pk.pack(std::string("get")); - pk.pack(std::string("t")); pk.pack_bin(tid.size()); - pk.pack_bin_body((const char*)tid.data(), tid.size()); - pk.pack(std::string("y")); pk.pack(std::string("q")); - pk.pack(std::string("v")); pk.pack(my_v); - - out_stats.get++; - - return send(buffer.data(), buffer.size(), confirm ? 0 : MSG_CONFIRM, sa, salen); -} - int Dht::sendListen(const sockaddr* sa, socklen_t salen, TransId tid, const InfoHash& infohash, const Blob& token, int confirm)