diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp index 47016f808..3689a8187 100644 --- a/libtorrent/include/libtorrent/aux_/session_impl.hpp +++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp @@ -509,6 +509,10 @@ namespace libtorrent // port we'll bind the next outgoing socket to int m_next_port; + // the sequence number to assign to the + // next torrent that's added + int m_torrent_sequence; + #ifndef TORRENT_DISABLE_DHT boost::intrusive_ptr m_dht; dht_settings m_dht_settings; @@ -522,10 +526,6 @@ namespace libtorrent // but for the udp port used by the DHT. int m_external_udp_port; - // the sequence number to assign to the - // next torrent that's added - int m_torrent_sequence; - udp_socket m_dht_socket; void on_receive_udp(asio::error_code const& e diff --git a/libtorrent/include/libtorrent/enum_net.hpp b/libtorrent/include/libtorrent/enum_net.hpp index 5a0d4b92a..577a7e308 100644 --- a/libtorrent/include/libtorrent/enum_net.hpp +++ b/libtorrent/include/libtorrent/enum_net.hpp @@ -43,6 +43,15 @@ namespace libtorrent { address interface_address; address netmask; + char name[32]; + }; + + struct ip_route + { + address destination; + address netmask; + address gateway; + char name[32]; }; // returns a list of the configured IP interfaces @@ -50,6 +59,8 @@ namespace libtorrent TORRENT_EXPORT std::vector enum_net_interfaces(asio::io_service& ios , asio::error_code& ec); + TORRENT_EXPORT std::vector enum_routes(asio::io_service& ios, asio::error_code& ec); + // returns true if the specified address is on the same // local network as the specified interface TORRENT_EXPORT bool in_subnet(address const& addr, ip_interface const& iface); @@ -59,7 +70,7 @@ namespace libtorrent TORRENT_EXPORT bool in_local_network(asio::io_service& ios, address const& addr , asio::error_code& ec); - TORRENT_EXPORT address get_default_gateway(asio::io_service& ios, address const& addr + TORRENT_EXPORT address get_default_gateway(asio::io_service& ios , asio::error_code& ec); } diff --git a/libtorrent/include/libtorrent/policy.hpp b/libtorrent/include/libtorrent/policy.hpp index e5e76f9ab..de0119de0 100755 --- a/libtorrent/include/libtorrent/policy.hpp +++ b/libtorrent/include/libtorrent/policy.hpp @@ -267,10 +267,6 @@ namespace libtorrent bool compare_peer(policy::peer const& lhs, policy::peer const& rhs , address const& external_ip) const; - // since the peer list can grow too large - // to scan all of it, start at this iterator - iterator m_round_robin; - iterator find_disconnect_candidate(); iterator find_connect_candidate(); @@ -278,6 +274,10 @@ namespace libtorrent std::multimap m_peers; + // since the peer list can grow too large + // to scan all of it, start at this iterator + iterator m_round_robin; + torrent* m_torrent; // free download we have got that hasn't diff --git a/libtorrent/include/libtorrent/time.hpp b/libtorrent/include/libtorrent/time.hpp index a03d728bf..27e6e2561 100644 --- a/libtorrent/include/libtorrent/time.hpp +++ b/libtorrent/include/libtorrent/time.hpp @@ -256,7 +256,7 @@ namespace libtorrent #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include +#include #include "libtorrent/assert.hpp" namespace libtorrent diff --git a/libtorrent/include/libtorrent/version.hpp b/libtorrent/include/libtorrent/version.hpp index de1b8bcc8..06b1bbe13 100755 --- a/libtorrent/include/libtorrent/version.hpp +++ b/libtorrent/include/libtorrent/version.hpp @@ -34,8 +34,8 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_VERSION_HPP_INCLUDED #define LIBTORRENT_VERSION_MAJOR 0 -#define LIBTORRENT_VERSION_MINOR 13 +#define LIBTORRENT_VERSION_MINOR 14 -#define LIBTORRENT_VERSION "0.13.0.0" +#define LIBTORRENT_VERSION "0.14.0.0" #endif diff --git a/libtorrent/src/enum_net.cpp b/libtorrent/src/enum_net.cpp index ff3c108c3..4fad81cdd 100644 --- a/libtorrent/src/enum_net.cpp +++ b/libtorrent/src/enum_net.cpp @@ -31,14 +31,24 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "libtorrent/config.hpp" - -#if defined TORRENT_BSD || defined TORRENT_LINUX +#include +#include +#include "libtorrent/enum_net.hpp" +#include "libtorrent/broadcast_socket.hpp" +#include + + +#if defined TORRENT_BSD #include #include #include #include #include -#elif defined TORRENT_WINDOWS +#include +#include +#endif + +#if defined TORRENT_WINDOWS #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -46,44 +56,161 @@ POSSIBILITY OF SUCH DAMAGE. #include #endif -#include "libtorrent/enum_net.hpp" -#include "libtorrent/broadcast_socket.hpp" -#include +#if defined TORRENT_LINUX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace libtorrent { namespace +{ + + address inaddr_to_address(in_addr const* ina) + { + typedef asio::ip::address_v4::bytes_type bytes_t; + bytes_t b; + memcpy(&b[0], ina, b.size()); + return address_v4(b); + } + + address inaddr6_to_address(in6_addr const* ina6) + { + typedef asio::ip::address_v6::bytes_type bytes_t; + bytes_t b; + memcpy(&b[0], ina6, b.size()); + return address_v6(b); + } + + address sockaddr_to_address(sockaddr const* sin) + { + if (sin->sa_family == AF_INET) + return inaddr_to_address(&((sockaddr_in const*)sin)->sin_addr); + else if (sin->sa_family == AF_INET6) + return inaddr6_to_address(&((sockaddr_in6 const*)sin)->sin6_addr); + return address(); + } + +#if defined TORRENT_LINUX + + int read_nl_sock(int sock, char *buf, int bufsize, int seq, int pid) + { + nlmsghdr* nl_hdr; + + int msg_len = 0; + + do + { + int read_len = recv(sock, buf, bufsize - msg_len, 0); + if (read_len < 0) return -1; + + nl_hdr = (nlmsghdr*)buf; + + if ((NLMSG_OK(nl_hdr, read_len) == 0) || (nl_hdr->nlmsg_type == NLMSG_ERROR)) + return -1; + + if (nl_hdr->nlmsg_type == NLMSG_DONE) break; + + buf += read_len; + msg_len += read_len; + + if ((nl_hdr->nlmsg_flags & NLM_F_MULTI) == 0) break; + + } while((nl_hdr->nlmsg_seq != seq) || (nl_hdr->nlmsg_pid != pid)); + return msg_len; + } + + bool parse_route(nlmsghdr* nl_hdr, ip_route* rt_info) + { + rtmsg* rt_msg = (rtmsg*)NLMSG_DATA(nl_hdr); + + if((rt_msg->rtm_family != AF_INET) || (rt_msg->rtm_table != RT_TABLE_MAIN)) + return false; + + int rt_len = RTM_PAYLOAD(nl_hdr); + for (rtattr* rt_attr = (rtattr*)RTM_RTA(rt_msg); + RTA_OK(rt_attr,rt_len); rt_attr = RTA_NEXT(rt_attr,rt_len)) + { + switch(rt_attr->rta_type) + { + case RTA_OIF: + if_indextoname(*(int*)RTA_DATA(rt_attr), rt_info->name); + break; + case RTA_GATEWAY: + rt_info->gateway = address_v4(*(u_int*)RTA_DATA(rt_attr)); + break; + case RTA_DST: + rt_info->destination = address_v4(*(u_int*)RTA_DATA(rt_attr)); + break; + } + } + return true; + } +#endif + +#if defined TORRENT_BSD + + bool parse_route(rt_msghdr* rtm, ip_route* rt_info) + { + sockaddr* rti_info[RTAX_MAX]; + sockaddr* sa = (sockaddr*)(rtm + 1); + for (int i = 0; i < RTAX_MAX; ++i) + { + if ((rtm->rtm_addrs & (1 << i)) == 0) + { + rti_info[i] = 0; + continue; + } + rti_info[i] = sa; + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) + + sa = (sockaddr*)((char*)(sa) + ROUNDUP(sa->sa_len)); + +#undef ROUNDUP + } + + sa = rti_info[RTAX_GATEWAY]; + if (sa == 0 + || rti_info[RTAX_DST] == 0 + || rti_info[RTAX_NETMASK] == 0 + || (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)) + return false; + + rt_info->gateway = sockaddr_to_address(rti_info[RTAX_GATEWAY]); + rt_info->netmask = sockaddr_to_address(rti_info[RTAX_NETMASK]); + rt_info->destination = sockaddr_to_address(rti_info[RTAX_DST]); + if_indextoname(rtm->rtm_index, rt_info->name); + return true; + } +#endif + + +#ifdef TORRENT_BSD + bool verify_sockaddr(sockaddr_in* sin) + { + return (sin->sin_len == sizeof(sockaddr_in) + && sin->sin_family == AF_INET) + || (sin->sin_len == sizeof(sockaddr_in6) + && sin->sin_family == AF_INET6); + } +#endif + +}} // namespace libtorrent { - namespace - { - address sockaddr_to_address(sockaddr const* sin) - { - if (sin->sa_family == AF_INET) - { - typedef asio::ip::address_v4::bytes_type bytes_t; - bytes_t b; - memcpy(&b[0], &((sockaddr_in const*)sin)->sin_addr, b.size()); - return address_v4(b); - } - else if (sin->sa_family == AF_INET6) - { - typedef asio::ip::address_v6::bytes_type bytes_t; - bytes_t b; - memcpy(&b[0], &((sockaddr_in6 const*)sin)->sin6_addr, b.size()); - return address_v6(b); - } - return address(); - } - -#ifdef TORRENT_BSD - bool verify_sockaddr(sockaddr_in* sin) - { - return (sin->sin_len == sizeof(sockaddr_in) - && sin->sin_family == AF_INET) - || (sin->sin_len == sizeof(sockaddr_in6) - && sin->sin_family == AF_INET6); - } -#endif - - } bool in_subnet(address const& addr, ip_interface const& iface) { @@ -144,6 +271,7 @@ namespace libtorrent { ip_interface iface; iface.interface_address = sockaddr_to_address(&item.ifr_addr); + strcpy(iface.name, item.ifr_name); ifreq netmask = item; if (ioctl(s, SIOCGIFNETMASK, &netmask) < 0) @@ -205,6 +333,7 @@ namespace libtorrent { iface.interface_address = sockaddr_to_address(&buffer[i].iiAddress.Address); iface.netmask = sockaddr_to_address(&buffer[i].iiNetmask.Address); + iface.name[0] = 0; if (iface.interface_address == address_v4::any()) continue; ret.push_back(iface); } @@ -227,11 +356,21 @@ namespace libtorrent return ret; } - address get_default_gateway(asio::io_service& ios, address const& interface, asio::error_code& ec) + address get_default_gateway(asio::io_service& ios, asio::error_code& ec) { + std::vector ret = enum_routes(ios, ec); + std::vector::iterator i = std::find_if(ret.begin(), ret.end() + , boost::bind(&ip_route::destination, _1) == address()); + if (i == ret.end()) return address(); + return i->gateway; + } + + std::vector enum_routes(asio::io_service& ios, asio::error_code& ec) + { + std::vector ret; #if defined TORRENT_BSD - +/* struct rt_msg { rt_msghdr m_rtm; @@ -244,15 +383,15 @@ namespace libtorrent m.m_rtm.rtm_type = RTM_GET; m.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY; m.m_rtm.rtm_version = RTM_VERSION; - m.m_rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; + m.m_rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; m.m_rtm.rtm_seq = 0; m.m_rtm.rtm_msglen = len; - int s = socket(PF_ROUTE, SOCK_RAW, AF_INET); + int s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); if (s == -1) { ec = asio::error_code(errno, asio::error::system_category); - return address_v4::any(); + return std::vector(); } int n = write(s, &m, len); @@ -260,13 +399,13 @@ namespace libtorrent { ec = asio::error_code(errno, asio::error::system_category); close(s); - return address_v4::any(); + return std::vector(); } else if (n != len) { ec = asio::error::operation_not_supported; close(s); - return address_v4::any(); + return std::vector(); } bzero(&m, len); @@ -275,61 +414,102 @@ namespace libtorrent { ec = asio::error_code(errno, asio::error::system_category); close(s); - return address_v4::any(); + return std::vector(); + } + + for (rt_msghdr* ptr = &m.m_rtm; (char*)ptr < ((char*)&m.m_rtm) + n; ptr = (rt_msghdr*)(((char*)ptr) + ptr->rtm_msglen)) + { + std::cout << " rtm_msglen: " << ptr->rtm_msglen << std::endl; + std::cout << " rtm_type: " << ptr->rtm_type << std::endl; + if (ptr->rtm_errno) + { + ec = asio::error_code(ptr->rtm_errno, asio::error::system_category); + return std::vector(); + } + if (m.m_rtm.rtm_flags & RTF_UP == 0 + || m.m_rtm.rtm_flags & RTF_GATEWAY == 0) + { + ec = asio::error::operation_not_supported; + return address_v4::any(); + } + if (ptr->rtm_addrs & RTA_DST == 0 + || ptr->rtm_addrs & RTA_GATEWAY == 0 + || ptr->rtm_addrs & RTA_NETMASK == 0) + { + ec = asio::error::operation_not_supported; + return std::vector(); + } + if (ptr->rtm_msglen > len - ((char*)ptr - ((char*)&m.m_rtm))) + { + ec = asio::error::operation_not_supported; + return std::vector(); + } + int min_len = sizeof(rt_msghdr) + 2 * sizeof(sockaddr_in); + if (m.m_rtm.rtm_msglen < min_len) + { + ec = asio::error::operation_not_supported; + return std::vector(); + } + + ip_route r; + // destination + char* p = m.buf; + sockaddr_in* sin = (sockaddr_in*)p; + r.destination = sockaddr_to_address((sockaddr*)p); + + // gateway + p += sin->sin_len; + sin = (sockaddr_in*)p; + r.gateway = sockaddr_to_address((sockaddr*)p); + + // netmask + p += sin->sin_len; + sin = (sockaddr_in*)p; + r.netmask = sockaddr_to_address((sockaddr*)p); + ret.push_back(r); } close(s); +*/ + int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_UNSPEC, NET_RT_DUMP, 0}; - TORRENT_ASSERT(m.m_rtm.rtm_seq == 0); - TORRENT_ASSERT(m.m_rtm.rtm_pid == getpid()); - if (m.m_rtm.rtm_errno) - { - ec = asio::error_code(m.m_rtm.rtm_errno, asio::error::system_category); - return address_v4::any(); - } - if (m.m_rtm.rtm_flags & RTF_UP == 0 - || m.m_rtm.rtm_flags & RTF_GATEWAY == 0) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } - if (m.m_rtm.rtm_addrs & RTA_DST == 0 - || m.m_rtm.rtm_addrs & RTA_GATEWAY == 0) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } - if (m.m_rtm.rtm_msglen > len) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } - int min_len = sizeof(rt_msghdr) + 2 * sizeof(struct sockaddr_in); - if (m.m_rtm.rtm_msglen < min_len) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } + size_t needed = 0; + if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) + { + ec = asio::error_code(errno, asio::error::system_category); + return std::vector(); + } - // default route - char* p = m.buf; - sockaddr_in* sin = (sockaddr_in*)p; - if (!verify_sockaddr(sin)) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } + if (needed <= 0) + { + return std::vector(); + } - // default gateway - p += sin->sin_len; - sin = (sockaddr_in*)p; - if (!verify_sockaddr(sin)) - { - ec = asio::error::operation_not_supported; - return address_v4::any(); - } + boost::scoped_array buf(new (std::nothrow) char[needed]); + if (buf.get() == 0) + { + ec = asio::error::no_memory; + return std::vector(); + } - return sockaddr_to_address((sockaddr*)sin); + if (sysctl(mib, 6, buf.get(), &needed, 0, 0) < 0) + { + ec = asio::error_code(errno, asio::error::system_category); + return std::vector(); + } + char* end = buf.get() + needed; + + rt_msghdr* rtm; + for (char* next = buf.get(); next < end; next += rtm->rtm_msglen) + { + rtm = (rt_msghdr*)next; + if (rtm->rtm_version != RTM_VERSION) + continue; + + ip_route r; + if (parse_route(rtm, &r)) ret.push_back(r); + } + #elif defined TORRENT_WINDOWS // Load Iphlpapi library @@ -337,7 +517,7 @@ namespace libtorrent if (!iphlp) { ec = asio::error::operation_not_supported; - return address_v4::any(); + return std::vector(); } // Get GetAdaptersInfo() pointer @@ -347,7 +527,7 @@ namespace libtorrent { FreeLibrary(iphlp); ec = asio::error::operation_not_supported; - return address_v4::any(); + return std::vector(); } PIP_ADAPTER_INFO adapter_info = 0; @@ -356,7 +536,7 @@ namespace libtorrent { FreeLibrary(iphlp); ec = asio::error::operation_not_supported; - return address_v4::any(); + return std::vector(); } adapter_info = (IP_ADAPTER_INFO*)malloc(out_buf_size); @@ -364,7 +544,7 @@ namespace libtorrent { FreeLibrary(iphlp); ec = asio::error::no_memory; - return address_v4::any(); + return std::vector(); } address ret; @@ -373,18 +553,19 @@ namespace libtorrent for (PIP_ADAPTER_INFO adapter = adapter_info; adapter != 0; adapter = adapter->Next) { - address iface = address::from_string(adapter->IpAddressList.IpAddress.String, ec); + + ip_route r; + r.source = address::from_string(adapter->IpAddressList.IpAddress.String, ec); + r.gateway = address::from_string(adapter->GatewayList.IpAddress.String, ec); + r.netmask = address::from_string(adapter->IpAddressList.IpMask.String, ec); + strcpy(r.name, adapter->AdapterName); + if (ec) { ec = asio::error_code(); continue; } - if (is_loopback(iface) || is_any(iface)) continue; - if (interface == address() || interface == iface) - { - ret = address::from_string(adapter->GatewayList.IpAddress.String, ec); - break; - } + ret.push_back(r); } } @@ -394,16 +575,53 @@ namespace libtorrent return ret; -//#elif defined TORRENT_LINUX -// No linux implementation yet -#else - if (!interface.is_v4()) +#elif defined TORRENT_LINUX + + enum { BUFSIZE = 8192 }; + + int sock = socket(PF_ROUTE, SOCK_DGRAM, NETLINK_ROUTE); + if (sock < 0) { - ec = asio::error::operation_not_supported; - return address_v4::any(); + ec = asio::error_code(errno, asio::error::system_category); + return std::vector(); } - return address_v4((interface.to_v4().to_ulong() & 0xffffff00) | 1); + + int seq = 0; + + char msg[BUFSIZE]; + memset(msg, 0, BUFSIZE); + nlmsghdr* nl_msg = (nlmsghdr*)msg; + + nl_msg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg)); + nl_msg->nlmsg_type = RTM_GETROUTE; + nl_msg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; + nl_msg->nlmsg_seq = seq++; + nl_msg->nlmsg_pid = getpid(); + + if (send(sock, nl_msg, nl_msg->nlmsg_len, 0) < 0) + { + ec = asio::error_code(errno, asio::error::system_category); + close(sock); + return std::vector(); + } + + int len = read_nl_sock(sock, msg, BUFSIZE, seq, getpid()); + if (len < 0) + { + ec = asio::error_code(errno, asio::error::system_category); + close(sock); + return std::vector(); + } + + for (; NLMSG_OK(nl_msg, len); nl_msg = NLMSG_NEXT(nl_msg, len)) + { + ip_route r; + if (parse_route(nl_msg, &r)) ret.push_back(r); + } + close(sock); + #endif + return ret; } } diff --git a/libtorrent/src/natpmp.cpp b/libtorrent/src/natpmp.cpp index dea34516e..234ceb6c7 100644 --- a/libtorrent/src/natpmp.cpp +++ b/libtorrent/src/natpmp.cpp @@ -64,7 +64,7 @@ void natpmp::rebind(address const& listen_interface) mutex_t::scoped_lock l(m_mutex); asio::error_code ec; - address gateway = get_default_gateway(m_socket.get_io_service(), listen_interface, ec); + address gateway = get_default_gateway(m_socket.get_io_service(), ec); if (ec) { #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index c2f49b3a3..51aba79d9 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -1415,6 +1415,7 @@ namespace libtorrent return; } disk_buffer_holder holder(m_ses, buffer); + std::memcpy(buffer, data, p.length); incoming_piece(p, holder); } diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index 61428521c..7c74a845f 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -344,7 +344,8 @@ namespace libtorrent } policy::policy(torrent* t) - : m_torrent(t) + : m_round_robin(m_peers.end()) + , m_torrent(t) , m_available_free_upload(0) , m_num_connect_candidates(0) { TORRENT_ASSERT(t); } @@ -484,8 +485,7 @@ namespace libtorrent external_ip = address_v4(bytes); } - if (m_round_robin == iterator() || m_round_robin == m_peers.end()) - m_round_robin = m_peers.begin(); + if (m_round_robin == m_peers.end()) m_round_robin = m_peers.begin(); for (int iterations = (std::min)(int(m_peers.size()), 300); iterations > 0; ++m_round_robin, --iterations) @@ -1330,26 +1330,24 @@ namespace libtorrent , address const& external_ip) const { // prefer peers with lower failcount - if (lhs.failcount < rhs.failcount) return true; - if (lhs.failcount > rhs.failcount) return false; + if (lhs.failcount != rhs.failcount) + return lhs.failcount < rhs.failcount; // Local peers should always be tried first bool lhs_local = is_local(lhs.ip.address()); bool rhs_local = is_local(rhs.ip.address()); - if (lhs_local && !rhs_local) return true; - if (!lhs_local && rhs_local) return false; + if (lhs_local != rhs_local) return lhs_local > rhs_local; - if (lhs.connected < rhs.connected) return true; - if (lhs.connected > rhs.connected) return false; + if (lhs.connected != rhs.connected) + return lhs.connected < rhs.connected; #ifndef TORRENT_DISABLE_GEO_IP // don't bias fast peers when seeding if (!m_torrent->is_finished() && m_torrent->session().has_asnum_db()) { - std::pair* lhs_as = lhs.inet_as; - std::pair* rhs_as = rhs.inet_as; - if (lhs_as ? lhs_as->second : 0 > rhs_as ? rhs_as->second : 0) return true; - if (lhs_as ? lhs_as->second : 0 < rhs_as ? rhs_as->second : 0) return false; + int lhs_as = lhs.inet_as ? lhs.inet_as->second : 0; + int rhs_as = rhs.inet_as ? rhs.inet_as->second : 0; + if (lhs_as != rhs_as) return lhs_as > rhs_as; } #endif int lhs_distance = cidr_distance(external_ip, lhs.ip.address()); diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp index ae07a940a..0a68547ea 100755 --- a/libtorrent/src/session_impl.cpp +++ b/libtorrent/src/session_impl.cpp @@ -164,10 +164,10 @@ namespace aux { , m_disconnect_time_scaler(90) , m_incoming_connection(false) , m_last_tick(time_now()) + , m_torrent_sequence(0) #ifndef TORRENT_DISABLE_DHT , m_dht_same_port(true) , m_external_udp_port(0) - , m_torrent_sequence(0) , m_dht_socket(m_io_service, bind(&session_impl::on_receive_udp, this, _1, _2, _3, _4) , m_half_open) #endif