From 42f55adccebf3fed0231509b773ce5bdf052fac6 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 11 Apr 2008 08:46:43 +0000 Subject: [PATCH] support for country lookup through GeoIP --- docs/manual.html | 14 +++++----- docs/manual.rst | 13 +++++---- examples/client_test.cpp | 1 + include/libtorrent/aux_/session_impl.hpp | 9 +++++-- include/libtorrent/session.hpp | 1 + src/peer_connection.cpp | 22 +++++++++++++++ src/session.cpp | 5 ++++ src/session_impl.cpp | 34 +++++++++++++++++------- 8 files changed, 77 insertions(+), 22 deletions(-) diff --git a/docs/manual.html b/docs/manual.html index 6dde7a9be..c8d5939e4 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -37,7 +37,7 @@
  • set_max_uploads() set_max_connections()
  • num_uploads() num_connections()
  • set_max_half_open_connections() max_half_open_connections()
  • -
  • load_asnum_db()
  • +
  • load_asnum_db() load_country_db()
  • load_state() state()
  • set_ip_filter()
  • status()
  • @@ -333,6 +333,7 @@ class session: public boost::noncopyable int num_connections() const; bool load_asnum_db(char const* file); + bool load_country_db(char const* file); void load_state(entry const& ses_state); entry state() const; @@ -597,16 +598,17 @@ their turn to get connected.

    max_half_open_connections() returns the set limit. This limit defaults to 8 on windows.

    -
    -

    load_asnum_db()

    +
    +

    load_asnum_db() load_country_db()

     bool load_asnum_db(char const* file);
    +bool load_country_db(char const* file);
     
    -

    This function is not available if TORRENT_DISABLE_GEO_IP is defined. This -expects a path to the MaxMind ASN database. This will be used to look up -which AS peers belong to.

    +

    These functions are not available if TORRENT_DISABLE_GEO_IP is defined. They +expects a path to the MaxMind ASN database and MaxMind GeoIP database +respectively. This will be used to look up which AS and country peers belong to.

    load_state() state()

    diff --git a/docs/manual.rst b/docs/manual.rst index 889ae7944..d21b22fed 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -133,6 +133,7 @@ The ``session`` class has the following synopsis:: int num_connections() const; bool load_asnum_db(char const* file); + bool load_country_db(char const* file); void load_state(entry const& ses_state); entry state() const; @@ -420,18 +421,20 @@ their turn to get connected. ``max_half_open_connections()`` returns the set limit. This limit defaults to 8 on windows. -load_asnum_db() ---------------- +load_asnum_db() load_country_db() +--------------------------------- :: bool load_asnum_db(char const* file); + bool load_country_db(char const* file); -This function is not available if ``TORRENT_DISABLE_GEO_IP`` is defined. This -expects a path to the `MaxMind ASN database`_. This will be used to look up -which AS peers belong to. +These functions are not available if ``TORRENT_DISABLE_GEO_IP`` is defined. They +expects a path to the `MaxMind ASN database`_ and `MaxMind GeoIP database`_ +respectively. This will be used to look up which AS and country peers belong to. .. _`MaxMind ASN database`: http://www.maxmind.com/app/asnum +.. _`MaxMind GeoIP database`: http://www.maxmind.com/app/geolitecountry load_state() state() -------------------- diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 5960645e8..89d9fda75 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -810,6 +810,7 @@ int main(int ac, char* av[]) session ses; #ifndef TORRENT_DISABLE_GEO_IP ses.load_asnum_db("GeoIPASNum.dat"); + ses.load_country_db("GeoIP.dat"); #endif // UPnP port mapping ses.start_upnp(); diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 3664e0e3a..dd7f882c4 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -295,7 +295,11 @@ namespace libtorrent int as_for_ip(address const& a); std::pair* lookup_as(int as); bool load_asnum_db(char const* file); - bool has_asnum_db() const { return m_geoip_db; } + bool has_asnum_db() const { return m_asnum_db; } + + bool load_country_db(char const* file); + bool has_country_db() const { return m_country_db; } + char const* country_for_ip(address const& a); #endif void load_state(entry const& ses_state); @@ -591,7 +595,8 @@ namespace libtorrent #endif #ifndef TORRENT_DISABLE_GEO_IP - GeoIP* m_geoip_db; + GeoIP* m_asnum_db; + GeoIP* m_country_db; // maps AS number to the peak download rate // we've seen from it. Entries are never removed diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 280c32a2b..63dae16e7 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -204,6 +204,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_GEO_IP bool load_asnum_db(char const* file); + bool load_country_db(char const* file); #endif void load_state(entry const& ses_state); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 44d8b91fe..9ed399cef 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -133,6 +133,17 @@ namespace libtorrent TORRENT_ASSERT(peerinfo == 0 || peerinfo->banned == false); #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES std::fill(m_country, m_country + 2, 0); +#ifndef TORRENT_DISABLE_GEO_IP + if (m_ses.has_country_db()) + { + char const *country = m_ses.country_for_ip(m_remote.address()); + if (country != 0) + { + m_country[0] = country[0]; + m_country[1] = country[1]; + } + } +#endif #endif #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING m_logger = m_ses.create_log(m_remote.address().to_string() + "_" @@ -218,6 +229,17 @@ namespace libtorrent #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES std::fill(m_country, m_country + 2, 0); +#ifndef TORRENT_DISABLE_GEO_IP + if (m_ses.has_country_db()) + { + char const *country = m_ses.country_for_ip(m_remote.address()); + if (country != 0) + { + m_country[0] = country[0]; + m_country[1] = country[1]; + } + } +#endif #endif #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING diff --git a/src/session.cpp b/src/session.cpp index c17a6602d..538ae47d5 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -180,6 +180,11 @@ namespace libtorrent { return m_impl->load_asnum_db(file); } + + bool session::load_country_db(char const* file) + { + return m_impl->load_country_db(file); + } #endif void session::load_state(entry const& ses_state) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index a12d906ef..f3f95b7c0 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -174,7 +174,8 @@ namespace aux { , m_logpath(logpath) #endif #ifndef TORRENT_DISABLE_GEO_IP - , m_geoip_db(0) + , m_asnum_db(0) + , m_country_db(0) #endif { m_tcp_mapping[0] = -1; @@ -265,10 +266,16 @@ namespace aux { }; } + char const* session_impl::country_for_ip(address const& a) + { + if (!a.is_v4() || m_country_db == 0) return 0; + return GeoIP_country_code_by_ipnum(m_country_db, a.to_v4().to_ulong()); + } + int session_impl::as_for_ip(address const& a) { - if (!a.is_v4() || m_geoip_db == 0) return 0; - char* name = GeoIP_name_by_ipnum(m_geoip_db, a.to_v4().to_ulong()); + if (!a.is_v4() || m_asnum_db == 0) return 0; + char* name = GeoIP_name_by_ipnum(m_asnum_db, a.to_v4().to_ulong()); if (name == 0) return 0; free_ptr p(name); // GeoIP returns the name as AS??? where ? is the AS-number @@ -277,8 +284,8 @@ namespace aux { std::string session_impl::as_name_for_ip(address const& a) { - if (!a.is_v4() || m_geoip_db == 0) return std::string(); - char* name = GeoIP_name_by_ipnum(m_geoip_db, a.to_v4().to_ulong()); + if (!a.is_v4() || m_asnum_db == 0) return std::string(); + char* name = GeoIP_name_by_ipnum(m_asnum_db, a.to_v4().to_ulong()); if (name == 0) return std::string(); free_ptr p(name); char* tmp = std::strchr(name, ' '); @@ -301,9 +308,17 @@ namespace aux { bool session_impl::load_asnum_db(char const* file) { mutex_t::scoped_lock l(m_mutex); - if (m_geoip_db) GeoIP_delete(m_geoip_db); - m_geoip_db = GeoIP_open(file, GEOIP_STANDARD); - return m_geoip_db; + if (m_asnum_db) GeoIP_delete(m_asnum_db); + m_asnum_db = GeoIP_open(file, GEOIP_STANDARD); + return m_asnum_db; + } + + bool session_impl::load_country_db(char const* file) + { + mutex_t::scoped_lock l(m_mutex); + if (m_country_db) GeoIP_delete(m_country_db); + m_country_db = GeoIP_open(file, GEOIP_STANDARD); + return m_country_db; } #endif @@ -1985,7 +2000,8 @@ namespace aux { abort(); #ifndef TORRENT_DISABLE_GEO_IP - if (m_geoip_db) GeoIP_delete(m_geoip_db); + if (m_asnum_db) GeoIP_delete(m_asnum_db); + if (m_country_db) GeoIP_delete(m_country_db); #endif #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " waiting for main thread\n";