diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index b7acbaecb..a95c08a0e 100644 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -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); diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index a25f602a2..9ae7794bd 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -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) diff --git a/src/torrent.cpp b/src/torrent.cpp index 16bb9cb81..d4ed6e823 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -46,6 +46,9 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#if TORRENT_USE_I2P +# include +#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());