From 13a06308750dccfa4bfb098e750011f0f6114f32 Mon Sep 17 00:00:00 2001 From: Marcos Pinto Date: Mon, 1 Oct 2007 22:56:48 +0000 Subject: [PATCH] windows fixes for lt --- .../include/libtorrent/broadcast_socket.hpp | 2 +- libtorrent/include/libtorrent/enum_net.hpp | 1 + libtorrent/src/broadcast_socket.cpp | 41 ++++++---- libtorrent/src/enum_net.cpp | 77 +++++++++++++++++++ libtorrent/src/kademlia/rpc_manager.cpp | 2 +- libtorrent/src/lsd.cpp | 4 +- libtorrent/src/natpmp.cpp | 19 +++-- libtorrent/src/upnp.cpp | 2 +- 8 files changed, 116 insertions(+), 32 deletions(-) diff --git a/libtorrent/include/libtorrent/broadcast_socket.hpp b/libtorrent/include/libtorrent/broadcast_socket.hpp index 485d1bd1f..df656f4ea 100644 --- a/libtorrent/include/libtorrent/broadcast_socket.hpp +++ b/libtorrent/include/libtorrent/broadcast_socket.hpp @@ -46,7 +46,7 @@ namespace libtorrent bool is_multicast(address const& addr); bool is_any(address const& addr); - address_v4 guess_local_address(asio::io_service&); + address guess_local_address(asio::io_service&); typedef boost::function receive_handler_t; diff --git a/libtorrent/include/libtorrent/enum_net.hpp b/libtorrent/include/libtorrent/enum_net.hpp index 0da76ff36..a794c705c 100644 --- a/libtorrent/include/libtorrent/enum_net.hpp +++ b/libtorrent/include/libtorrent/enum_net.hpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { std::vector
enum_net_interfaces(asio::io_service& ios, asio::error_code& ec); + address router_for_interface(address const interface, asio::error_code& ec); } #endif diff --git a/libtorrent/src/broadcast_socket.cpp b/libtorrent/src/broadcast_socket.cpp index 359c0e0d2..8872b59b1 100644 --- a/libtorrent/src/broadcast_socket.cpp +++ b/libtorrent/src/broadcast_socket.cpp @@ -51,23 +51,6 @@ namespace libtorrent || (ip & 0xffff0000) == 0xc0a80000); } - address_v4 guess_local_address(asio::io_service& ios) - { - // make a best guess of the interface we're using and its IP - udp::resolver r(ios); - udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0")); - for (;i != udp::resolver_iterator(); ++i) - { - address const& a = i->endpoint().address(); - // ignore non-IPv4 addresses - if (!a.is_v4()) break; - // ignore the loopback - if (a.to_v4() == address_v4::loopback()) continue; - } - if (i == udp::resolver_iterator()) return address_v4::any(); - return i->endpoint().address().to_v4(); - } - bool is_loopback(address const& addr) { if (addr.is_v4()) @@ -92,6 +75,30 @@ namespace libtorrent return addr.to_v6() == address_v6::any(); } + address guess_local_address(asio::io_service& ios) + { + // make a best guess of the interface we're using and its IP + asio::error_code ec; + std::vector
const& interfaces = enum_net_interfaces(ios, ec); + address ret = address_v4::any(); + for (std::vector
::const_iterator i = interfaces.begin() + , end(interfaces.end()); i != end; ++i) + { + address const& a = *i; + if (is_loopback(a) + || is_multicast(a) + || is_any(a)) continue; + + // prefer a v4 address, but return a v6 if + // there are no v4 + if (a.is_v4()) return a; + + if (ret != address_v4::any()) + ret = a; + } + return ret; + } + broadcast_socket::broadcast_socket(asio::io_service& ios , udp::endpoint const& multicast_endpoint , receive_handler_t const& handler diff --git a/libtorrent/src/enum_net.cpp b/libtorrent/src/enum_net.cpp index 94c74e855..585fa0f38 100644 --- a/libtorrent/src/enum_net.cpp +++ b/libtorrent/src/enum_net.cpp @@ -34,6 +34,12 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#elif defined WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include #endif #include "libtorrent/enum_net.hpp" @@ -136,6 +142,77 @@ namespace libtorrent return ret; } + address router_for_interface(address const interface, asio::error_code& ec) + { +#ifdef WIN32 + + // Load Iphlpapi library + HMODULE iphlp = LoadLibraryA("Iphlpapi.dll"); + if (!iphlp) + { + ec = asio::error::fault; + return address_v4::any(); + } + + // Get GetAdaptersInfo() pointer + typedef DWORD (WINAPI *GetAdaptersInfo_t)(PIP_ADAPTER_INFO, PULONG); + GetAdaptersInfo_t GetAdaptersInfo = (GetAdaptersInfo_t)GetProcAddress(iphlp, "GetAdaptersInfo"); + if (!GetAdaptersInfo) + { + FreeLibrary(iphlp); + ec = asio::error::fault; + return address_v4::any(); + } + + PIP_ADAPTER_INFO adapter_info = 0; + ULONG out_buf_size = 0; + if (GetAdaptersInfo(adapter_info, &out_buf_size) != ERROR_BUFFER_OVERFLOW) + { + FreeLibrary(iphlp); + ec = asio::error::fault; + return address_v4::any(); + } + + adapter_info = (IP_ADAPTER_INFO*)malloc(out_buf_size); + if (!adapter_info) + { + FreeLibrary(iphlp); + ec = asio::error::fault; + return address_v4::any(); + } + + address ret; + if (GetAdaptersInfo(adapter_info, &out_buf_size) == NO_ERROR) + { + PIP_ADAPTER_INFO adapter = adapter_info; + while (adapter != 0) + { + if (interface == address::from_string(adapter->IpAddressList.IpAddress.String, ec)) + { + ret = address::from_string(adapter->GatewayList.IpAddress.String, ec); + break; + } + adapter = adapter->Next; + } + } + + // Free memory + free(adapter_info); + FreeLibrary(iphlp); + + return ret; + +#else + // TODO: temporary implementation + if (!interface.is_v4()) + { + ec = asio::error::fault; + return address_v4::any(); + } + return address_v4((interface.to_v4().to_ulong() & 0xffffff00) | 1); +#endif + } + } diff --git a/libtorrent/src/kademlia/rpc_manager.cpp b/libtorrent/src/kademlia/rpc_manager.cpp index 93eac8565..247c79a0f 100644 --- a/libtorrent/src/kademlia/rpc_manager.cpp +++ b/libtorrent/src/kademlia/rpc_manager.cpp @@ -83,7 +83,7 @@ void intrusive_ptr_release(observer const* o) { boost::pool<>& p = o->pool_allocator; o->~observer(); - p.ordered_free(const_cast(o)); + p.free(const_cast(o)); } } diff --git a/libtorrent/src/lsd.cpp b/libtorrent/src/lsd.cpp index cab115515..44d7b19d4 100644 --- a/libtorrent/src/lsd.cpp +++ b/libtorrent/src/lsd.cpp @@ -49,8 +49,8 @@ using namespace libtorrent; namespace libtorrent { - // defined in upnp.cpp - address_v4 guess_local_address(asio::io_service&); + // defined in broadcast_socket.cpp + address guess_local_address(asio::io_service&); } lsd::lsd(io_service& ios, address const& listen_interface diff --git a/libtorrent/src/natpmp.cpp b/libtorrent/src/natpmp.cpp index 5ddbb8dd8..38ae52413 100644 --- a/libtorrent/src/natpmp.cpp +++ b/libtorrent/src/natpmp.cpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/natpmp.hpp" #include "libtorrent/io.hpp" #include "libtorrent/assert.hpp" +#include "libtorrent/enum_net.hpp" using boost::bind; using namespace libtorrent; @@ -48,7 +49,7 @@ namespace libtorrent { // defined in upnp.cpp bool is_local(address const& a); - address_v4 guess_local_address(asio::io_service&); + address guess_local_address(asio::io_service&); } natpmp::natpmp(io_service& ios, address const& listen_interface, portmap_callback_t const& cb) @@ -71,10 +72,10 @@ natpmp::natpmp(io_service& ios, address const& listen_interface, portmap_callbac void natpmp::rebind(address const& listen_interface) try { - address_v4 local = address_v4::any(); - if (listen_interface.is_v4() && listen_interface != address_v4::any()) + address local = address_v4::any(); + if (listen_interface != address_v4::any()) { - local = listen_interface.to_v4(); + local = listen_interface; } else { @@ -101,14 +102,12 @@ void natpmp::rebind(address const& listen_interface) try m_disabled = false; - // assume the router is located on the local - // network as x.x.x.1 - udp::endpoint nat_endpoint( - address_v4((local.to_ulong() & 0xffffff00) | 1), 5351); + asio::error_code ec; + udp::endpoint nat_endpoint(router_for_interface(local, ec), 5351); + if (ec) + throw std::runtime_error("cannot retrieve router address"); if (nat_endpoint == m_nat_endpoint) return; - - // TODO: find a better way to figure out the router IP m_nat_endpoint = nat_endpoint; #if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING) diff --git a/libtorrent/src/upnp.cpp b/libtorrent/src/upnp.cpp index 2f5d4a992..f1ee92636 100644 --- a/libtorrent/src/upnp.cpp +++ b/libtorrent/src/upnp.cpp @@ -56,7 +56,7 @@ using namespace libtorrent; namespace libtorrent { bool is_local(address const& a); - address_v4 guess_local_address(asio::io_service&); + address guess_local_address(asio::io_service&); } upnp::upnp(io_service& ios, connection_queue& cc