int lazy_bdecode(char const* start, char const* end , lazy_entry& ret, int depth_limit, int item_limit) { error_code ec; int pos; return lazy_bdecode(start, end, ret, ec, &pos, depth_limit, item_limit); }
void save_settings::load_impl(std::string filename, error_code& ec) { std::vector<char> buf; if (load_file(filename, buf, ec) < 0) return; lazy_entry sett; if (lazy_bdecode(&buf[0], &buf[0] + buf.size(), sett, ec) != 0) return; m_ses.load_state(sett); // load the custom int and string keys if (sett.type() != lazy_entry::dict_t) return; int num_items = sett.dict_size(); for (int i = 0; i < num_items; ++i) { lazy_entry const* item; std::string key; boost::tie(key, item) = sett.dict_at(i); if (item->type() == lazy_entry::string_t) { m_strings[key] = item->string_value(); } else if (item->type() == lazy_entry::int_t) { m_ints[key] = item->int_value(); } } }
void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::intrusive_ptr<http_tracker_connection> me(this); if (ec && ec != asio::error::eof) { fail(-1, ec.message().c_str()); return; } if (!parser.header_finished()) { fail(-1, "premature end of file"); return; } if (parser.status_code() != 200) { fail(parser.status_code(), parser.message().c_str()); return; } if (ec && ec != asio::error::eof) { fail(parser.status_code(), ec.message().c_str()); return; } received_bytes(size + parser.body_start()); // handle tracker response lazy_entry e; int res = lazy_bdecode(data, data + size, e); if (res == 0 && e.type() == lazy_entry::dict_t) { parse(parser.status_code(), e); } else { std::string error_str("invalid encoding of tracker response: \""); for (char const* i = data, *end(data + size); i != end; ++i) { if (*i >= ' ' && *i <= '~') error_str += *i; else { char val[30]; snprintf(val, sizeof(val), "0x%02x ", *i); error_str += val; } } error_str += "\""; fail(parser.status_code(), error_str.c_str()); } close(); }
void session::load_state(entry const& ses_state) { std::vector<char> buf; bencode(std::back_inserter(buf), ses_state); lazy_entry e; error_code ec; int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec); TORRENT_ASSERT(ret == 0); TORRENT_SYNC_CALL1(load_state, &e); }
void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { // keep this alive boost::intrusive_ptr<http_tracker_connection> me(this); if (ec && ec != asio::error::eof) { fail(ec); return; } if (!parser.header_finished()) { fail(asio::error::eof); return; } if (parser.status_code() != 200) { fail(error_code(parser.status_code(), get_http_category()) , parser.status_code(), parser.message().c_str()); return; } if (ec && ec != asio::error::eof) { fail(ec, parser.status_code()); return; } received_bytes(size + parser.body_start()); // Howdy Patch to work around extra lines in tracker responses. while (data && (*data == 0x0d || *data == 0x0a)) { data++; size--; } // handle tracker response lazy_entry e; error_code ecode; int res = lazy_bdecode(data, data + size, e, ecode); if (res == 0 && e.type() == lazy_entry::dict_t) { parse(parser.status_code(), e); } else { fail(ecode, parser.status_code()); } close(); }
void session::load_state(entry const& ses_state) { if (ses_state.type() == entry::undefined_t) return; std::vector<char> buf; bencode(std::back_inserter(buf), ses_state); lazy_entry e; error_code ec; int ret = lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec); TORRENT_ASSERT(ret == 0); #ifndef BOOST_NO_EXCEPTIONS if (ret != 0) throw libtorrent_exception(ec); #endif TORRENT_SYNC_CALL1(load_state, &e); }
void session::load_state(entry const& ses_state) { if (ses_state.type() == entry::undefined_t) return; std::vector<char> buf; bencode(std::back_inserter(buf), ses_state); lazy_entry e; error_code ec; #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS int ret = #endif lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec); TORRENT_ASSERT(ret == 0); TORRENT_SYNC_CALL1(load_state, &e); }
uTorrentParser::uTorrentParser(entry const& torrent_file) : torrent_info(m_info_hash) { std::vector<char> tmp; std::back_insert_iterator<std::vector<char> > out(tmp); bencode(out, torrent_file); lazy_entry e; if (tmp.size() == 0 || lazy_bdecode(&tmp[0], &tmp[0] + tmp.size(), e) != 0) { #ifndef BOOST_NO_EXCEPTIONS throw invalid_torrent_file(errors::invalid_bencoding); #endif return; } error_code ec; #ifndef BOOST_NO_EXCEPTIONS if (!parse_torrent_file(e, ec)) throw invalid_torrent_file(ec); #else parse_torrent_file(e, ec); #endif }
tracker_response parse_tracker_response(char const* data, int size, error_code& ec , bool scrape_request, sha1_hash scrape_ih) { tracker_response resp; lazy_entry e; int res = lazy_bdecode(data, data + size, e, ec); if (ec) return resp; if (res != 0 || e.type() != lazy_entry::dict_t) { ec.assign(errors::invalid_tracker_response, get_libtorrent_category()); return resp; } int interval = int(e.dict_find_int_value("interval", 0)); // if no interval is specified, default to 30 minutes if (interval == 0) interval = 1800; int min_interval = int(e.dict_find_int_value("min interval", 30)); resp.interval = interval; resp.min_interval = min_interval; lazy_entry const* tracker_id = e.dict_find_string("tracker id"); if (tracker_id) resp.trackerid = tracker_id->string_value(); // parse the response lazy_entry const* failure = e.dict_find_string("failure reason"); if (failure) { resp.failure_reason = failure->string_value(); ec.assign(errors::tracker_failure, get_libtorrent_category()); return resp; } lazy_entry const* warning = e.dict_find_string("warning message"); if (warning) resp.warning_message = warning->string_value(); if (scrape_request) { lazy_entry const* files = e.dict_find_dict("files"); if (files == 0) { ec.assign(errors::invalid_files_entry, get_libtorrent_category()); return resp; } lazy_entry const* scrape_data = files->dict_find_dict( scrape_ih.to_string()); if (scrape_data == 0) { ec.assign(errors::invalid_hash_entry, get_libtorrent_category()); return resp; } resp.complete = int(scrape_data->dict_find_int_value("complete", -1)); resp.incomplete = int(scrape_data->dict_find_int_value("incomplete", -1)); resp.downloaded = int(scrape_data->dict_find_int_value("downloaded", -1)); resp.downloaders = int(scrape_data->dict_find_int_value("downloaders", -1)); return resp; } // look for optional scrape info resp.complete = int(e.dict_find_int_value("complete", -1)); resp.incomplete = int(e.dict_find_int_value("incomplete", -1)); resp.downloaded = int(e.dict_find_int_value("downloaded", -1)); 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(); resp.peers4.reserve(len / 6); for (int i = 0; i < len; i += 6) { if (len - i < 6) break; ipv4_peer_entry p; error_code ec; p.ip = detail::read_v4_address(peers).to_v4().to_bytes(); p.port = detail::read_uint16(peers); resp.peers4.push_back(p); } } else if (peers_ent && peers_ent->type() == lazy_entry::list_t) { int len = peers_ent->list_size(); resp.peers.reserve(len); error_code parse_error; for (int i = 0; i < len; ++i) { peer_entry p; if (!extract_peer_info(*peers_ent->list_at(i), p, parse_error)) continue; resp.peers.push_back(p); } // only report an error if all peer entries are invalid if (resp.peers.empty() && parse_error) { ec = parse_error; return resp; } } 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(); resp.peers6.reserve(len / 18); for (int i = 0; i < len; i += 18) { if (len - i < 18) break; ipv6_peer_entry p; p.ip = detail::read_v6_address(peers).to_v6().to_bytes(); p.port = detail::read_uint16(peers); resp.peers6.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) { ec.assign(errors::invalid_peers_entry, get_libtorrent_category()); return resp; } */ 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() == int(address_v4::bytes_type().size())) resp.external_ip = detail::read_v4_address(p); #if TORRENT_USE_IPV6 else if (ip_ent->string_length() == int(address_v6::bytes_type().size())) resp.external_ip = detail::read_v6_address(p); #endif } return resp; }