forked from premiere/premiere-libtorrent
added a failcounter to upnp portmaps
This commit is contained in:
parent
28b90cb702
commit
e5d1456c58
|
@ -108,6 +108,7 @@ private:
|
||||||
void map_port(rootdevice& d, int i);
|
void map_port(rootdevice& d, int i);
|
||||||
void unmap_port(rootdevice& d, int i);
|
void unmap_port(rootdevice& d, int i);
|
||||||
void disable();
|
void disable();
|
||||||
|
void return_error(int code);
|
||||||
|
|
||||||
void delete_port_mapping(rootdevice& d, int i);
|
void delete_port_mapping(rootdevice& d, int i);
|
||||||
void create_port_mapping(http_connection& c, rootdevice& d, int i);
|
void create_port_mapping(http_connection& c, rootdevice& d, int i);
|
||||||
|
@ -121,6 +122,7 @@ private:
|
||||||
, local_port(0)
|
, local_port(0)
|
||||||
, external_port(0)
|
, external_port(0)
|
||||||
, protocol(1)
|
, protocol(1)
|
||||||
|
, failcount(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// the time the port mapping will expire
|
// the time the port mapping will expire
|
||||||
|
@ -139,6 +141,9 @@ private:
|
||||||
|
|
||||||
// 1 = udp, 0 = tcp
|
// 1 = udp, 0 = tcp
|
||||||
int protocol;
|
int protocol;
|
||||||
|
|
||||||
|
// the number of times this mapping has failed
|
||||||
|
int failcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rootdevice
|
struct rootdevice
|
||||||
|
|
62
src/upnp.cpp
62
src/upnp.cpp
|
@ -471,6 +471,13 @@ void upnp::map_port(rootdevice& d, int i)
|
||||||
TORRENT_ASSERT(d.magic == 1337);
|
TORRENT_ASSERT(d.magic == 1337);
|
||||||
if (d.upnp_connection) return;
|
if (d.upnp_connection) return;
|
||||||
|
|
||||||
|
if (d.mapping[i].failcount > 5)
|
||||||
|
{
|
||||||
|
// giving up
|
||||||
|
if (i < num_mappings - 1)
|
||||||
|
map_port(d, i + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!d.mapping[i].need_update)
|
if (!d.mapping[i].need_update)
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_UPNP_LOGGING
|
#ifdef TORRENT_UPNP_LOGGING
|
||||||
|
@ -825,32 +832,37 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
||||||
// only permanent leases supported
|
// only permanent leases supported
|
||||||
d.lease_duration = 0;
|
d.lease_duration = 0;
|
||||||
d.mapping[mapping].need_update = true;
|
d.mapping[mapping].need_update = true;
|
||||||
|
++d.mapping[mapping].failcount;
|
||||||
map_port(d, mapping);
|
map_port(d, mapping);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (s.error_code == 718)
|
else if (s.error_code == 718 || s.error_code == 727)
|
||||||
{
|
{
|
||||||
// conflict in mapping, try next external port
|
if (d.mapping[mapping].external_port != 0)
|
||||||
++d.mapping[mapping].external_port;
|
{
|
||||||
|
// conflict in mapping, set port to wildcard
|
||||||
|
// and let the router decide
|
||||||
|
d.mapping[mapping].external_port = 0;
|
||||||
|
d.mapping[mapping].need_update = true;
|
||||||
|
++d.mapping[mapping].failcount;
|
||||||
|
map_port(d, mapping);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return_error(s.error_code);
|
||||||
|
}
|
||||||
|
else if (s.error_code == 716)
|
||||||
|
{
|
||||||
|
// The external port cannot be wildcarder
|
||||||
|
// pick a random port
|
||||||
|
d.mapping[mapping].external_port = 40000 + (rand() % 10000);
|
||||||
d.mapping[mapping].need_update = true;
|
d.mapping[mapping].need_update = true;
|
||||||
|
++d.mapping[mapping].failcount;
|
||||||
map_port(d, mapping);
|
map_port(d, mapping);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (s.error_code != -1)
|
else if (s.error_code != -1)
|
||||||
{
|
{
|
||||||
int num_errors = sizeof(error_codes) / sizeof(error_codes[0]);
|
return_error(s.error_code);
|
||||||
error_code_t* end = error_codes + num_errors;
|
|
||||||
error_code_t tmp = {s.error_code, 0};
|
|
||||||
error_code_t* e = std::lower_bound(error_codes, end, tmp
|
|
||||||
, bind(&error_code_t::code, _1) < bind(&error_code_t::code, _2));
|
|
||||||
std::string error_string = "UPnP mapping error ";
|
|
||||||
error_string += boost::lexical_cast<std::string>(s.error_code);
|
|
||||||
if (e != end && e->code == s.error_code)
|
|
||||||
{
|
|
||||||
error_string += ": ";
|
|
||||||
error_string += e->msg;
|
|
||||||
}
|
|
||||||
m_callback(0, 0, error_string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_UPNP_LOGGING
|
#ifdef TORRENT_UPNP_LOGGING
|
||||||
|
@ -887,6 +899,7 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
||||||
{
|
{
|
||||||
d.mapping[mapping].expires = max_time();
|
d.mapping[mapping].expires = max_time();
|
||||||
}
|
}
|
||||||
|
d.mapping[mapping].failcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_mappings; ++i)
|
for (int i = 0; i < num_mappings; ++i)
|
||||||
|
@ -899,6 +912,23 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void upnp::return_error(int code)
|
||||||
|
{
|
||||||
|
int num_errors = sizeof(error_codes) / sizeof(error_codes[0]);
|
||||||
|
error_code_t* end = error_codes + num_errors;
|
||||||
|
error_code_t tmp = {code, 0};
|
||||||
|
error_code_t* e = std::lower_bound(error_codes, end, tmp
|
||||||
|
, bind(&error_code_t::code, _1) < bind(&error_code_t::code, _2));
|
||||||
|
std::string error_string = "UPnP mapping error ";
|
||||||
|
error_string += boost::lexical_cast<std::string>(code);
|
||||||
|
if (e != end && e->code == code)
|
||||||
|
{
|
||||||
|
error_string += ": ";
|
||||||
|
error_string += e->msg;
|
||||||
|
}
|
||||||
|
m_callback(0, 0, error_string);
|
||||||
|
}
|
||||||
|
|
||||||
void upnp::on_upnp_unmap_response(asio::error_code const& e
|
void upnp::on_upnp_unmap_response(asio::error_code const& e
|
||||||
, libtorrent::http_parser const& p, rootdevice& d, int mapping)
|
, libtorrent::http_parser const& p, rootdevice& d, int mapping)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue