refactoring in natpmp, upnp and lsd. made lsd (probably) work on windows

This commit is contained in:
Arvid Norberg 2007-05-17 02:54:13 +00:00
parent ea45641c8b
commit 8987d7077d
4 changed files with 49 additions and 38 deletions

View File

@ -44,7 +44,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/thread/condition.hpp>
#include <set>
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
#define TORRENT_UPNP_LOGGING
#endif
#if defined(TORRENT_UPNP_LOGGING)
#include <fstream>
#endif
@ -52,6 +57,7 @@ namespace libtorrent
{
bool is_local(address const& a);
address_v4 guess_local_address(asio::io_service&);
// int: external tcp port
// int: external udp port

View File

@ -42,10 +42,17 @@ POSSIBILITY OF SUCH DAMAGE.
#include <asio/ip/multicast.hpp>
#include <boost/thread/mutex.hpp>
#include <cstdlib>
#include <boost/config.hpp>
using boost::bind;
using namespace libtorrent;
namespace libtorrent
{
// defined in upnp.cpp
address_v4 guess_local_address(asio::io_service&);
}
address_v4 lsd::lsd_multicast_address;
udp::endpoint lsd::lsd_multicast_endpoint;
@ -99,7 +106,7 @@ void lsd::rebind(address const& listen_interface)
m_socket.set_option(join_group(lsd_multicast_address));
m_socket.set_option(outbound_interface(local_ip));
m_socket.set_option(enable_loopback(false));
m_socket.set_option(enable_loopback(true));
m_socket.set_option(hops(255));
}
catch (std::exception& e)

View File

@ -44,7 +44,9 @@ enum { num_mappings = 2 };
namespace libtorrent
{
// defined in upnp.cpp
bool is_local(address const& a);
address_v4 guess_local_address(asio::io_service&);
}
natpmp::natpmp(io_service& ios, address const& listen_interface, portmap_callback_t const& cb)
@ -74,26 +76,13 @@ void natpmp::rebind(address const& listen_interface) try
}
else
{
// make a best guess of the interface we're using and its IP
udp::resolver r(m_socket.io_service());
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0"));
for (;i != udp::resolver_iterator(); ++i)
{
// ignore the loopback
if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue;
// ignore addresses that are not on a local network
if (!is_local(i->endpoint().address())) continue;
// ignore non-IPv4 addresses
if (i->endpoint().address().is_v4()) break;
}
local = guess_local_address(m_socket.io_service());
if (i == udp::resolver_iterator())
if (local == address_v4::any())
{
throw std::runtime_error("local host is probably not on a NATed "
"network. disabling NAT-PMP");
}
local = i->endpoint().address().to_v4();
}
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)

View File

@ -46,6 +46,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/thread/mutex.hpp>
#include <cstdlib>
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
#define TORRENT_UPNP_LOGGING
#endif
using boost::bind;
using namespace libtorrent;
@ -62,6 +66,24 @@ namespace libtorrent
|| (a4.to_ulong() & 0xfff00000) == 0xac100000
|| (a4.to_ulong() & 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)
{
// ignore the loopback
if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue;
// ignore addresses that are not on a local network
if (!is_local(i->endpoint().address())) continue;
// ignore non-IPv4 addresses
if (i->endpoint().address().is_v4()) break;
}
if (i == udp::resolver_iterator()) return address_v4::any();
return i->endpoint().address().to_v4();
}
}
upnp::upnp(io_service& ios, connection_queue& cc
@ -96,32 +118,26 @@ upnp::~upnp()
void upnp::rebind(address const& listen_interface) try
{
m_local_ip = address_v4::any();
if (listen_interface.is_v4() && listen_interface != address_v4::any())
{
m_local_ip = listen_interface.to_v4();
if (!is_local(m_local_ip))
{
// the local address seems to be an external
// internet address. Assume it is not behind a NAT
throw std::runtime_error("local IP is not on a local network");
}
}
else
{
// make a best guess of the interface we're using and its IP
udp::resolver r(m_socket.io_service());
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0"));
for (;i != udp::resolver_iterator(); ++i)
{
// ignore the loopback
if (i->endpoint().address() == address_v4((127 << 24) + 1)) continue;
// ignore addresses that are not on a local network
if (!is_local(i->endpoint().address())) continue;
// ignore non-IPv4 addresses
if (i->endpoint().address().is_v4()) break;
}
address_v4 local_ip = guess_local_address(m_socket.io_service());
if (i == udp::resolver_iterator())
if (local_ip == address_v4::any())
{
throw std::runtime_error("local host is probably not on a NATed "
"network. disabling UPnP");
}
m_local_ip = i->endpoint().address().to_v4();
}
#ifdef TORRENT_UPNP_LOGGING
@ -129,13 +145,6 @@ void upnp::rebind(address const& listen_interface) try
<< " local ip: " << m_local_ip.to_string() << std::endl;
#endif
if (!is_local(m_local_ip))
{
// the local address seems to be an external
// internet address. Assume it is not behind a NAT
throw std::runtime_error("local IP is not on a local network");
}
// the local interface hasn't changed
if (m_socket.is_open()
&& m_socket.local_endpoint().address() == m_local_ip)