added router_for_interface along with a proper windows implementation. NAT-PMP support is now good on windows
This commit is contained in:
parent
6fd42631c0
commit
973e7be386
|
@ -18,7 +18,12 @@ int main()
|
||||||
if (is_multicast(*i)) std::cout << "multicast ";
|
if (is_multicast(*i)) std::cout << "multicast ";
|
||||||
if (is_local(*i)) std::cout << "local ";
|
if (is_local(*i)) std::cout << "local ";
|
||||||
if (is_loopback(*i)) std::cout << "loopback ";
|
if (is_loopback(*i)) std::cout << "loopback ";
|
||||||
|
std::cout << "router: " << router_for_interface(*i, ec);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address local = guess_local_address(ios);
|
||||||
|
|
||||||
|
std::cout << "Local address: " << local << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace libtorrent
|
||||||
bool is_multicast(address const& addr);
|
bool is_multicast(address const& addr);
|
||||||
bool is_any(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<void(udp::endpoint const& from
|
typedef boost::function<void(udp::endpoint const& from
|
||||||
, char* buffer, int size)> receive_handler_t;
|
, char* buffer, int size)> receive_handler_t;
|
||||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
std::vector<address> enum_net_interfaces(asio::io_service& ios, asio::error_code& ec);
|
std::vector<address> enum_net_interfaces(asio::io_service& ios, asio::error_code& ec);
|
||||||
|
address router_for_interface(address const interface, asio::error_code& ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,23 +51,6 @@ namespace libtorrent
|
||||||
|| (ip & 0xffff0000) == 0xc0a80000);
|
|| (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)
|
bool is_loopback(address const& addr)
|
||||||
{
|
{
|
||||||
if (addr.is_v4())
|
if (addr.is_v4())
|
||||||
|
@ -92,6 +75,30 @@ namespace libtorrent
|
||||||
return addr.to_v6() == address_v6::any();
|
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<address> const& interfaces = enum_net_interfaces(ios, ec);
|
||||||
|
address ret = address_v4::any();
|
||||||
|
for (std::vector<address>::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
|
broadcast_socket::broadcast_socket(asio::io_service& ios
|
||||||
, udp::endpoint const& multicast_endpoint
|
, udp::endpoint const& multicast_endpoint
|
||||||
, receive_handler_t const& handler
|
, receive_handler_t const& handler
|
||||||
|
|
|
@ -34,6 +34,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#elif defined WIN32
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/enum_net.hpp"
|
#include "libtorrent/enum_net.hpp"
|
||||||
|
@ -136,6 +142,77 @@ namespace libtorrent
|
||||||
return ret;
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ using namespace libtorrent;
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
// defined in upnp.cpp
|
// defined in broadcast_socket.cpp
|
||||||
address_v4 guess_local_address(asio::io_service&);
|
address guess_local_address(asio::io_service&);
|
||||||
}
|
}
|
||||||
|
|
||||||
lsd::lsd(io_service& ios, address const& listen_interface
|
lsd::lsd(io_service& ios, address const& listen_interface
|
||||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/natpmp.hpp"
|
#include "libtorrent/natpmp.hpp"
|
||||||
#include "libtorrent/io.hpp"
|
#include "libtorrent/io.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
#include "libtorrent/enum_net.hpp"
|
||||||
|
|
||||||
using boost::bind;
|
using boost::bind;
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
@ -48,7 +49,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
// defined in upnp.cpp
|
// defined in upnp.cpp
|
||||||
bool is_local(address const& a);
|
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)
|
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
|
void natpmp::rebind(address const& listen_interface) try
|
||||||
{
|
{
|
||||||
address_v4 local = address_v4::any();
|
address local = address_v4::any();
|
||||||
if (listen_interface.is_v4() && listen_interface != address_v4::any())
|
if (listen_interface != address_v4::any())
|
||||||
{
|
{
|
||||||
local = listen_interface.to_v4();
|
local = listen_interface;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -101,14 +102,12 @@ void natpmp::rebind(address const& listen_interface) try
|
||||||
|
|
||||||
m_disabled = false;
|
m_disabled = false;
|
||||||
|
|
||||||
// assume the router is located on the local
|
asio::error_code ec;
|
||||||
// network as x.x.x.1
|
udp::endpoint nat_endpoint(router_for_interface(local, ec), 5351);
|
||||||
udp::endpoint nat_endpoint(
|
if (ec)
|
||||||
address_v4((local.to_ulong() & 0xffffff00) | 1), 5351);
|
throw std::runtime_error("cannot retrieve router address");
|
||||||
|
|
||||||
if (nat_endpoint == m_nat_endpoint) return;
|
if (nat_endpoint == m_nat_endpoint) return;
|
||||||
|
|
||||||
// TODO: find a better way to figure out the router IP
|
|
||||||
m_nat_endpoint = nat_endpoint;
|
m_nat_endpoint = nat_endpoint;
|
||||||
|
|
||||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
|
|
|
@ -56,7 +56,7 @@ using namespace libtorrent;
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
bool is_local(address const& a);
|
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
|
upnp::upnp(io_service& ios, connection_queue& cc
|
||||||
|
|
Loading…
Reference in New Issue