| Index: webrtc/p2p/base/stunport.cc
|
| diff --git a/webrtc/p2p/base/stunport.cc b/webrtc/p2p/base/stunport.cc
|
| index 8f37dd5218bb745b5e06ab6d8b2574faefc9aa44..e871a6c0cc6c042f544f0f6543d52726db464e00 100644
|
| --- a/webrtc/p2p/base/stunport.cc
|
| +++ b/webrtc/p2p/base/stunport.cc
|
| @@ -24,21 +24,23 @@ namespace cricket {
|
|
|
| // TODO: Move these to a common place (used in relayport too)
|
| const int KEEPALIVE_DELAY = 10 * 1000; // 10 seconds - sort timeouts
|
| -const int RETRY_TIMEOUT = 50 * 1000; // ICE says 50 secs
|
| -// Stop sending STUN binding requests after this amount of time
|
| -// (in milliseconds) because the connection binding requests should keep
|
| -// the NAT binding alive.
|
| -const int KEEP_ALIVE_TIMEOUT = 2 * 60 * 1000; // 2 minutes
|
| +const int RETRY_TIMEOUT = 50 * 1000; // 50 seconds
|
| +// Lifetime chosen for STUN ports on low-cost networks.
|
| +const int INFINITE_LIFETIME = -1;
|
| +// Lifetime for STUN ports on high-cost networks: 2 minutes
|
| +const int HIGH_COST_PORT_KEEPALIVE_LIFETIME = 2 * 60 * 1000;
|
|
|
| // Handles a binding request sent to the STUN server.
|
| class StunBindingRequest : public StunRequest {
|
| public:
|
| StunBindingRequest(UDPPort* port,
|
| const rtc::SocketAddress& addr,
|
| - uint32_t deadline)
|
| - : port_(port), server_addr_(addr), deadline_(deadline) {
|
| - start_time_ = rtc::Time();
|
| - }
|
| + uint32_t start_time,
|
| + int lifetime)
|
| + : port_(port),
|
| + server_addr_(addr),
|
| + start_time_(start_time),
|
| + lifetime_(lifetime) {}
|
|
|
| virtual ~StunBindingRequest() {
|
| }
|
| @@ -62,11 +64,10 @@ class StunBindingRequest : public StunRequest {
|
| port_->OnStunBindingRequestSucceeded(server_addr_, addr);
|
| }
|
|
|
| - // We will do a keep-alive regardless of whether this request succeeds.
|
| - // It will be stopped after |deadline_| mostly to conserve the battery life.
|
| - if (rtc::Time() <= deadline_) {
|
| + // The keep-alive requests will be stopped after its lifetime has passed.
|
| + if (WithinLifetime(rtc::Time())) {
|
| port_->requests_.SendDelayed(
|
| - new StunBindingRequest(port_, server_addr_, deadline_),
|
| + new StunBindingRequest(port_, server_addr_, start_time_, lifetime_),
|
| port_->stun_keepalive_delay());
|
| }
|
| }
|
| @@ -77,34 +78,41 @@ class StunBindingRequest : public StunRequest {
|
| LOG(LS_ERROR) << "Bad allocate response error code";
|
| } else {
|
| LOG(LS_ERROR) << "Binding error response:"
|
| - << " class=" << attr->eclass()
|
| - << " number=" << attr->number()
|
| - << " reason='" << attr->reason() << "'";
|
| + << " class=" << attr->eclass()
|
| + << " number=" << attr->number() << " reason='"
|
| + << attr->reason() << "'";
|
| }
|
|
|
| port_->OnStunBindingOrResolveRequestFailed(server_addr_);
|
|
|
| uint32_t now = rtc::Time();
|
| - if (now <= deadline_ && rtc::TimeDiff(now, start_time_) <= RETRY_TIMEOUT) {
|
| + if (WithinLifetime(now) &&
|
| + rtc::TimeDiff(now, start_time_) < RETRY_TIMEOUT) {
|
| port_->requests_.SendDelayed(
|
| - new StunBindingRequest(port_, server_addr_, deadline_),
|
| + new StunBindingRequest(port_, server_addr_, start_time_, lifetime_),
|
| port_->stun_keepalive_delay());
|
| }
|
| }
|
| -
|
| virtual void OnTimeout() override {
|
| LOG(LS_ERROR) << "Binding request timed out from "
|
| - << port_->GetLocalAddress().ToSensitiveString()
|
| - << " (" << port_->Network()->name() << ")";
|
| + << port_->GetLocalAddress().ToSensitiveString() << " ("
|
| + << port_->Network()->name() << ")";
|
|
|
| port_->OnStunBindingOrResolveRequestFailed(server_addr_);
|
| }
|
|
|
| private:
|
| + // Returns true if |now| is within the lifetime of the request (a negative
|
| + // lifetime means infinite).
|
| + bool WithinLifetime(uint32_t now) const {
|
| + return lifetime_ < 0 || rtc::TimeDiff(now, start_time_) <= lifetime_;
|
| + }
|
| UDPPort* port_;
|
| const rtc::SocketAddress server_addr_;
|
| +
|
| uint32_t start_time_;
|
| - uint32_t deadline_;
|
| + // The time duration for which this request will be rescheduled.
|
| + int lifetime_;
|
| };
|
|
|
| UDPPort::AddressResolver::AddressResolver(
|
| @@ -212,6 +220,12 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
| }
|
|
|
| bool UDPPort::Init() {
|
| + // If this is a zero-cost network, it will keep on sending STUN binding
|
| + // requests indefinitely to keep the NAT binding alive. Otherwise, stop
|
| + // sending STUN binding requests after HIGH_COST_PORT_KEEPALIVE_LIFETIME.
|
| + stun_keepalive_lifetime_ = (network_cost() == 0)
|
| + ? INFINITE_LIFETIME
|
| + : HIGH_COST_PORT_KEEPALIVE_LIFETIME;
|
| if (!SharedSocket()) {
|
| ASSERT(socket_ == NULL);
|
| socket_ = socket_factory()->CreateUdpSocket(
|
| @@ -397,8 +411,8 @@ void UDPPort::SendStunBindingRequest(const rtc::SocketAddress& stun_addr) {
|
| } else if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
|
| // Check if |server_addr_| is compatible with the port's ip.
|
| if (IsCompatibleAddress(stun_addr)) {
|
| - requests_.Send(new StunBindingRequest(this, stun_addr,
|
| - rtc::Time() + KEEP_ALIVE_TIMEOUT));
|
| + requests_.Send(new StunBindingRequest(this, stun_addr, rtc::Time(),
|
| + stun_keepalive_lifetime_));
|
| } else {
|
| // Since we can't send stun messages to the server, we should mark this
|
| // port ready.
|
|
|