bool http_tracker_connection::extract_peer_info(lazy_entry const& info, peer_entry& ret) { // extract peer id (if any) if (info.type() != lazy_entry::dict_t) { fail(error_code(errors::invalid_peer_dict)); return false; } lazy_entry const* i = info.dict_find_string("peer id"); if (i != 0 && 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) { fail(error_code(errors::invalid_tracker_response)); return false; } ret.ip = i->string_value(); // extract port i = info.dict_find_int("port"); if (i == 0) { fail(error_code(errors::invalid_tracker_response)); return false; } ret.port = (unsigned short)i->int_value(); return true; }
std::string parse_dht_client(lazy_entry const& e) { lazy_entry const* ver = e.dict_find_string("v"); if (!ver) return "generic"; std::string const& client = ver->string_value(); if (client.size() < 2) { ++g_unknown_message_input; return client; } else if (std::equal(client.begin(), client.begin() + 2, "Az")) { ++g_az_message_input; return "Azureus"; } else if (std::equal(client.begin(), client.begin() + 2, "UT")) { ++g_ut_message_input; return "uTorrent"; } else if (std::equal(client.begin(), client.begin() + 2, "LT")) { ++g_lt_message_input; return "libtorrent"; } else if (std::equal(client.begin(), client.begin() + 2, "MP")) { ++g_mp_message_input; return "MooPolice"; } else if (std::equal(client.begin(), client.begin() + 2, "GR")) { ++g_gr_message_input; return "GetRight"; } else if (std::equal(client.begin(), client.begin() + 2, "MO")) { ++g_mo_message_input; return "Mono Torrent"; } else { ++g_unknown_message_input; return client; } }
bool default_storage::verify_resume_data(lazy_entry const& rd, error_code& error) { lazy_entry const* file_priority = rd.dict_find_list("file_priority"); if (file_priority && file_priority->list_size() == files().num_files()) { m_file_priority.resize(file_priority->list_size()); for (int i = 0; i < file_priority->list_size(); ++i) m_file_priority[i] = boost::uint8_t(file_priority->list_int_value_at(i, 1)); } bool seed = false; if (lazy_entry const* pieces = rd.dict_find_string("pieces")) { if (int(pieces->string_length()) == m_files.num_pieces()) { seed = true; char const* p = pieces->string_ptr(); for (int i = 0; i < pieces->string_length(); ++i) { if ((p[i] & 1) == 1) continue; seed = false; break; } } } else { error = errors::missing_pieces; return false; } int flags = (settings().ignore_resume_timestamps ? ignore_timestamps : 0); return true; }
void http_tracker_connection::parse(int status_code, lazy_entry const& e) { boost::shared_ptr<request_callback> cb = requester(); if (!cb) return; int interval = int(e.dict_find_int_value("interval", 1800)); int min_interval = int(e.dict_find_int_value("min interval", 60)); std::string trackerid; lazy_entry const* tracker_id = e.dict_find_string("tracker id"); if (tracker_id) trackerid = tracker_id->string_value(); // parse the response lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { fail(error_code(errors::tracker_failure), status_code , failure->string_value().c_str(), interval, min_interval); return; } lazy_entry const* warning = e.dict_find_string("warning message"); if (warning) cb->tracker_warning(tracker_req(), warning->string_value()); std::vector<peer_entry> peer_list; if (tracker_req().kind == tracker_request::scrape_request) { std::string ih = tracker_req().info_hash.to_string(); lazy_entry const* files = e.dict_find_dict("files"); if (files == 0) { fail(error_code(errors::invalid_files_entry), -1, "" , interval, min_interval); return; } lazy_entry const* scrape_data = files->dict_find_dict(ih.c_str()); if (scrape_data == 0) { fail(error_code(errors::invalid_hash_entry), -1, "" , interval, min_interval); return; } int complete = int(scrape_data->dict_find_int_value("complete", -1)); int incomplete = int(scrape_data->dict_find_int_value("incomplete", -1)); int downloaded = int(scrape_data->dict_find_int_value("downloaded", -1)); int downloaders = int(scrape_data->dict_find_int_value("downloaders", -1)); cb->tracker_scrape_response(tracker_req(), complete , incomplete, downloaded, downloaders); return; } lazy_entry const* peers_ent = e.dict_find("peers"); if (peers_ent && peers_ent->type() == lazy_entry::string_t) { char const* peers = peers_ent->string_ptr(); int len = peers_ent->string_length(); for (int i = 0; i < len; i += 6) { if (len - i < 6) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v4_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else if (peers_ent && peers_ent->type() == lazy_entry::list_t) { int len = peers_ent->list_size(); for (int i = 0; i < len; ++i) { peer_entry p; if (!extract_peer_info(*peers_ent->list_at(i), p)) return; peer_list.push_back(p); } } else { peers_ent = 0; } #if TORRENT_USE_IPV6 lazy_entry const* ipv6_peers = e.dict_find_string("peers6"); if (ipv6_peers) { char const* peers = ipv6_peers->string_ptr(); int len = ipv6_peers->string_length(); for (int i = 0; i < len; i += 18) { if (len - i < 18) break; peer_entry p; p.pid.clear(); error_code ec; p.ip = detail::read_v6_address(peers).to_string(ec); p.port = detail::read_uint16(peers); if (ec) continue; peer_list.push_back(p); } } else { ipv6_peers = 0; } #else lazy_entry const* ipv6_peers = 0; #endif // if we didn't receive any peers. We don't care if we're stopping anyway if (peers_ent == 0 && ipv6_peers == 0 && tracker_req().event != tracker_request::stopped) { fail(error_code(errors::invalid_peers_entry), -1, "" , interval, min_interval); return; } // look for optional scrape info address external_ip; lazy_entry const* ip_ent = e.dict_find_string("external ip"); if (ip_ent) { char const* p = ip_ent->string_ptr(); if (ip_ent->string_length() == address_v4::bytes_type().size()) external_ip = detail::read_v4_address(p); #if TORRENT_USE_IPV6 else if (ip_ent->string_length() == address_v6::bytes_type().size()) external_ip = detail::read_v6_address(p); #endif } int complete = int(e.dict_find_int_value("complete", -1)); int incomplete = int(e.dict_find_int_value("incomplete", -1)); std::list<address> ip_list; if (m_tracker_connection) { error_code ec; ip_list.push_back(m_tracker_connection->socket().remote_endpoint(ec).address()); std::list<tcp::endpoint> const& epts = m_tracker_connection->endpoints(); for (std::list<tcp::endpoint>::const_iterator i = epts.begin() , end(epts.end()); i != end; ++i) { ip_list.push_back(i->address()); } } cb->tracker_response(tracker_req(), m_tracker_ip, ip_list, peer_list , interval, min_interval, complete, incomplete, external_ip, trackerid); }