improved natpmp logging and handling of mapped ports in session
This commit is contained in:
parent
e9a33e6a05
commit
a48ffe36e0
|
@ -176,6 +176,7 @@ namespace libtorrent
|
||||||
void start_dht(entry const& startup_state);
|
void start_dht(entry const& startup_state);
|
||||||
void stop_dht();
|
void stop_dht();
|
||||||
entry dht_state() const;
|
entry dht_state() const;
|
||||||
|
void maybe_update_udp_mapping(int nat, int local_port, int external_port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
||||||
int add_mapping(protocol_type p, int external_port, int local_port);
|
int add_mapping(protocol_type p, int external_port, int local_port);
|
||||||
void delete_mapping(int mapping_index);
|
void delete_mapping(int mapping_index);
|
||||||
|
bool get_mapping(int mapping_index, int& local_port, int& external_port, int& protocol) const;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
@ -88,6 +89,7 @@ private:
|
||||||
, local_port(0)
|
, local_port(0)
|
||||||
, external_port(0)
|
, external_port(0)
|
||||||
, protocol(none)
|
, protocol(none)
|
||||||
|
, map_sent(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// indicates that the mapping has changed
|
// indicates that the mapping has changed
|
||||||
|
@ -107,6 +109,9 @@ private:
|
||||||
int external_port;
|
int external_port;
|
||||||
|
|
||||||
int protocol;
|
int protocol;
|
||||||
|
|
||||||
|
// set to true when the first map request is sent
|
||||||
|
bool map_sent;
|
||||||
};
|
};
|
||||||
|
|
||||||
portmap_callback_t m_callback;
|
portmap_callback_t m_callback;
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
||||||
int add_mapping(protocol_type p, int external_port, int local_port);
|
int add_mapping(protocol_type p, int external_port, int local_port);
|
||||||
void delete_mapping(int mapping_index);
|
void delete_mapping(int mapping_index);
|
||||||
|
bool get_mapping(int mapping_index, int& local_port, int& external_port, int& protocol) const;
|
||||||
|
|
||||||
void discover_device();
|
void discover_device();
|
||||||
void close();
|
void close();
|
||||||
|
|
|
@ -114,6 +114,18 @@ void natpmp::rebind(address const& listen_interface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool natpmp::get_mapping(int index, int& local_port, int& external_port, int& protocol) const
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(index < int(m_mappings.size()) && index >= 0);
|
||||||
|
if (index >= int(m_mappings.size()) || index < 0) return false;
|
||||||
|
mapping_t const& m = m_mappings[index];
|
||||||
|
if (m.protocol == none) return false;
|
||||||
|
local_port = m.local_port;
|
||||||
|
external_port = m.external_port;
|
||||||
|
protocol = m.protocol;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void natpmp::log(std::string const& msg)
|
void natpmp::log(std::string const& msg)
|
||||||
{
|
{
|
||||||
m_callback(-1, 0, msg);
|
m_callback(-1, 0, msg);
|
||||||
|
@ -132,6 +144,7 @@ void natpmp::disable(char const* message)
|
||||||
}
|
}
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void natpmp::delete_mapping(int index)
|
void natpmp::delete_mapping(int index)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(index < int(m_mappings.size()) && index >= 0);
|
TORRENT_ASSERT(index < int(m_mappings.size()) && index >= 0);
|
||||||
|
@ -139,6 +152,12 @@ void natpmp::delete_mapping(int index)
|
||||||
mapping_t& m = m_mappings[index];
|
mapping_t& m = m_mappings[index];
|
||||||
|
|
||||||
if (m.protocol == none) return;
|
if (m.protocol == none) return;
|
||||||
|
if (!m.map_sent)
|
||||||
|
{
|
||||||
|
m.action = mapping_t::action_none;
|
||||||
|
m.protocol = none;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m.action = mapping_t::action_delete;
|
m.action = mapping_t::action_delete;
|
||||||
update_mapping(index);
|
update_mapping(index);
|
||||||
|
@ -270,7 +289,7 @@ void natpmp::send_map_request(int i)
|
||||||
write_uint32(ttl, out); // port mapping lifetime
|
write_uint32(ttl, out); // port mapping lifetime
|
||||||
|
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "port map [ action: " << (m.action == mapping_t::action_add ? "add" : "delete")
|
msg << "==> port map [ action: " << (m.action == mapping_t::action_add ? "add" : "delete")
|
||||||
<< " proto: " << (m.protocol == udp ? "udp" : "tcp")
|
<< " proto: " << (m.protocol == udp ? "udp" : "tcp")
|
||||||
<< " local: " << m.local_port << " external: " << m.external_port
|
<< " local: " << m.local_port << " external: " << m.external_port
|
||||||
<< " ttl: " << ttl << " ]";
|
<< " ttl: " << ttl << " ]";
|
||||||
|
@ -278,6 +297,7 @@ void natpmp::send_map_request(int i)
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
m_socket.send_to(asio::buffer(buf, 12), m_nat_endpoint, 0, ec);
|
m_socket.send_to(asio::buffer(buf, 12), m_nat_endpoint, 0, ec);
|
||||||
|
m.map_sent = true;
|
||||||
// linear back-off instead of exponential
|
// linear back-off instead of exponential
|
||||||
++m_retry_count;
|
++m_retry_count;
|
||||||
m_send_timer.expires_from_now(milliseconds(250 * m_retry_count), ec);
|
m_send_timer.expires_from_now(milliseconds(250 * m_retry_count), ec);
|
||||||
|
@ -348,7 +368,7 @@ void natpmp::on_reply(error_code const& e
|
||||||
(void)time; // to remove warning
|
(void)time; // to remove warning
|
||||||
|
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "port map ["
|
msg << "<== port map ["
|
||||||
<< " protocol: " << (cmd - 128 == 1 ? "udp" : "tcp")
|
<< " protocol: " << (cmd - 128 == 1 ? "udp" : "tcp")
|
||||||
<< " local: " << private_port << " external: " << public_port
|
<< " local: " << private_port << " external: " << public_port
|
||||||
<< " ttl: " << lifetime << " ]";
|
<< " ttl: " << lifetime << " ]";
|
||||||
|
@ -486,7 +506,7 @@ void natpmp::close()
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
m_abort = true;
|
m_abort = true;
|
||||||
error_code ec;
|
log("closing");
|
||||||
/*
|
/*
|
||||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
m_log << time_now_string() << " close" << std::endl;
|
m_log << time_now_string() << " close" << std::endl;
|
||||||
|
@ -511,6 +531,7 @@ void natpmp::close()
|
||||||
if (i->protocol == none) continue;
|
if (i->protocol == none) continue;
|
||||||
i->action = mapping_t::action_delete;
|
i->action = mapping_t::action_delete;
|
||||||
}
|
}
|
||||||
|
error_code ec;
|
||||||
m_refresh_timer.cancel(ec);
|
m_refresh_timer.cancel(ec);
|
||||||
update_mapping(0);
|
update_mapping(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1990,20 +1990,9 @@ namespace aux {
|
||||||
m_dht_settings.service_port = new_interface.port();
|
m_dht_settings.service_port = new_interface.port();
|
||||||
// the listen interface changed, rebind the dht listen socket as well
|
// the listen interface changed, rebind the dht listen socket as well
|
||||||
m_dht_socket.bind(m_dht_settings.service_port);
|
m_dht_socket.bind(m_dht_settings.service_port);
|
||||||
if (m_natpmp.get())
|
|
||||||
{
|
maybe_update_udp_mapping(0, m_dht_settings.service_port, m_dht_settings.service_port);
|
||||||
if (m_udp_mapping[0] != -1) m_natpmp->delete_mapping(m_udp_mapping[0]);
|
maybe_update_udp_mapping(1, m_dht_settings.service_port, m_dht_settings.service_port);
|
||||||
m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::tcp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
if (m_upnp.get())
|
|
||||||
{
|
|
||||||
if (m_udp_mapping[1] != -1) m_upnp->delete_mapping(m_udp_mapping[1]);
|
|
||||||
m_udp_mapping[1] = m_upnp->add_mapping(upnp::tcp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2194,18 +2183,8 @@ namespace aux {
|
||||||
m_dht_settings.service_port = 45000 + (rand() % 10000);
|
m_dht_settings.service_port = 45000 + (rand() % 10000);
|
||||||
}
|
}
|
||||||
m_external_udp_port = m_dht_settings.service_port;
|
m_external_udp_port = m_dht_settings.service_port;
|
||||||
if (m_natpmp.get() && m_udp_mapping[0] == -1)
|
maybe_update_udp_mapping(0, m_dht_settings.service_port, m_dht_settings.service_port);
|
||||||
{
|
maybe_update_udp_mapping(1, m_dht_settings.service_port, m_dht_settings.service_port);
|
||||||
m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
if (m_upnp.get() && m_udp_mapping[1] == -1)
|
|
||||||
{
|
|
||||||
m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
m_dht = new dht::dht_tracker(*this, m_dht_socket, m_dht_settings, &startup_state);
|
m_dht = new dht::dht_tracker(*this, m_dht_socket, m_dht_settings, &startup_state);
|
||||||
if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port)
|
if (!m_dht_socket.is_open() || m_dht_socket.local_port() != m_dht_settings.service_port)
|
||||||
{
|
{
|
||||||
|
@ -2222,6 +2201,45 @@ namespace aux {
|
||||||
m_dht->start(startup_state);
|
m_dht->start(startup_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
void session_impl::maybe_update_udp_mapping(int nat, int local_port, int external_port)
|
||||||
|
{
|
||||||
|
int local, external, protocol;
|
||||||
|
if (nat == 0 && m_natpmp.get())
|
||||||
|
{
|
||||||
|
if (m_udp_mapping[nat] != -1)
|
||||||
|
{
|
||||||
|
if (m_natpmp->get_mapping(m_udp_mapping[nat], local, external, protocol))
|
||||||
|
{
|
||||||
|
// we already have a mapping. If it's the same, don't do anything
|
||||||
|
if (local == local_port && external == external_port && protocol == natpmp::udp)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_natpmp->delete_mapping(m_udp_mapping[nat]);
|
||||||
|
}
|
||||||
|
m_udp_mapping[nat] = m_natpmp->add_mapping(natpmp::udp
|
||||||
|
, local_port, external_port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (nat == 1 && m_upnp.get())
|
||||||
|
{
|
||||||
|
if (m_udp_mapping[nat] != -1)
|
||||||
|
{
|
||||||
|
if (m_upnp->get_mapping(m_udp_mapping[nat], local, external, protocol))
|
||||||
|
{
|
||||||
|
// we already have a mapping. If it's the same, don't do anything
|
||||||
|
if (local == local_port && external == external_port && protocol == natpmp::udp)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_upnp->delete_mapping(m_udp_mapping[nat]);
|
||||||
|
}
|
||||||
|
m_udp_mapping[nat] = m_upnp->add_mapping(upnp::udp
|
||||||
|
, local_port, external_port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void session_impl::stop_dht()
|
void session_impl::stop_dht()
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
@ -2246,20 +2264,8 @@ namespace aux {
|
||||||
{
|
{
|
||||||
m_dht_socket.bind(settings.service_port);
|
m_dht_socket.bind(settings.service_port);
|
||||||
|
|
||||||
if (m_natpmp.get())
|
maybe_update_udp_mapping(0, settings.service_port, settings.service_port);
|
||||||
{
|
maybe_update_udp_mapping(1, settings.service_port, settings.service_port);
|
||||||
if (m_udp_mapping[0] != -1) m_upnp->delete_mapping(m_udp_mapping[0]);
|
|
||||||
m_udp_mapping[0] = m_natpmp->add_mapping(natpmp::udp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
if (m_upnp.get())
|
|
||||||
{
|
|
||||||
if (m_udp_mapping[1] != -1) m_upnp->delete_mapping(m_udp_mapping[1]);
|
|
||||||
m_udp_mapping[1] = m_upnp->add_mapping(upnp::udp
|
|
||||||
, m_dht_settings.service_port
|
|
||||||
, m_dht_settings.service_port);
|
|
||||||
}
|
|
||||||
m_external_udp_port = settings.service_port;
|
m_external_udp_port = settings.service_port;
|
||||||
}
|
}
|
||||||
m_dht_settings = settings;
|
m_dht_settings = settings;
|
||||||
|
|
12
src/upnp.cpp
12
src/upnp.cpp
|
@ -228,6 +228,18 @@ void upnp::delete_mapping(int mapping)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool upnp::get_mapping(int index, int& local_port, int& external_port, int& protocol) const
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(index < int(m_mappings.size()) && index >= 0);
|
||||||
|
if (index >= int(m_mappings.size()) || index < 0) return false;
|
||||||
|
global_mapping_t const& m = m_mappings[index];
|
||||||
|
if (m.protocol == none) return false;
|
||||||
|
local_port = m.local_port;
|
||||||
|
external_port = m.external_port;
|
||||||
|
protocol = m.protocol;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void upnp::resend_request(error_code const& e)
|
void upnp::resend_request(error_code const& e)
|
||||||
{
|
{
|
||||||
if (e) return;
|
if (e) return;
|
||||||
|
|
Loading…
Reference in New Issue