bool udp_tracker_connection::on_announce_response(aux::array_view<char const> buf) { if (buf.size() < 20) return false; buf = buf.cut_first(8); restart_read_timeout(); tracker_response resp; resp.interval = aux::read_int32(buf); resp.min_interval = 60; resp.incomplete = aux::read_int32(buf); resp.complete = aux::read_int32(buf); int const num_peers = int(buf.size()) / 6; if ((buf.size() % 6) != 0) { fail(error_code(errors::invalid_tracker_response_length)); return false; } boost::shared_ptr<request_callback> cb = requester(); #ifndef TORRENT_DISABLE_LOGGING if (cb) { cb->debug_log("<== UDP_TRACKER_RESPONSE [ url: %s ]", tracker_req().url.c_str()); } #endif if (!cb) { close(); return true; } std::vector<peer_entry> peer_list; resp.peers4.reserve(num_peers); for (int i = 0; i < num_peers; ++i) { ipv4_peer_entry e; memcpy(&e.ip[0], buf.data(), 4); buf = buf.cut_first(4); e.port = aux::read_uint16(buf); resp.peers4.push_back(e); } std::list<address> ip_list; for (std::vector<tcp::endpoint>::const_iterator i = m_endpoints.begin() , end(m_endpoints.end()); i != end; ++i) { ip_list.push_back(i->address()); } cb->tracker_response(tracker_req(), m_target.address(), ip_list , resp); close(); return true; }
bool udp_tracker_connection::on_connect_response(aux::array_view<char const> buf) { // ignore packets smaller than 16 bytes if (buf.size() < 16) return false; restart_read_timeout(); // skip header buf = buf.cut_first(8); // reset transaction update_transaction_id(); std::uint64_t const connection_id = read_int64(buf); std::lock_guard<std::mutex> l(m_cache_mutex); connection_cache_entry& cce = m_connection_cache[m_target.address()]; cce.connection_id = connection_id; cce.expires = aux::time_now() + seconds(m_man.settings().get_int(settings_pack::udp_tracker_token_expiry)); if (0 == (tracker_req().kind & tracker_request::scrape_request)) send_udp_announce(); else if (0 != (tracker_req().kind & tracker_request::scrape_request)) send_udp_scrape(); return true; }