void get_item_observer::reply(msg const& m) { public_key pk; signature sig; sequence_number seq{0}; bdecode_node const r = m.message.dict_find_dict("r"); if (!r) { #ifndef TORRENT_DISABLE_LOGGING get_observer()->log(dht_logger::traversal, "[%p] missing response dict" , static_cast<void*>(algorithm())); #endif timeout(); return; } bdecode_node const k = r.dict_find_string("k"); if (k && k.string_length() == public_key::len) std::memcpy(pk.bytes.data(), k.string_ptr(), public_key::len); bdecode_node const s = r.dict_find_string("sig"); if (s && s.string_length() == signature::len) std::memcpy(sig.bytes.data(), s.string_ptr(), signature::len); bdecode_node const q = r.dict_find_int("seq"); if (q) { seq = sequence_number(q.int_value()); } else if (k && s) { timeout(); return; } bdecode_node v = r.dict_find("v"); if (v) { static_cast<get_item*>(algorithm())->got_data(v, pk, seq, sig); } find_data_observer::reply(m); }
// TODO: 2 returning a bool here is redundant. Instead this function should // return the peer_entry bool extract_peer_info(bdecode_node const& info, peer_entry& ret, error_code& ec) { // extract peer id (if any) if (info.type() != bdecode_node::dict_t) { ec.assign(errors::invalid_peer_dict, get_libtorrent_category()); return false; } bdecode_node i = info.dict_find_string("peer id"); if (i && i.string_length() == 20) { std::copy(i.string_ptr(), i.string_ptr()+20, ret.pid.begin()); } else { // if there's no peer_id, just initialize it to a bunch of zeroes std::fill_n(ret.pid.begin(), 20, 0); } // extract ip i = info.dict_find_string("ip"); if (i == 0) { ec.assign(errors::invalid_tracker_response, get_libtorrent_category()); return false; } ret.hostname = i.string_value(); // extract port i = info.dict_find_int("port"); if (i == 0) { ec.assign(errors::invalid_tracker_response, get_libtorrent_category()); return false; } ret.port = boost::uint16_t(i.int_value()); return true; }