forked from premiere/premiere-libtorrent
commit
68bc4f2cf4
|
@ -39,6 +39,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
namespace string
|
||||
{
|
||||
enum flags_t
|
||||
{
|
||||
// use lower case alphabet used with i2p
|
||||
lowercase = 0x1,
|
||||
// don't insert padding
|
||||
no_padding = 0x2,
|
||||
// shortcut used for addresses as sha256 hashes
|
||||
i2p = lowercase | no_padding
|
||||
};
|
||||
|
||||
}
|
||||
TORRENT_EXTRA_EXPORT std::string unescape_string(std::string const& s, error_code& ec);
|
||||
// replaces all disallowed URL characters by their %-encoding
|
||||
TORRENT_EXTRA_EXPORT std::string escape_string(const char* str, int len);
|
||||
|
@ -58,7 +71,7 @@ namespace libtorrent
|
|||
// encodes a string using the base64 scheme
|
||||
TORRENT_EXTRA_EXPORT std::string base64encode(std::string const& s);
|
||||
// encodes a string using the base32 scheme
|
||||
TORRENT_EXTRA_EXPORT std::string base32encode(std::string const& s);
|
||||
TORRENT_EXTRA_EXPORT std::string base32encode(std::string const& s, int flags=0);
|
||||
TORRENT_EXTRA_EXPORT std::string base32decode(std::string const& s);
|
||||
|
||||
TORRENT_EXTRA_EXPORT std::string url_has_argument(
|
||||
|
|
|
@ -397,6 +397,8 @@ namespace libtorrent
|
|||
|
||||
// The URL specified an i2p address, but no i2p router is configured
|
||||
no_i2p_router = 160,
|
||||
// i2p acceptor is not available yet, can't announce without endpoint
|
||||
no_i2p_endpoint = 161,
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
|
|||
private:
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
void connect_i2p_tracker(char const* destination);
|
||||
void on_i2p_resolve(error_code const& e
|
||||
, char const* destination);
|
||||
#endif
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace libtorrent
|
|||
|
||||
TORRENT_EXTRA_EXPORT tracker_response parse_tracker_response(
|
||||
char const* data, int size, error_code& ec
|
||||
, bool scrape_request, sha1_hash scrape_ih);
|
||||
, int flags, sha1_hash scrape_ih);
|
||||
|
||||
TORRENT_EXTRA_EXPORT bool extract_peer_info(bdecode_node const& info
|
||||
, peer_entry& ret, error_code& ec);
|
||||
|
|
|
@ -118,8 +118,12 @@ namespace libtorrent
|
|||
|
||||
enum kind_t
|
||||
{
|
||||
announce_request,
|
||||
scrape_request
|
||||
// do not compare against announce_request ! check if not scrape instead
|
||||
announce_request = 0,
|
||||
scrape_request = 1,
|
||||
// affects interpretation of peers string in HTTP response
|
||||
// see parse_tracker_response()
|
||||
i2p = 2
|
||||
};
|
||||
|
||||
std::string url;
|
||||
|
|
|
@ -2282,7 +2282,10 @@ namespace libtorrent
|
|||
std::string remote_address;
|
||||
std::back_insert_iterator<std::string> out(remote_address);
|
||||
detail::write_address(remote().address(), out);
|
||||
handshake["yourip"] = remote_address;
|
||||
#if TORRENT_USE_I2P
|
||||
if (!is_i2p(*get_socket()))
|
||||
#endif
|
||||
handshake["yourip"] = remote_address;
|
||||
handshake["reqq"] = m_settings.get_int(settings_pack::max_allowed_in_request_queue);
|
||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
TORRENT_ASSERT(t);
|
||||
|
|
|
@ -321,15 +321,23 @@ namespace libtorrent
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string base32encode(std::string const& s)
|
||||
std::string base32encode(std::string const& s, int flags)
|
||||
{
|
||||
static const char base32_table[] =
|
||||
static const char base32_table_canonical[] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7'
|
||||
};
|
||||
static const char base32_table_lowercase[] =
|
||||
{
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||
'y', 'z', '2', '3', '4', '5', '6', '7'
|
||||
};
|
||||
const char *base32_table = 0 != (flags & string::lowercase) ? base32_table_lowercase : base32_table_canonical;
|
||||
|
||||
int input_output_mapping[] = {0, 2, 4, 5, 7, 8};
|
||||
|
||||
|
@ -365,10 +373,13 @@ namespace libtorrent
|
|||
ret += base32_table[outbuf[j]];
|
||||
}
|
||||
|
||||
// write pad
|
||||
for (int j = 0; j < 8 - num_out; ++j)
|
||||
if (0 == (flags & string::no_padding))
|
||||
{
|
||||
ret += '=';
|
||||
// write pad
|
||||
for (int j = 0; j < 8 - num_out; ++j)
|
||||
{
|
||||
ret += '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -369,11 +369,16 @@ void http_connection::start(std::string const& hostname, int port
|
|||
#if TORRENT_USE_I2P
|
||||
if (is_i2p)
|
||||
{
|
||||
if (hostname.length() < 516) // Base64 encoded destination with optional .i2p
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("http_connection::on_i2p_resolve");
|
||||
add_outstanding_async("http_connection::on_i2p_resolve");
|
||||
#endif
|
||||
i2p_conn->async_name_lookup(hostname.c_str(), boost::bind(&http_connection::on_i2p_resolve
|
||||
, me, _1, _2));
|
||||
i2p_conn->async_name_lookup(hostname.c_str(), boost::bind(&http_connection::on_i2p_resolve
|
||||
, me, _1, _2));
|
||||
}
|
||||
else
|
||||
connect_i2p_tracker(hostname.c_str());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -470,19 +475,8 @@ void http_connection::close(bool force)
|
|||
}
|
||||
|
||||
#if TORRENT_USE_I2P
|
||||
void http_connection::on_i2p_resolve(error_code const& e
|
||||
, char const* destination)
|
||||
void http_connection::connect_i2p_tracker(char const* destination)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("http_connection::on_i2p_resolve");
|
||||
#endif
|
||||
if (e)
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
TORRENT_ASSERT(m_ssl == false);
|
||||
TORRENT_ASSERT(m_sock.get<socket_type>());
|
||||
|
@ -501,6 +495,21 @@ void http_connection::on_i2p_resolve(error_code const& e
|
|||
m_sock.async_connect(tcp::endpoint(), boost::bind(&http_connection::on_connect
|
||||
, shared_from_this(), _1));
|
||||
}
|
||||
|
||||
void http_connection::on_i2p_resolve(error_code const& e
|
||||
, char const* destination)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("http_connection::on_i2p_resolve");
|
||||
#endif
|
||||
if (e)
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
connect_i2p_tracker(destination);
|
||||
}
|
||||
#endif
|
||||
|
||||
void http_connection::on_resolve(error_code const& e
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace libtorrent
|
|||
{
|
||||
std::string url = tracker_req().url;
|
||||
|
||||
if (tracker_req().kind == tracker_request::scrape_request)
|
||||
if (0 != (tracker_req().kind & tracker_request::scrape_request))
|
||||
{
|
||||
// find and replace "announce" with "scrape"
|
||||
// in request
|
||||
|
@ -117,7 +117,7 @@ namespace libtorrent
|
|||
url += "info_hash=";
|
||||
url += escape_string((const char*)&tracker_req().info_hash[0], 20);
|
||||
|
||||
if (tracker_req().kind == tracker_request::announce_request)
|
||||
if (0 == (tracker_req().kind & tracker_request::scrape_request))
|
||||
{
|
||||
const char* event_string[] = {"completed", "started", "stopped", "paused"};
|
||||
|
||||
|
@ -168,10 +168,10 @@ namespace libtorrent
|
|||
#if TORRENT_USE_I2P
|
||||
if (i2p && tracker_req().i2pconn)
|
||||
{
|
||||
url += "&ip=";
|
||||
url += escape_string(tracker_req().i2pconn->local_endpoint().c_str()
|
||||
, tracker_req().i2pconn->local_endpoint().size());
|
||||
url += ".i2p";
|
||||
if (tracker_req().i2pconn->local_endpoint().empty())
|
||||
fail(error_code(errors::no_i2p_endpoint), -1, "Waiting for i2p acceptor from SAM bridge", 5);
|
||||
else
|
||||
url += "&ip=" + tracker_req ().i2pconn->local_endpoint () + ".i2p";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -332,8 +332,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
tracker_response resp = parse_tracker_response(data, size, ecode
|
||||
, tracker_req().kind == tracker_request::scrape_request
|
||||
, tracker_req().info_hash);
|
||||
, tracker_req().kind, tracker_req().info_hash);
|
||||
|
||||
if (!resp.warning_message.empty())
|
||||
cb->tracker_warning(tracker_req(), resp.warning_message);
|
||||
|
@ -354,7 +353,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// do slightly different things for scrape requests
|
||||
if (tracker_req().kind == tracker_request::scrape_request)
|
||||
if (0 != (tracker_req().kind & tracker_request::scrape_request))
|
||||
{
|
||||
cb->tracker_scrape_response(tracker_req(), resp.complete
|
||||
, resp.incomplete, resp.downloaded, resp.downloaders);
|
||||
|
@ -423,7 +422,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
tracker_response parse_tracker_response(char const* data, int size, error_code& ec
|
||||
, bool scrape_request, sha1_hash scrape_ih)
|
||||
, int flags, sha1_hash scrape_ih)
|
||||
{
|
||||
tracker_response resp;
|
||||
|
||||
|
@ -463,7 +462,7 @@ namespace libtorrent
|
|||
if (warning)
|
||||
resp.warning_message = warning.string_value();
|
||||
|
||||
if (scrape_request)
|
||||
if (0 != (flags & tracker_request::scrape_request))
|
||||
{
|
||||
bdecode_node files = e.dict_find_dict("files");
|
||||
if (!files)
|
||||
|
@ -499,16 +498,34 @@ namespace libtorrent
|
|||
{
|
||||
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 TORRENT_USE_I2P
|
||||
if (0 != (flags & tracker_request::i2p))
|
||||
{
|
||||
if (len - i < 6) break;
|
||||
error_code parse_error;
|
||||
for (int i = 0; i < len; i += 32)
|
||||
{
|
||||
if (len - i < 32) break;
|
||||
peer_entry p;
|
||||
p.hostname = base32encode(std::string(peers + i, 32), string::i2p);
|
||||
p.hostname += ".b32.i2p";
|
||||
p.port = 6881;
|
||||
resp.peers.push_back (p);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
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() == bdecode_node::list_t)
|
||||
|
|
|
@ -414,6 +414,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
error_code ec(result, get_i2p_category());
|
||||
switch (result)
|
||||
{
|
||||
case i2p_error::no_error:
|
||||
|
@ -421,7 +422,6 @@ namespace libtorrent
|
|||
break;
|
||||
default:
|
||||
{
|
||||
error_code ec (result, get_i2p_category ());
|
||||
handle_error (ec, h);
|
||||
return;
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ namespace libtorrent
|
|||
case read_connect_response:
|
||||
case read_session_create_response:
|
||||
case read_name_lookup_response:
|
||||
(*h)(e);
|
||||
(*h)(ec);
|
||||
std::vector<char>().swap(m_buffer);
|
||||
break;
|
||||
case read_accept_response:
|
||||
|
|
|
@ -1266,6 +1266,7 @@ namespace aux {
|
|||
#endif
|
||||
#if TORRENT_USE_I2P
|
||||
req.i2pconn = &m_i2p_conn;
|
||||
req.kind |= tracker_request::i2p;
|
||||
#endif
|
||||
|
||||
if (is_any(req.bind_ip)) req.bind_ip = m_listen_interface.address();
|
||||
|
|
|
@ -46,6 +46,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
#if TORRENT_USE_I2P
|
||||
# include <boost/algorithm/string/predicate.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
#include "libtorrent/ssl_stream.hpp"
|
||||
|
@ -3244,7 +3247,7 @@ namespace libtorrent
|
|||
req.filter = m_ip_filter;
|
||||
|
||||
req.info_hash = m_torrent_file->info_hash();
|
||||
req.kind = tracker_request::scrape_request;
|
||||
req.kind |= tracker_request::scrape_request;
|
||||
req.url = m_trackers[i].url;
|
||||
req.auth = tracker_login();
|
||||
req.key = tracker_key();
|
||||
|
@ -3267,7 +3270,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
|
||||
TORRENT_ASSERT(0 != (req.kind & tracker_request::scrape_request));
|
||||
|
||||
announce_entry* ae = find_tracker(req);
|
||||
if (ae)
|
||||
|
@ -3325,7 +3328,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(r.kind == tracker_request::announce_request);
|
||||
TORRENT_ASSERT(0 == (r.kind & tracker_request::scrape_request));
|
||||
|
||||
// TODO: 2 this looks suspicious. Figure out why it makes sense to use the
|
||||
// first IP in this list and leave a comment here
|
||||
|
@ -3418,20 +3421,22 @@ namespace libtorrent
|
|||
{
|
||||
// this is an i2p name, we need to use the sam connection
|
||||
// to do the name lookup
|
||||
/*
|
||||
m_ses.m_i2p_conn.async_name_lookup(i->ip.c_str()
|
||||
, boost::bind(&torrent::on_i2p_resolve
|
||||
, shared_from_this(), _1));
|
||||
*/
|
||||
// it seems like you're not supposed to do a name lookup
|
||||
// on the peers returned from the tracker, but just strip
|
||||
// the .i2p and use it as a destination
|
||||
std::string hostname = i->hostname.substr(i->hostname.size() - 4);
|
||||
torrent_state st = get_peer_list_state();
|
||||
need_peer_list();
|
||||
if (m_peer_list->add_i2p_peer(hostname.c_str(), peer_info::tracker, 0, &st))
|
||||
state_updated();
|
||||
peers_erased(st.erased);
|
||||
if (boost::algorithm::ends_with(i->hostname, ".b32.i2p"))
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
add_outstanding_async("torrent::on_i2p_resolve");
|
||||
#endif
|
||||
r.i2pconn->async_name_lookup(i->hostname.c_str()
|
||||
, boost::bind(&torrent::on_i2p_resolve
|
||||
, shared_from_this(), _1, _2));
|
||||
}
|
||||
else {
|
||||
torrent_state st = get_peer_list_state();
|
||||
need_peer_list();
|
||||
if (m_peer_list->add_i2p_peer (i->hostname.c_str (), peer_info::tracker, 0, &st))
|
||||
state_updated ();
|
||||
peers_erased (st.erased);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -3647,6 +3652,9 @@ namespace libtorrent
|
|||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
complete_async("torrent::on_i2p_resolve");
|
||||
#endif
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
if (ec)
|
||||
debug_log("i2p_resolve error: %s", ec.message().c_str());
|
||||
|
@ -7128,6 +7136,8 @@ namespace libtorrent
|
|||
error_code ec;
|
||||
torrent_peer const* p = *i;
|
||||
address addr = p->address();
|
||||
if (p->is_i2p_addr)
|
||||
continue;
|
||||
if (p->banned)
|
||||
{
|
||||
#if TORRENT_USE_IPV6
|
||||
|
@ -11801,7 +11811,7 @@ namespace libtorrent
|
|||
debug_log("*** tracker error: (%d) %s %s", ec.value()
|
||||
, ec.message().c_str(), msg.c_str());
|
||||
#endif
|
||||
if (r.kind == tracker_request::announce_request)
|
||||
if (0 == (r.kind & tracker_request::scrape_request))
|
||||
{
|
||||
announce_entry* ae = find_tracker(r);
|
||||
if (ae)
|
||||
|
@ -11824,7 +11834,7 @@ namespace libtorrent
|
|||
, ae?ae->fails:0, response_code, r.url, ec, msg);
|
||||
}
|
||||
}
|
||||
else if (r.kind == tracker_request::scrape_request)
|
||||
else if (0 != (r.kind & tracker_request::scrape_request))
|
||||
{
|
||||
if (response_code == 410)
|
||||
{
|
||||
|
|
|
@ -288,9 +288,9 @@ namespace libtorrent
|
|||
// use if if it hasn't expired
|
||||
if (aux::time_now() < cc->second.expires)
|
||||
{
|
||||
if (tracker_req().kind == tracker_request::announce_request)
|
||||
if (0 == (tracker_req().kind & tracker_request::scrape_request))
|
||||
send_udp_announce();
|
||||
else if (tracker_req().kind == tracker_request::scrape_request)
|
||||
else if (0 != (tracker_req().kind & tracker_request::scrape_request))
|
||||
send_udp_scrape();
|
||||
return;
|
||||
}
|
||||
|
@ -468,9 +468,9 @@ namespace libtorrent
|
|||
cce.connection_id = connection_id;
|
||||
cce.expires = aux::time_now() + seconds(m_man.settings().get_int(settings_pack::udp_tracker_token_expiry));
|
||||
|
||||
if (tracker_req().kind == tracker_request::announce_request)
|
||||
if (0 == (tracker_req().kind & tracker_request::scrape_request))
|
||||
send_udp_announce();
|
||||
else if (tracker_req().kind == tracker_request::scrape_request)
|
||||
else if (0 != (tracker_req().kind & tracker_request::scrape_request))
|
||||
send_udp_scrape();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,11 @@ TORRENT_TEST(string)
|
|||
TEST_CHECK(base32encode("fooba") == "MZXW6YTB");
|
||||
TEST_CHECK(base32encode("foobar") == "MZXW6YTBOI======");
|
||||
|
||||
// base32 for i2p
|
||||
TEST_CHECK(base32encode("fo", string::no_padding) == "MZXQ");
|
||||
TEST_CHECK(base32encode("foob", string::i2p) == "mzxw6yq");
|
||||
TEST_CHECK(base32encode("foobar", string::lowercase) == "mzxw6ytboi======");
|
||||
|
||||
TEST_CHECK(base32decode("") == "");
|
||||
TEST_CHECK(base32decode("MY======") == "f");
|
||||
TEST_CHECK(base32decode("MZXQ====") == "fo");
|
||||
|
|
|
@ -101,6 +101,66 @@ TORRENT_TEST(parse_peers4)
|
|||
}
|
||||
}
|
||||
|
||||
TORRENT_TEST(parse_i2p_peers)
|
||||
{
|
||||
// d8:completei8e10:incompletei4e8:intervali3600e5:peers352: ...
|
||||
char const response[] = { 0x64, 0x38, 0x3a, 0x63, 0x6f, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x74, 0x65, 0x69, 0x38, 0x65, 0x31, 0x30,
|
||||
0x3a, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x69, 0x34, 0x65, 0x38, 0x3a, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x76, 0x61, 0x6c, 0x69, 0x33, 0x36, 0x30, 0x30, 0x65,
|
||||
0x35, 0x3a, 0x70, 0x65, 0x65, 0x72, 0x73, 0x33, 0x35, 0x32,
|
||||
0x3a, 0xb1, 0x84, 0xe0, 0x96, 0x1f, 0xdb, 0xf2, 0xc9, 0xb0,
|
||||
0x53, 0x9a, 0x31, 0xa5, 0x35, 0xcd, 0xe8, 0x59, 0xa0, 0x7c,
|
||||
0xcd, 0xf2, 0x7c, 0x81, 0x81, 0x02, 0x11, 0x7b, 0xb4, 0x2a,
|
||||
0xd1, 0x20, 0x87, 0xd6, 0x1b, 0x06, 0x4c, 0xbb, 0x4c, 0x4e,
|
||||
0x30, 0xf9, 0xa3, 0x5d, 0x58, 0xa0, 0xa5, 0x10, 0x48, 0xfa,
|
||||
0x9b, 0x3b, 0x10, 0x86, 0x43, 0x5c, 0x2e, 0xa2, 0xa6, 0x22,
|
||||
0x31, 0xd0, 0x63, 0x6a, 0xfb, 0x4f, 0x25, 0x5b, 0xe2, 0x29,
|
||||
0xbc, 0xcc, 0xa0, 0x1a, 0x0a, 0x30, 0x45, 0x32, 0xa1, 0xc8,
|
||||
0x49, 0xf7, 0x9e, 0x03, 0xfd, 0x34, 0x80, 0x9a, 0x5b, 0xe9,
|
||||
0x78, 0x04, 0x48, 0x4e, 0xbd, 0xc0, 0x5c, 0xdd, 0x4f, 0xf8,
|
||||
0xbd, 0xc8, 0x4c, 0x4b, 0xcc, 0xf6, 0x25, 0x1b, 0xb3, 0x4d,
|
||||
0xc0, 0x91, 0xb1, 0x4b, 0xb6, 0xbd, 0x95, 0xb7, 0x8e, 0x88,
|
||||
0x79, 0xa8, 0xaa, 0x83, 0xa5, 0x7e, 0xec, 0x17, 0x60, 0x8d,
|
||||
0x1d, 0xe2, 0xbe, 0x16, 0x35, 0x83, 0x25, 0xee, 0xe4, 0xd5,
|
||||
0xbe, 0x54, 0x7b, 0xc8, 0x00, 0xdc, 0x5d, 0x56, 0xc7, 0x29,
|
||||
0xd2, 0x1e, 0x6d, 0x7a, 0xfb, 0xfc, 0xef, 0x36, 0x05, 0x8a,
|
||||
0xd0, 0xa7, 0x05, 0x4c, 0x11, 0xd5, 0x50, 0xe6, 0x2d, 0x7b,
|
||||
0xe0, 0x7d, 0x84, 0xda, 0x47, 0x48, 0x9d, 0xf9, 0x77, 0xa2,
|
||||
0xc7, 0x78, 0x90, 0xa4, 0xb5, 0x05, 0xf4, 0x95, 0xea, 0x36,
|
||||
0x7b, 0x92, 0x8c, 0x5b, 0xf7, 0x8b, 0x18, 0x94, 0x2c, 0x2f,
|
||||
0x88, 0xcf, 0xf8, 0xec, 0x5c, 0x52, 0xa8, 0x98, 0x8f, 0xd1,
|
||||
0xd3, 0xf0, 0xd8, 0x63, 0x19, 0x73, 0x33, 0xd7, 0xeb, 0x1f,
|
||||
0x87, 0x1c, 0x9f, 0x5b, 0xce, 0xe4, 0xd0, 0x15, 0x4e, 0x38,
|
||||
0xb7, 0xe3, 0xbd, 0x93, 0x64, 0xe2, 0x15, 0x3d, 0xfc, 0x56,
|
||||
0x4f, 0xd4, 0x19, 0x62, 0xe0, 0xb7, 0x59, 0x24, 0xff, 0x7f,
|
||||
0x32, 0xdf, 0x56, 0xa5, 0x62, 0x42, 0x87, 0xa3, 0x04, 0xec,
|
||||
0x09, 0x0a, 0x5b, 0x90, 0x48, 0x57, 0xc3, 0x32, 0x5f, 0x87,
|
||||
0xeb, 0xfb, 0x08, 0x69, 0x6f, 0xa9, 0x46, 0x46, 0xa9, 0x54,
|
||||
0x67, 0xec, 0x7b, 0x15, 0xc9, 0x68, 0x6b, 0x01, 0xb8, 0x10,
|
||||
0x59, 0x53, 0x9c, 0xe6, 0x1b, 0x2e, 0x70, 0x72, 0x6e, 0x82,
|
||||
0x7b, 0x03, 0xbc, 0xf2, 0x26, 0x9b, 0xb3, 0x91, 0xaa, 0xf1,
|
||||
0xba, 0x62, 0x12, 0xbb, 0x74, 0x4b, 0x70, 0x44, 0x74, 0x19,
|
||||
0xb2, 0xa1, 0x68, 0xd2, 0x30, 0xd6, 0xa5, 0x1b, 0xd9, 0xea,
|
||||
0x4d, 0xdb, 0x81, 0x8e, 0x66, 0xbf, 0x4d, 0x6c, 0x32, 0x66,
|
||||
0xc2, 0x8a, 0x22, 0x6b, 0x47, 0xc1, 0xd1, 0x52, 0x61, 0x66,
|
||||
0xa0, 0x75, 0xab, 0x65 };
|
||||
error_code ec;
|
||||
tracker_response resp = parse_tracker_response(response, sizeof(response)
|
||||
, ec, tracker_request::i2p, sha1_hash());
|
||||
|
||||
TEST_EQUAL(ec, error_code());
|
||||
TEST_EQUAL(resp.peers.size(), 11);
|
||||
|
||||
if (resp.peers.size() == 11)
|
||||
{
|
||||
TEST_EQUAL(resp.peers[0].hostname, "wgcobfq73pzmtmcttiy2knon5bm2a7gn6j6idaiccf53ikwrecdq.b32.i2p");
|
||||
// TEST_EQUAL(resp.peers[9].hostname, "cbmvhhhgdmxha4toqj5qhphse2n3henk6g5geev3orfxardudgza.b32.i2p");
|
||||
TEST_EQUAL(resp.peers[10].hostname, "ufunemgwuun5t2sn3oay4zv7jvwdezwcrirgwr6b2fjgczvaowvq.b32.i2p");
|
||||
}
|
||||
}
|
||||
|
||||
TORRENT_TEST(parse_interval)
|
||||
{
|
||||
char const response[] = "d8:intervali1042e12:min intervali10e5:peers0:e";
|
||||
|
|
Loading…
Reference in New Issue