diff --git a/libtransmission/natpmp.cc b/libtransmission/natpmp.cc index 79400f724..31544a05f 100644 --- a/libtransmission/natpmp.cc +++ b/libtransmission/natpmp.cc @@ -27,32 +27,6 @@ static char const* getKey(void) return _("Port Forwarding (NAT-PMP)"); } -enum tr_natpmp_state -{ - TR_NATPMP_IDLE, - TR_NATPMP_ERR, - TR_NATPMP_DISCOVER, - TR_NATPMP_RECV_PUB, - TR_NATPMP_SEND_MAP, - TR_NATPMP_RECV_MAP, - TR_NATPMP_SEND_UNMAP, - TR_NATPMP_RECV_UNMAP -}; - -struct tr_natpmp -{ - bool has_discovered; - bool is_mapped; - - tr_port public_port; - tr_port private_port; - - time_t renew_time; - time_t command_time; - tr_natpmp_state state; - natpmp_t natpmp; -}; - /** *** **/ @@ -110,7 +84,12 @@ static void setCommandTime(struct tr_natpmp* nat) nat->command_time = tr_time() + CommandWaitSecs; } -tr_port_forwarding tr_natpmpPulse(struct tr_natpmp* nat, tr_port private_port, bool is_enabled, tr_port* public_port) +tr_port_forwarding tr_natpmpPulse( + struct tr_natpmp* nat, + tr_port private_port, + bool is_enabled, + tr_port* public_port, + tr_port* real_private_port) { if (is_enabled && nat->state == TR_NATPMP_DISCOVER) { @@ -227,6 +206,7 @@ tr_port_forwarding tr_natpmpPulse(struct tr_natpmp* nat, tr_port private_port, b { case TR_NATPMP_IDLE: *public_port = nat->public_port; + *real_private_port = nat->private_port; return nat->is_mapped ? TR_PORT_MAPPED : TR_PORT_UNMAPPED; case TR_NATPMP_DISCOVER: diff --git a/libtransmission/natpmp_local.h b/libtransmission/natpmp_local.h index f5230ebfe..ca7241cef 100644 --- a/libtransmission/natpmp_local.h +++ b/libtransmission/natpmp_local.h @@ -14,12 +14,38 @@ * @{ */ -struct tr_natpmp; +#include "natpmp.h" + +enum tr_natpmp_state +{ + TR_NATPMP_IDLE, + TR_NATPMP_ERR, + TR_NATPMP_DISCOVER, + TR_NATPMP_RECV_PUB, + TR_NATPMP_SEND_MAP, + TR_NATPMP_RECV_MAP, + TR_NATPMP_SEND_UNMAP, + TR_NATPMP_RECV_UNMAP +}; + +struct tr_natpmp +{ + bool has_discovered; + bool is_mapped; + + tr_port public_port; + tr_port private_port; + + time_t renew_time; + time_t command_time; + tr_natpmp_state state; + natpmp_t natpmp; +}; tr_natpmp* tr_natpmpInit(void); void tr_natpmpClose(tr_natpmp*); -tr_port_forwarding tr_natpmpPulse(tr_natpmp*, tr_port port, bool isEnabled, tr_port* public_port); +tr_port_forwarding tr_natpmpPulse(tr_natpmp*, tr_port port, bool isEnabled, tr_port* public_port, tr_port* real_private_port); /* @} */ diff --git a/libtransmission/port-forwarding.cc b/libtransmission/port-forwarding.cc index a95e566f7..89f7b5e1e 100644 --- a/libtransmission/port-forwarding.cc +++ b/libtransmission/port-forwarding.cc @@ -68,6 +68,7 @@ static char const* getNatStateStr(int state) static void natPulse(tr_shared* s, bool do_check) { + tr_port received_private_port; tr_port const private_peer_port = s->session->private_peer_port; bool const is_enabled = s->isEnabled && !s->isShuttingDown; @@ -84,11 +85,17 @@ static void natPulse(tr_shared* s, bool do_check) auto const old_status = tr_sharedTraversalStatus(s); auto public_peer_port = tr_port{}; - s->natpmpStatus = tr_natpmpPulse(s->natpmp, private_peer_port, is_enabled, &public_peer_port); + s->natpmpStatus = tr_natpmpPulse(s->natpmp, private_peer_port, is_enabled, &public_peer_port, &received_private_port); if (s->natpmpStatus == TR_PORT_MAPPED) { s->session->public_peer_port = public_peer_port; + s->session->private_peer_port = received_private_port; + tr_logAddNamedInfo( + getKey(), + "public peer port %d (private %d) ", + s->session->public_peer_port, + s->session->private_peer_port); } s->upnpStatus = tr_upnpPulse( @@ -119,10 +126,10 @@ static void set_evtimer_from_status(tr_shared* s) switch (tr_sharedTraversalStatus(s)) { case TR_PORT_MAPPED: - /* if we're mapped, everything is fine... check back in 20 minutes + /* if we're mapped, everything is fine... check back at renew_time * to renew the port forwarding if it's expired */ s->doPortCheck = true; - sec = 60 * 20; + sec = int(s->natpmp->renew_time - tr_time()); break; case TR_PORT_ERROR: diff --git a/libtransmission/session.cc b/libtransmission/session.cc index b99ff47a4..6bce027fc 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -1240,7 +1240,7 @@ void tr_sessionSetPeerPort(tr_session* session, tr_port port) tr_port tr_sessionGetPeerPort(tr_session const* session) { - return tr_isSession(session) ? session->private_peer_port : 0; + return tr_isSession(session) ? session->public_peer_port : 0; } tr_port tr_sessionSetPeerPortRandom(tr_session* session)