Parse compact response from I2P tracker

This fixes #2
This commit is contained in:
Mikhail Titov 2015-06-27 17:11:50 -05:00
parent 007a580207
commit 5d3938b39b
3 changed files with 62 additions and 25 deletions

View File

@ -100,7 +100,11 @@ 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);
, bool scrape_request, sha1_hash scrape_ih
#if TORRENT_USE_I2P
, bool is_i2p=false
#endif
);
TORRENT_EXTRA_EXPORT bool extract_peer_info(bdecode_node const& info
, peer_entry& ret, error_code& ec);

View File

@ -333,7 +333,11 @@ namespace libtorrent
tracker_response resp = parse_tracker_response(data, size, ecode
, tracker_req().kind == tracker_request::scrape_request
, tracker_req().info_hash);
, tracker_req().info_hash
#if TORRENT_USE_I2P
, tracker_req().i2pconn != NULL
#endif
);
if (!resp.warning_message.empty())
cb->tracker_warning(tracker_req(), resp.warning_message);
@ -423,7 +427,11 @@ namespace libtorrent
}
tracker_response parse_tracker_response(char const* data, int size, error_code& ec
, bool scrape_request, sha1_hash scrape_ih)
, bool scrape_request, sha1_hash scrape_ih
#if TORRENT_USE_I2P
, bool is_i2p
#endif
)
{
tracker_response resp;
@ -499,16 +507,33 @@ 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 (is_i2p) {
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
{
if (len - i < 6) break;
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)

View File

@ -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"
@ -3395,20 +3398,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
@ -3624,6 +3629,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());