made the trackers pick the most suitable interface to connect to (IPv6/Ipv4 issue). added Mono Torrent to identify_client and dht statistics.

This commit is contained in:
Arvid Norberg 2007-03-02 18:40:02 +00:00
parent be574bcc33
commit 7e3a415d0b
10 changed files with 92 additions and 21 deletions

View File

@ -119,6 +119,7 @@ namespace libtorrent
, std::string const& hostname
, unsigned short port
, std::string request
, address bind_infc
, boost::weak_ptr<request_callback> c
, session_settings const& stn
, std::string const& password = "");

View File

@ -147,6 +147,7 @@ namespace libtorrent { namespace dht
int m_lt_message_input;
int m_mp_message_input;
int m_gr_message_input;
int m_mo_message_input;
int m_total_in_bytes;
int m_total_out_bytes;

View File

@ -197,6 +197,7 @@ namespace libtorrent
tracker_connection(tracker_manager& man
, tracker_request req
, asio::strand& str
, address bind_interface
, boost::weak_ptr<request_callback> r);
request_callback& requester();
@ -208,10 +209,12 @@ namespace libtorrent
void fail(int code, char const* msg);
void fail_timeout();
void close();
address const& bind_interface() const { return m_bind_interface; }
protected:
boost::weak_ptr<request_callback> m_requester;
private:
address m_bind_interface;
tracker_manager& m_man;
const tracker_request m_req;
};
@ -227,6 +230,7 @@ namespace libtorrent
asio::strand& str
, tracker_request r
, std::string const& auth
, address bind_infc
, boost::weak_ptr<request_callback> c
= boost::weak_ptr<request_callback>());
void abort_all_requests();

View File

@ -71,6 +71,7 @@ namespace libtorrent
, tracker_request const& req
, std::string const& hostname
, unsigned short port
, address bind_infc
, boost::weak_ptr<request_callback> c
, session_settings const& stn);
@ -87,7 +88,7 @@ namespace libtorrent
boost::intrusive_ptr<udp_tracker_connection> self()
{ return boost::intrusive_ptr<udp_tracker_connection>(this); }
void name_lookup(asio::error_code const& error, tcp::resolver::iterator i);
void name_lookup(asio::error_code const& error, udp::resolver::iterator i);
void timeout(asio::error_code const& error);
void send_udp_connect();
@ -104,8 +105,7 @@ namespace libtorrent
tracker_manager& m_man;
asio::strand& m_strand;
tcp::resolver m_name_lookup;
int m_port;
udp::resolver m_name_lookup;
boost::shared_ptr<datagram_socket> m_socket;
udp::endpoint m_target;
udp::endpoint m_sender;

View File

@ -277,10 +277,11 @@ namespace libtorrent
, std::string const& hostname
, unsigned short port
, std::string request
, address bind_infc
, boost::weak_ptr<request_callback> c
, session_settings const& stn
, std::string const& auth)
: tracker_connection(man, req, str, c)
: tracker_connection(man, req, str, bind_infc, c)
, m_man(man)
, m_strand(str)
, m_name_lookup(m_strand.io_service())
@ -499,9 +500,35 @@ namespace libtorrent
if (has_requester()) requester().debug_log("tracker name lookup successful");
#endif
restart_read_timeout();
// look for an address that has the same kind as the one
// we're listening on. To make sure the tracker get our
// correct listening address.
tcp::resolver::iterator target = i;
tcp::resolver::iterator end;
tcp::endpoint target_address = *i;
for (; target != end && target->endpoint().address().is_v4()
!= bind_interface().is_v4(); ++target);
if (target == end)
{
assert(target_address.address().is_v4() != bind_interface().is_v4());
if (has_requester())
{
std::string tracker_address_type = target_address.address().is_v4() ? "IPv4" : "IPv6";
std::string bind_address_type = bind_interface().is_v4() ? "IPv4" : "IPv6";
requester().tracker_warning("the tracker only resolves to an "
+ tracker_address_type + " address, and your listen interface is an "
+ bind_address_type + " address. This may prevent you from incoming connections.");
}
}
else
{
target_address = *target;
}
if (has_requester()) requester().m_tracker_address = target_address;
m_socket.reset(new stream_socket(m_name_lookup.io_service()));
if (has_requester()) requester().m_tracker_address = *i;
m_socket->async_connect(*i, bind(&http_tracker_connection::connected, self(), _1));
m_socket->async_connect(target_address, bind(&http_tracker_connection::connected, self(), _1));
}
catch (std::exception& e)
{
@ -676,7 +703,7 @@ namespace libtorrent
req.url = location;
m_man.queue_request(m_strand, req
, m_password, m_requester);
, m_password, bind_interface(), m_requester);
close();
return;
}

View File

@ -159,6 +159,7 @@ namespace
, map_entry("LT", "libtorrent")
, map_entry("M", "Mainline")
, map_entry("ML", "MLDonkey")
, map_entry("MO", "Mono Torrent")
, map_entry("MP", "MooPolice")
, map_entry("MT", "Moonlight Torrent")
, map_entry("O", "Osprey Permaseed")

View File

@ -181,6 +181,7 @@ namespace libtorrent { namespace dht
m_lt_message_input = 0;
m_mp_message_input = 0;
m_gr_message_input = 0;
m_mo_message_input = 0;
m_total_in_bytes = 0;
m_total_out_bytes = 0;
m_queries_out_bytes = 0;
@ -345,6 +346,7 @@ namespace libtorrent { namespace dht
<< "\t" << (m_lt_message_input / float(tick_period))
<< "\t" << (m_mp_message_input / float(tick_period))
<< "\t" << (m_gr_message_input / float(tick_period))
<< "\t" << (m_mo_message_input / float(tick_period))
<< "\t" << (m_total_in_bytes / float(tick_period*60))
<< "\t" << (m_total_out_bytes / float(tick_period*60))
<< "\t" << (m_queries_out_bytes / float(tick_period*60))
@ -444,6 +446,11 @@ namespace libtorrent { namespace dht
++m_gr_message_input;
TORRENT_LOG(dht_tracker) << " client: GetRight";
}
else if (client.size() > 1 && std::equal(client.begin(), client.begin() + 2, "MO"))
{
++m_mo_message_input;
TORRENT_LOG(dht_tracker) << " client: Mono Torrent";
}
else
{
TORRENT_LOG(dht_tracker) << " client: generic";

View File

@ -959,7 +959,7 @@ namespace libtorrent { namespace detail
req.listen_port = m_listen_interface.port();
req.key = m_key;
m_tracker_manager.queue_request(m_strand, req, t.tracker_login()
, i->second);
, m_listen_interface.address(), i->second);
if (m_alerts.should_post(alert::info))
{
@ -1086,9 +1086,9 @@ namespace libtorrent { namespace detail
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
m_tracker_loggers.push_back(tl);
m_tracker_manager.queue_request(m_strand, req, login, tl);
m_tracker_manager.queue_request(m_strand, req, login, m_listen_interface.address(), tl);
#else
m_tracker_manager.queue_request(m_strand, req, login);
m_tracker_manager.queue_request(m_strand, req, login, m_listen_interface.address());
#endif
}
}
@ -1375,10 +1375,10 @@ namespace libtorrent { namespace detail
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
m_tracker_loggers.push_back(tl);
m_tracker_manager.queue_request(m_strand, req
, t.tracker_login(), tl);
, t.tracker_login(), m_listen_interface.address(), tl);
#else
m_tracker_manager.queue_request(m_strand, req
, t.tracker_login());
, t.tracker_login(), m_listen_interface.address());
#endif
if (m_alerts.should_post(alert::info))

View File

@ -382,11 +382,13 @@ namespace libtorrent
tracker_manager& man
, tracker_request req
, asio::strand& str
, address bind_interface_
, boost::weak_ptr<request_callback> r)
: timeout_handler(str)
, m_requester(r)
, m_man(man)
, m_req(req)
, m_bind_interface(bind_interface_)
{}
request_callback& tracker_connection::requester()
@ -484,6 +486,7 @@ namespace libtorrent
asio::strand& str
, tracker_request req
, std::string const& auth
, address bind_infc
, boost::weak_ptr<request_callback> c)
{
mutex_t::scoped_lock l(m_mutex);
@ -512,6 +515,7 @@ namespace libtorrent
, hostname
, port
, request_string
, bind_infc
, c
, m_settings
, auth);
@ -524,6 +528,7 @@ namespace libtorrent
, req
, hostname
, port
, bind_infc
, c
, m_settings);
}

View File

@ -78,20 +78,20 @@ namespace libtorrent
, tracker_request const& req
, std::string const& hostname
, unsigned short port
, address bind_infc
, boost::weak_ptr<request_callback> c
, session_settings const& stn)
: tracker_connection(man, req, str, c)
: tracker_connection(man, req, str, bind_infc, c)
, m_man(man)
, m_strand(str)
, m_name_lookup(m_strand.io_service())
, m_port(port)
, m_transaction_id(0)
, m_connection_id(0)
, m_settings(stn)
, m_attempts(0)
{
m_socket.reset(new datagram_socket(m_strand.io_service()));
tcp::resolver::query q(hostname, "0");
udp::resolver::query q(hostname, boost::lexical_cast<std::string>(port));
m_name_lookup.async_resolve(q
, m_strand.wrap(boost::bind(
&udp_tracker_connection::name_lookup, self(), _1, _2)));
@ -100,11 +100,11 @@ namespace libtorrent
}
void udp_tracker_connection::name_lookup(asio::error_code const& error
, tcp::resolver::iterator i) try
, udp::resolver::iterator i) try
{
if (error == asio::error::operation_aborted) return;
if (!m_socket) return; // the operation was aborted
if (error || i == tcp::resolver::iterator())
if (error || i == udp::resolver::iterator())
{
fail(-1, error.message().c_str());
return;
@ -114,10 +114,35 @@ namespace libtorrent
if (has_requester()) requester().debug_log("udp tracker name lookup successful");
#endif
restart_read_timeout();
m_target = udp::endpoint(i->endpoint().address(), m_port);
if (has_requester()) requester().m_tracker_address
= tcp::endpoint(i->endpoint().address(), m_port);
m_socket->connect(m_target);
// look for an address that has the same kind as the one
// we're listening on. To make sure the tracker get our
// correct listening address.
udp::resolver::iterator target = i;
udp::resolver::iterator end;
udp::endpoint target_address = *i;
for (; target != end && target->endpoint().address().is_v4()
!= bind_interface().is_v4(); ++target);
if (target == end)
{
assert(target_address.address().is_v4() != bind_interface().is_v4());
if (has_requester())
{
std::string tracker_address_type = target_address.address().is_v4() ? "IPv4" : "IPv6";
std::string bind_address_type = bind_interface().is_v4() ? "IPv4" : "IPv6";
requester().tracker_warning("the tracker only resolves to an "
+ tracker_address_type + " address, and your listen interface is an "
+ bind_address_type + " address. This may prevent you from incoming connections.");
}
}
else
{
target_address = *target;
}
if (has_requester()) requester().m_tracker_address = tcp::endpoint(target_address.address(), target_address.port());
m_target = target_address;
m_socket->connect(target_address);
send_udp_connect();
}
catch (std::exception& e)