fixed nat-pmp bug

This commit is contained in:
Arvid Norberg 2008-12-02 08:20:29 +00:00
parent eacab8680e
commit 4cc15f34ad
1 changed files with 33 additions and 21 deletions

View File

@ -339,6 +339,14 @@ void natpmp::on_reply(error_code const& e
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16) m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
, m_remote, bind(&natpmp::on_reply, self(), _1, _2)); , m_remote, bind(&natpmp::on_reply, self(), _1, _2));
// simulate packet loss
/*
if ((rand() % 2) == 0)
{
log(" simulating drop");
return;
}
*/
if (m_remote != m_nat_endpoint) if (m_remote != m_nat_endpoint)
{ {
std::stringstream msg; std::stringstream msg;
@ -352,10 +360,6 @@ void natpmp::on_reply(error_code const& e
error_code ec; error_code ec;
m_send_timer.cancel(ec); m_send_timer.cancel(ec);
TORRENT_ASSERT(m_currently_mapping >= 0);
int i = m_currently_mapping;
mapping_t& m = m_mappings[i];
char* in = m_response_buffer; char* in = m_response_buffer;
int version = read_uint8(in); int version = read_uint8(in);
int cmd = read_uint8(in); int cmd = read_uint8(in);
@ -367,12 +371,13 @@ void natpmp::on_reply(error_code const& e
(void)time; // to remove warning (void)time; // to remove warning
int protocol = (cmd - 128 == 1)?udp:tcp;
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 << " ]";
log(msg.str());
if (version != 0) if (version != 0)
{ {
@ -381,30 +386,37 @@ void natpmp::on_reply(error_code const& e
log(msg.str()); log(msg.str());
} }
if (private_port != m.local_port) mapping_t* m = 0;
int index = -1;
for (std::vector<mapping_t>::iterator i = m_mappings.begin()
, end(m_mappings.end()); i != end; ++i)
{ {
std::stringstream msg; if (private_port != i->local_port) continue;
msg << "unexpected local port: " << private_port; if (protocol != i->protocol) continue;
log(msg.str()); if (!i->map_sent) continue;
m = &*i;
index = i - m_mappings.begin();
break;
} }
if (cmd != 128 + m.protocol) if (m == 0)
{ {
std::stringstream msg; msg << " not found in map table";
msg << "unexpected protocol: " << (cmd - 128);
log(msg.str()); log(msg.str());
return;
} }
log(msg.str());
if (public_port == 0 || lifetime == 0) if (public_port == 0 || lifetime == 0)
{ {
// this means the mapping was // this means the mapping was
// successfully closed // successfully closed
m.protocol = none; m->protocol = none;
} }
else else
{ {
m.expires = time_now() + seconds(int(lifetime * 0.7f)); m->expires = time_now() + seconds(int(lifetime * 0.7f));
m.external_port = public_port; m->external_port = public_port;
} }
if (result != 0) if (result != 0)
@ -419,19 +431,19 @@ void natpmp::on_reply(error_code const& e
case 4: errmsg << "Out of resources"; break; case 4: errmsg << "Out of resources"; break;
case 5: errmsg << "Unsupported opcode"; break; case 5: errmsg << "Unsupported opcode"; break;
} }
m.expires = time_now() + hours(2); m->expires = time_now() + hours(2);
m_callback(i, 0, errmsg.str()); m_callback(index, 0, errmsg.str());
} }
else if (m.action == mapping_t::action_add) else if (m->action == mapping_t::action_add)
{ {
m_callback(i, m.external_port, ""); m_callback(index, m->external_port, "");
} }
m_currently_mapping = -1; m_currently_mapping = -1;
m.action = mapping_t::action_none; m->action = mapping_t::action_none;
m_send_timer.cancel(ec); m_send_timer.cancel(ec);
update_expiration_timer(); update_expiration_timer();
try_next_mapping(i); try_next_mapping(index);
} }
void natpmp::update_expiration_timer() void natpmp::update_expiration_timer()