From 45a7329d5cc2b25cbc264dfbb34ea0d9e9af7c63 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 29 Mar 2008 22:45:55 +0000 Subject: [PATCH] added alert for when the client's external IP is received --- docs/manual.rst | 18 ++++++++++++++++++ include/libtorrent/alert_types.hpp | 15 +++++++++++++++ include/libtorrent/aux_/session_impl.hpp | 7 +++++-- include/libtorrent/socket.hpp | 9 +++++++++ include/libtorrent/torrent.hpp | 2 +- include/libtorrent/tracker_manager.hpp | 3 ++- src/bt_peer_connection.cpp | 4 ++-- src/http_tracker_connection.cpp | 15 ++++++++++++++- src/policy.cpp | 2 +- src/session_impl.cpp | 16 ++++++++++++++++ src/torrent.cpp | 7 ++++++- src/udp_tracker_connection.cpp | 2 +- 12 files changed, 90 insertions(+), 10 deletions(-) diff --git a/docs/manual.rst b/docs/manual.rst index ca395a9b5..c0706fb69 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -3344,6 +3344,24 @@ alerts that are generated for a specific torrent are derived from:: The specific alerts, that all derives from ``alert``, are: +external_ip_alert +----------------- + +Whenever libtorrent learns about the machines external IP, this alert is +generated. The external IP address can be acquired from the tracker (if it +supports that) or from peers that supports the extension protocol. +The address can be accessed through the ``external_address`` member. +This alert is generated as severity level ``info``. + +:: + + struct external_ip_alert: alert + { + external_ip_alert(address const& ip, const std::string& msg); + address external_address; + virtual std::auto_ptr clone() const; + }; + listen_failed_alert ------------------- diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index d920c1af8..2ad9add42 100755 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -379,6 +379,21 @@ namespace libtorrent { return std::auto_ptr(new udp_error_alert(*this)); } }; + struct TORRENT_EXPORT external_ip_alert: alert + { + external_ip_alert( + address const& ip + , std::string const& msg) + : alert(alert::info, msg) + , external_address(ip) + {} + + address external_address; + + virtual std::auto_ptr clone() const + { return std::auto_ptr(new external_ip_alert(*this)); } + }; + struct TORRENT_EXPORT listen_failed_alert: alert { listen_failed_alert( diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 5fac2edc5..f0fd4fd2a 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -319,8 +319,9 @@ namespace libtorrent std::pair allocate_buffer(int size); void free_buffer(char* buf, int size); void free_disk_buffer(char* buf); - - address m_external_address; + + void set_external_address(address const& ip); + address const& external_address() const { return m_external_address; } // private: @@ -554,7 +555,9 @@ namespace libtorrent public: boost::shared_ptr m_logger; private: + #endif + address m_external_address; #ifndef TORRENT_DISABLE_EXTENSIONS typedef std::list deadline_timer; + inline std::ostream& print_address(std::ostream& os, address const& addr) + { + asio::error_code ec; + std::string a = addr.to_string(ec); + if (ec) return os; + os << a; + return os; + } + inline std::ostream& print_endpoint(std::ostream& os, tcp::endpoint const& ep) { address const& addr = ep.address(); diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 281f26032..9fc51bccf 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -310,7 +310,7 @@ namespace libtorrent virtual void tracker_response( tracker_request const& r , std::vector& e, int interval - , int complete, int incomplete); + , int complete, int incomplete, address const& external_ip); virtual void tracker_request_timed_out( tracker_request const& r); virtual void tracker_request_error(tracker_request const& r diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index 031099d7d..580e6d5eb 100755 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -126,7 +126,8 @@ namespace libtorrent , std::vector& peers , int interval , int complete - , int incomplete) = 0; + , int incomplete + , address const& external_ip) = 0; virtual void tracker_request_timed_out( tracker_request const&) = 0; virtual void tracker_request_error( diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index 90c421d3e..b103309c3 100755 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1296,13 +1296,13 @@ namespace libtorrent { address_v4::bytes_type bytes; std::copy(my_ip.begin(), my_ip.end(), bytes.begin()); - m_ses.m_external_address = address_v4(bytes); + m_ses.set_external_address(address_v4(bytes)); } else if (my_ip.size() == address_v6::bytes_type::static_size) { address_v6::bytes_type bytes; std::copy(my_ip.begin(), my_ip.end(), bytes.begin()); - m_ses.m_external_address = address_v6(bytes); + m_ses.set_external_address(address_v6(bytes)); } } } diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 0dbbb837a..ff79f31af 100755 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -59,6 +59,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/bencode.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/io.hpp" +#include "libtorrent/socket.hpp" using namespace libtorrent; using boost::bind; @@ -406,7 +407,19 @@ namespace libtorrent // look for optional scrape info int complete = -1; int incomplete = -1; + address external_ip; + entry const* ip_ent = e.find_key("external ip"); + if (ip_ent && ip_ent->type() == entry::string_t) + { + std::string const& ip = ip_ent->string(); + char const* p = &ip[0]; + if (ip.size() == address_v4::bytes_type::static_size) + external_ip = detail::read_v4_address(p); + else if (ip.size() == address_v6::bytes_type::static_size) + external_ip = detail::read_v6_address(p); + } + entry const* complete_ent = e.find_key("complete"); if (complete_ent && complete_ent->type() == entry::int_t) complete = complete_ent->integer(); @@ -416,7 +429,7 @@ namespace libtorrent incomplete = incomplete_ent->integer(); cb->tracker_response(tracker_req(), peer_list, interval->integer(), complete - , incomplete); + , incomplete, external_ip); } } diff --git a/src/policy.cpp b/src/policy.cpp index 29a1d684b..5d977dd7b 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -459,7 +459,7 @@ namespace libtorrent int min_reconnect_time = m_torrent->settings().min_reconnect_time; int min_cidr_distance = (std::numeric_limits::max)(); bool finished = m_torrent->is_finished(); - address external_ip = m_torrent->session().m_external_address; + address external_ip = m_torrent->session().external_address(); if (external_ip == address()) { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 71d9bc8a7..12bcbedc3 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -2008,6 +2008,22 @@ namespace aux { m_upnp = 0; } + void session_impl::set_external_address(address const& ip) + { + TORRENT_ASSERT(ip != address()); + + if (m_external_address == ip) return; + + m_external_address = ip; + if (m_alerts.should_post(alert::info)) + { + std::stringstream msg; + msg << "external address is '"; + print_address(msg, ip) << "'"; + m_alerts.post_alert(external_ip_alert(ip, msg.str())); + } + } + void session_impl::free_disk_buffer(char* buf) { m_disk_thread.free_buffer(buf); diff --git a/src/torrent.cpp b/src/torrent.cpp index 14c99a7f8..5365f38cd 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -803,13 +803,17 @@ namespace libtorrent , std::vector& peer_list , int interval , int complete - , int incomplete) + , int incomplete + , address const& external_ip) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); INVARIANT_CHECK; TORRENT_ASSERT(r.kind == tracker_request::announce_request); + if (external_ip != address()) + m_ses.set_external_address(external_ip); + m_failed_trackers = 0; // announce intervals less than 5 minutes // are insane. @@ -841,6 +845,7 @@ namespace libtorrent if (!i->pid.is_all_zeros()) s << " " << i->pid << " " << identify_client(i->pid); s << "\n"; } + s << "external ip: " << external_ip << "\n"; debug_log(s.str()); #endif // for each of the peers we got from the tracker diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index fecf6bac1..7347dbe4b 100755 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -394,7 +394,7 @@ namespace libtorrent } cb->tracker_response(tracker_req(), peer_list, interval - , complete, incomplete); + , complete, incomplete, address()); m_man.remove_request(this); close();