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 stop_dht();
|
||||
entry dht_state() const;
|
||||
void maybe_update_udp_mapping(int nat, int local_port, int external_port);
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
||||
int add_mapping(protocol_type p, int external_port, int local_port);
|
||||
void delete_mapping(int mapping_index);
|
||||
bool get_mapping(int mapping_index, int& local_port, int& external_port, int& protocol) const;
|
||||
|
||||
void close();
|
||||
|
||||
|
@ -88,6 +89,7 @@ private:
|
|||
, local_port(0)
|
||||
, external_port(0)
|
||||
, protocol(none)
|
||||
, map_sent(false)
|
||||
{}
|
||||
|
||||
// indicates that the mapping has changed
|
||||
|
@ -107,6 +109,9 @@ private:
|
|||
int external_port;
|
||||
|
||||
int protocol;
|
||||
|
||||
// set to true when the first map request is sent
|
||||
bool map_sent;
|
||||
};
|
||||
|
||||
portmap_callback_t m_callback;
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
enum protocol_type { none = 0, udp = 1, tcp = 2 };
|
||||
int add_mapping(protocol_type p, int external_port, int local_port);
|
||||
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 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)
|
||||
{
|
||||
m_callback(-1, 0, msg);
|
||||
|
@ -132,6 +144,7 @@ void natpmp::disable(char const* message)
|
|||
}
|
||||
close();
|
||||
}
|
||||
|
||||
void natpmp::delete_mapping(int index)
|
||||
{
|
||||
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];
|
||||
|
||||
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;
|
||||
update_mapping(index);
|
||||
|
@ -270,7 +289,7 @@ void natpmp::send_map_request(int i)
|
|||
write_uint32(ttl, out); // port mapping lifetime
|
||||
|
||||
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")
|
||||
<< " local: " << m.local_port << " external: " << m.external_port
|
||||
<< " ttl: " << ttl << " ]";
|
||||
|
@ -278,6 +297,7 @@ void natpmp::send_map_request(int i)
|
|||
|
||||
error_code ec;
|
||||
m_socket.send_to(asio::buffer(buf, 12), m_nat_endpoint, 0, ec);
|
||||
m.map_sent = true;
|
||||
// linear back-off instead of exponential
|
||||
++m_retry_count;
|
||||
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
|
||||
|
||||
std::stringstream msg;
|
||||
msg << "port map ["
|
||||
msg << "<== port map ["
|
||||
<< " protocol: " << (cmd - 128 == 1 ? "udp" : "tcp")
|
||||
<< " local: " << private_port << " external: " << public_port
|
||||
<< " ttl: " << lifetime << " ]";
|
||||
|
@ -486,7 +506,7 @@ void natpmp::close()
|
|||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_abort = true;
|
||||
error_code ec;
|
||||
log("closing");
|
||||
/*
|
||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||
m_log << time_now_string() << " close" << std::endl;
|
||||
|
@ -511,6 +531,7 @@ void natpmp::close()
|
|||
if (i->protocol == none) continue;
|
||||
i->action = mapping_t::action_delete;
|
||||
}
|
||||
error_code ec;
|
||||
m_refresh_timer.cancel(ec);
|
||||
update_mapping(0);
|
||||
}
|
||||
|
|
|
@ -1990,20 +1990,9 @@ namespace aux {
|
|||
m_dht_settings.service_port = new_interface.port();
|
||||
// the listen interface changed, rebind the dht listen socket as well
|
||||
m_dht_socket.bind(m_dht_settings.service_port);
|
||||
if (m_natpmp.get())
|
||||
{
|
||||
if (m_udp_mapping[0] != -1) m_natpmp->delete_mapping(m_udp_mapping[0]);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2194,18 +2183,8 @@ namespace aux {
|
|||
m_dht_settings.service_port = 45000 + (rand() % 10000);
|
||||
}
|
||||
m_external_udp_port = m_dht_settings.service_port;
|
||||
if (m_natpmp.get() && m_udp_mapping[0] == -1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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_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)
|
||||
{
|
||||
|
@ -2222,6 +2201,45 @@ namespace aux {
|
|||
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()
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -2246,20 +2264,8 @@ namespace aux {
|
|||
{
|
||||
m_dht_socket.bind(settings.service_port);
|
||||
|
||||
if (m_natpmp.get())
|
||||
{
|
||||
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);
|
||||
}
|
||||
maybe_update_udp_mapping(0, settings.service_port, settings.service_port);
|
||||
maybe_update_udp_mapping(1, settings.service_port, settings.service_port);
|
||||
m_external_udp_port = settings.service_port;
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (e) return;
|
||||
|
|
Loading…
Reference in New Issue