void timeout() override { if (flags & flag_done) return; flags |= flag_done; bdecode_node e; msg m(e, target_ep()); static_cast<direct_traversal*>(algorithm())->invoke_cb(m); }
void traversal_observer::reply(msg const& m) { bdecode_node r = m.message.dict_find_dict("r"); if (!r) { #ifndef TORRENT_DISABLE_LOGGING if (get_observer() != nullptr) { get_observer()->log(dht_logger::traversal , "[%p] missing response dict" , static_cast<void*>(algorithm())); } #endif return; } #ifndef TORRENT_DISABLE_LOGGING dht_observer* logger = get_observer(); if (logger != nullptr && logger->should_log(dht_logger::traversal)) { bdecode_node nid = r.dict_find_string("id"); char hex_id[41]; aux::to_hex({nid.string_ptr(), 20}, hex_id); logger->log(dht_logger::traversal , "[%p] RESPONSE id: %s invoke-count: %d addr: %s type: %s" , static_cast<void*>(algorithm()), hex_id, algorithm()->invoke_count() , print_endpoint(target_ep()).c_str(), algorithm()->name()); } #endif // look for nodes #if TORRENT_USE_IPV6 udp protocol = algorithm()->get_node().protocol(); #endif char const* nodes_key = algorithm()->get_node().protocol_nodes_key(); bdecode_node n = r.dict_find_string(nodes_key); if (n) { char const* nodes = n.string_ptr(); char const* end = nodes + n.string_length(); while (end - nodes >= 20 + detail::address_size(protocol) + 2) { node_id id; std::copy(nodes, nodes + 20, id.begin()); nodes += 20; udp::endpoint ep; #if TORRENT_USE_IPV6 if (protocol == udp::v6()) ep = detail::read_v6_endpoint<udp::endpoint>(nodes); else #endif ep = detail::read_v4_endpoint<udp::endpoint>(nodes); algorithm()->traverse(id, ep); } } bdecode_node id = r.dict_find_string("id"); if (!id || id.string_length() != 20) { #ifndef TORRENT_DISABLE_LOGGING if (get_observer() != nullptr) { get_observer()->log(dht_logger::traversal, "[%p] invalid id in response" , static_cast<void*>(algorithm())); } #endif return; } // in case we didn't know the id of this peer when we sent the message to // it. For instance if it's a bootstrap node. set_id(node_id(id.string_ptr())); }