Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/p2p/base/stunport.h"
     12 
     13 #include "webrtc/p2p/base/common.h"
     14 #include "webrtc/p2p/base/portallocator.h"
     15 #include "webrtc/p2p/base/stun.h"
     16 #include "webrtc/base/checks.h"
     17 #include "webrtc/base/common.h"
     18 #include "webrtc/base/helpers.h"
     19 #include "webrtc/base/ipaddress.h"
     20 #include "webrtc/base/logging.h"
     21 #include "webrtc/base/nethelpers.h"
     22 
     23 namespace cricket {
     24 
     25 // TODO: Move these to a common place (used in relayport too)
     26 const int KEEPALIVE_DELAY = 10 * 1000;  // 10 seconds - sort timeouts
     27 const int RETRY_TIMEOUT = 50 * 1000;    // ICE says 50 secs
     28 // Stop sending STUN binding requests after this amount of time
     29 // (in milliseconds) because the connection binding requests should keep
     30 // the NAT binding alive.
     31 const int KEEP_ALIVE_TIMEOUT = 2 * 60 * 1000;  // 2 minutes
     32 
     33 // Handles a binding request sent to the STUN server.
     34 class StunBindingRequest : public StunRequest {
     35  public:
     36   StunBindingRequest(UDPPort* port,
     37                      const rtc::SocketAddress& addr,
     38                      uint32_t deadline)
     39       : port_(port), server_addr_(addr), deadline_(deadline) {
     40     start_time_ = rtc::Time();
     41   }
     42 
     43   virtual ~StunBindingRequest() {
     44   }
     45 
     46   const rtc::SocketAddress& server_addr() const { return server_addr_; }
     47 
     48   virtual void Prepare(StunMessage* request) override {
     49     request->SetType(STUN_BINDING_REQUEST);
     50   }
     51 
     52   virtual void OnResponse(StunMessage* response) override {
     53     const StunAddressAttribute* addr_attr =
     54         response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
     55     if (!addr_attr) {
     56       LOG(LS_ERROR) << "Binding response missing mapped address.";
     57     } else if (addr_attr->family() != STUN_ADDRESS_IPV4 &&
     58                addr_attr->family() != STUN_ADDRESS_IPV6) {
     59       LOG(LS_ERROR) << "Binding address has bad family";
     60     } else {
     61       rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
     62       port_->OnStunBindingRequestSucceeded(server_addr_, addr);
     63     }
     64 
     65     // We will do a keep-alive regardless of whether this request succeeds.
     66     // It will be stopped after |deadline_| mostly to conserve the battery life.
     67     if (rtc::Time() <= deadline_) {
     68       port_->requests_.SendDelayed(
     69           new StunBindingRequest(port_, server_addr_, deadline_),
     70           port_->stun_keepalive_delay());
     71     }
     72   }
     73 
     74   virtual void OnErrorResponse(StunMessage* response) override {
     75     const StunErrorCodeAttribute* attr = response->GetErrorCode();
     76     if (!attr) {
     77       LOG(LS_ERROR) << "Bad allocate response error code";
     78     } else {
     79       LOG(LS_ERROR) << "Binding error response:"
     80                  << " class=" << attr->eclass()
     81                  << " number=" << attr->number()
     82                  << " reason='" << attr->reason() << "'";
     83     }
     84 
     85     port_->OnStunBindingOrResolveRequestFailed(server_addr_);
     86 
     87     uint32_t now = rtc::Time();
     88     if (now <= deadline_ && rtc::TimeDiff(now, start_time_) <= RETRY_TIMEOUT) {
     89       port_->requests_.SendDelayed(
     90           new StunBindingRequest(port_, server_addr_, deadline_),
     91           port_->stun_keepalive_delay());
     92     }
     93   }
     94 
     95   virtual void OnTimeout() override {
     96     LOG(LS_ERROR) << "Binding request timed out from "
     97       << port_->GetLocalAddress().ToSensitiveString()
     98       << " (" << port_->Network()->name() << ")";
     99 
    100     port_->OnStunBindingOrResolveRequestFailed(server_addr_);
    101   }
    102 
    103  private:
    104   UDPPort* port_;
    105   const rtc::SocketAddress server_addr_;
    106   uint32_t start_time_;
    107   uint32_t deadline_;
    108 };
    109 
    110 UDPPort::AddressResolver::AddressResolver(
    111     rtc::PacketSocketFactory* factory)
    112     : socket_factory_(factory) {}
    113 
    114 UDPPort::AddressResolver::~AddressResolver() {
    115   for (ResolverMap::iterator it = resolvers_.begin();
    116        it != resolvers_.end(); ++it) {
    117     // TODO(guoweis): Change to asynchronous DNS resolution to prevent the hang
    118     // when passing true to the Destroy() which is a safer way to avoid the code
    119     // unloaded before the thread exits. Please see webrtc bug 5139.
    120     it->second->Destroy(false);
    121   }
    122 }
    123 
    124 void UDPPort::AddressResolver::Resolve(
    125     const rtc::SocketAddress& address) {
    126   if (resolvers_.find(address) != resolvers_.end())
    127     return;
    128 
    129   rtc::AsyncResolverInterface* resolver =
    130       socket_factory_->CreateAsyncResolver();
    131   resolvers_.insert(
    132       std::pair<rtc::SocketAddress, rtc::AsyncResolverInterface*>(
    133           address, resolver));
    134 
    135   resolver->SignalDone.connect(this,
    136                                &UDPPort::AddressResolver::OnResolveResult);
    137 
    138   resolver->Start(address);
    139 }
    140 
    141 bool UDPPort::AddressResolver::GetResolvedAddress(
    142     const rtc::SocketAddress& input,
    143     int family,
    144     rtc::SocketAddress* output) const {
    145   ResolverMap::const_iterator it = resolvers_.find(input);
    146   if (it == resolvers_.end())
    147     return false;
    148 
    149   return it->second->GetResolvedAddress(family, output);
    150 }
    151 
    152 void UDPPort::AddressResolver::OnResolveResult(
    153     rtc::AsyncResolverInterface* resolver) {
    154   for (ResolverMap::iterator it = resolvers_.begin();
    155        it != resolvers_.end(); ++it) {
    156     if (it->second == resolver) {
    157       SignalDone(it->first, resolver->GetError());
    158       return;
    159     }
    160   }
    161 }
    162 
    163 UDPPort::UDPPort(rtc::Thread* thread,
    164                  rtc::PacketSocketFactory* factory,
    165                  rtc::Network* network,
    166                  rtc::AsyncPacketSocket* socket,
    167                  const std::string& username,
    168                  const std::string& password,
    169                  const std::string& origin,
    170                  bool emit_local_for_anyaddress)
    171     : Port(thread,
    172            factory,
    173            network,
    174            socket->GetLocalAddress().ipaddr(),
    175            username,
    176            password),
    177       requests_(thread),
    178       socket_(socket),
    179       error_(0),
    180       ready_(false),
    181       stun_keepalive_delay_(KEEPALIVE_DELAY),
    182       emit_local_for_anyaddress_(emit_local_for_anyaddress) {
    183   requests_.set_origin(origin);
    184 }
    185 
    186 UDPPort::UDPPort(rtc::Thread* thread,
    187                  rtc::PacketSocketFactory* factory,
    188                  rtc::Network* network,
    189                  const rtc::IPAddress& ip,
    190                  uint16_t min_port,
    191                  uint16_t max_port,
    192                  const std::string& username,
    193                  const std::string& password,
    194                  const std::string& origin,
    195                  bool emit_local_for_anyaddress)
    196     : Port(thread,
    197            LOCAL_PORT_TYPE,
    198            factory,
    199            network,
    200            ip,
    201            min_port,
    202            max_port,
    203            username,
    204            password),
    205       requests_(thread),
    206       socket_(NULL),
    207       error_(0),
    208       ready_(false),
    209       stun_keepalive_delay_(KEEPALIVE_DELAY),
    210       emit_local_for_anyaddress_(emit_local_for_anyaddress) {
    211   requests_.set_origin(origin);
    212 }
    213 
    214 bool UDPPort::Init() {
    215   if (!SharedSocket()) {
    216     ASSERT(socket_ == NULL);
    217     socket_ = socket_factory()->CreateUdpSocket(
    218         rtc::SocketAddress(ip(), 0), min_port(), max_port());
    219     if (!socket_) {
    220       LOG_J(LS_WARNING, this) << "UDP socket creation failed";
    221       return false;
    222     }
    223     socket_->SignalReadPacket.connect(this, &UDPPort::OnReadPacket);
    224   }
    225   socket_->SignalSentPacket.connect(this, &UDPPort::OnSentPacket);
    226   socket_->SignalReadyToSend.connect(this, &UDPPort::OnReadyToSend);
    227   socket_->SignalAddressReady.connect(this, &UDPPort::OnLocalAddressReady);
    228   requests_.SignalSendPacket.connect(this, &UDPPort::OnSendPacket);
    229   return true;
    230 }
    231 
    232 UDPPort::~UDPPort() {
    233   if (!SharedSocket())
    234     delete socket_;
    235 }
    236 
    237 void UDPPort::PrepareAddress() {
    238   ASSERT(requests_.empty());
    239   if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
    240     OnLocalAddressReady(socket_, socket_->GetLocalAddress());
    241   }
    242 }
    243 
    244 void UDPPort::MaybePrepareStunCandidate() {
    245   // Sending binding request to the STUN server if address is available to
    246   // prepare STUN candidate.
    247   if (!server_addresses_.empty()) {
    248     SendStunBindingRequests();
    249   } else {
    250     // Port is done allocating candidates.
    251     MaybeSetPortCompleteOrError();
    252   }
    253 }
    254 
    255 Connection* UDPPort::CreateConnection(const Candidate& address,
    256                                       CandidateOrigin origin) {
    257   if (!SupportsProtocol(address.protocol())) {
    258     return NULL;
    259   }
    260 
    261   if (!IsCompatibleAddress(address.address())) {
    262     return NULL;
    263   }
    264 
    265   if (SharedSocket() && Candidates()[0].type() != LOCAL_PORT_TYPE) {
    266     ASSERT(false);
    267     return NULL;
    268   }
    269 
    270   Connection* conn = new ProxyConnection(this, 0, address);
    271   AddConnection(conn);
    272   return conn;
    273 }
    274 
    275 int UDPPort::SendTo(const void* data, size_t size,
    276                     const rtc::SocketAddress& addr,
    277                     const rtc::PacketOptions& options,
    278                     bool payload) {
    279   int sent = socket_->SendTo(data, size, addr, options);
    280   if (sent < 0) {
    281     error_ = socket_->GetError();
    282     LOG_J(LS_ERROR, this) << "UDP send of " << size
    283                           << " bytes failed with error " << error_;
    284   }
    285   return sent;
    286 }
    287 
    288 int UDPPort::SetOption(rtc::Socket::Option opt, int value) {
    289   return socket_->SetOption(opt, value);
    290 }
    291 
    292 int UDPPort::GetOption(rtc::Socket::Option opt, int* value) {
    293   return socket_->GetOption(opt, value);
    294 }
    295 
    296 int UDPPort::GetError() {
    297   return error_;
    298 }
    299 
    300 void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
    301                                   const rtc::SocketAddress& address) {
    302   // When adapter enumeration is disabled and binding to the any address, the
    303   // default local address will be issued as a candidate instead if
    304   // |emit_local_for_anyaddress| is true. This is to allow connectivity for
    305   // applications which absolutely requires a HOST candidate.
    306   rtc::SocketAddress addr = address;
    307 
    308   // If MaybeSetDefaultLocalAddress fails, we keep the "any" IP so that at
    309   // least the port is listening.
    310   MaybeSetDefaultLocalAddress(&addr);
    311 
    312   AddAddress(addr, addr, rtc::SocketAddress(), UDP_PROTOCOL_NAME, "", "",
    313              LOCAL_PORT_TYPE, ICE_TYPE_PREFERENCE_HOST, 0, false);
    314   MaybePrepareStunCandidate();
    315 }
    316 
    317 void UDPPort::OnReadPacket(rtc::AsyncPacketSocket* socket,
    318                            const char* data,
    319                            size_t size,
    320                            const rtc::SocketAddress& remote_addr,
    321                            const rtc::PacketTime& packet_time) {
    322   ASSERT(socket == socket_);
    323   ASSERT(!remote_addr.IsUnresolvedIP());
    324 
    325   // Look for a response from the STUN server.
    326   // Even if the response doesn't match one of our outstanding requests, we
    327   // will eat it because it might be a response to a retransmitted packet, and
    328   // we already cleared the request when we got the first response.
    329   if (server_addresses_.find(remote_addr) != server_addresses_.end()) {
    330     requests_.CheckResponse(data, size);
    331     return;
    332   }
    333 
    334   if (Connection* conn = GetConnection(remote_addr)) {
    335     conn->OnReadPacket(data, size, packet_time);
    336   } else {
    337     Port::OnReadPacket(data, size, remote_addr, PROTO_UDP);
    338   }
    339 }
    340 
    341 void UDPPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
    342                            const rtc::SentPacket& sent_packet) {
    343   PortInterface::SignalSentPacket(sent_packet);
    344 }
    345 
    346 void UDPPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
    347   Port::OnReadyToSend();
    348 }
    349 
    350 void UDPPort::SendStunBindingRequests() {
    351   // We will keep pinging the stun server to make sure our NAT pin-hole stays
    352   // open until the deadline (specified in SendStunBindingRequest).
    353   ASSERT(requests_.empty());
    354 
    355   for (ServerAddresses::const_iterator it = server_addresses_.begin();
    356        it != server_addresses_.end(); ++it) {
    357     SendStunBindingRequest(*it);
    358   }
    359 }
    360 
    361 void UDPPort::ResolveStunAddress(const rtc::SocketAddress& stun_addr) {
    362   if (!resolver_) {
    363     resolver_.reset(new AddressResolver(socket_factory()));
    364     resolver_->SignalDone.connect(this, &UDPPort::OnResolveResult);
    365   }
    366 
    367   LOG_J(LS_INFO, this) << "Starting STUN host lookup for "
    368                        << stun_addr.ToSensitiveString();
    369   resolver_->Resolve(stun_addr);
    370 }
    371 
    372 void UDPPort::OnResolveResult(const rtc::SocketAddress& input,
    373                               int error) {
    374   ASSERT(resolver_.get() != NULL);
    375 
    376   rtc::SocketAddress resolved;
    377   if (error != 0 ||
    378       !resolver_->GetResolvedAddress(input, ip().family(), &resolved))  {
    379     LOG_J(LS_WARNING, this) << "StunPort: stun host lookup received error "
    380                             << error;
    381     OnStunBindingOrResolveRequestFailed(input);
    382     return;
    383   }
    384 
    385   server_addresses_.erase(input);
    386 
    387   if (server_addresses_.find(resolved) == server_addresses_.end()) {
    388     server_addresses_.insert(resolved);
    389     SendStunBindingRequest(resolved);
    390   }
    391 }
    392 
    393 void UDPPort::SendStunBindingRequest(const rtc::SocketAddress& stun_addr) {
    394   if (stun_addr.IsUnresolvedIP()) {
    395     ResolveStunAddress(stun_addr);
    396 
    397   } else if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
    398     // Check if |server_addr_| is compatible with the port's ip.
    399     if (IsCompatibleAddress(stun_addr)) {
    400       requests_.Send(new StunBindingRequest(this, stun_addr,
    401                                             rtc::Time() + KEEP_ALIVE_TIMEOUT));
    402     } else {
    403       // Since we can't send stun messages to the server, we should mark this
    404       // port ready.
    405       LOG(LS_WARNING) << "STUN server address is incompatible.";
    406       OnStunBindingOrResolveRequestFailed(stun_addr);
    407     }
    408   }
    409 }
    410 
    411 bool UDPPort::MaybeSetDefaultLocalAddress(rtc::SocketAddress* addr) const {
    412   if (!addr->IsAnyIP() || !emit_local_for_anyaddress_ ||
    413       !Network()->default_local_address_provider()) {
    414     return true;
    415   }
    416   rtc::IPAddress default_address;
    417   bool result =
    418       Network()->default_local_address_provider()->GetDefaultLocalAddress(
    419           addr->family(), &default_address);
    420   if (!result || default_address.IsNil()) {
    421     return false;
    422   }
    423 
    424   addr->SetIP(default_address);
    425   return true;
    426 }
    427 
    428 void UDPPort::OnStunBindingRequestSucceeded(
    429     const rtc::SocketAddress& stun_server_addr,
    430     const rtc::SocketAddress& stun_reflected_addr) {
    431   if (bind_request_succeeded_servers_.find(stun_server_addr) !=
    432           bind_request_succeeded_servers_.end()) {
    433     return;
    434   }
    435   bind_request_succeeded_servers_.insert(stun_server_addr);
    436 
    437   // If socket is shared and |stun_reflected_addr| is equal to local socket
    438   // address, or if the same address has been added by another STUN server,
    439   // then discarding the stun address.
    440   // For STUN, related address is the local socket address.
    441   if ((!SharedSocket() || stun_reflected_addr != socket_->GetLocalAddress()) &&
    442       !HasCandidateWithAddress(stun_reflected_addr)) {
    443 
    444     rtc::SocketAddress related_address = socket_->GetLocalAddress();
    445     // If we can't stamp the related address correctly, empty it to avoid leak.
    446     if (!MaybeSetDefaultLocalAddress(&related_address) ||
    447         !(candidate_filter() & CF_HOST)) {
    448       // If candidate filter doesn't have CF_HOST specified, empty raddr to
    449       // avoid local address leakage.
    450       related_address = rtc::EmptySocketAddressWithFamily(
    451           related_address.family());
    452     }
    453 
    454     AddAddress(stun_reflected_addr, socket_->GetLocalAddress(), related_address,
    455                UDP_PROTOCOL_NAME, "", "", STUN_PORT_TYPE,
    456                ICE_TYPE_PREFERENCE_SRFLX, 0, false);
    457   }
    458   MaybeSetPortCompleteOrError();
    459 }
    460 
    461 void UDPPort::OnStunBindingOrResolveRequestFailed(
    462     const rtc::SocketAddress& stun_server_addr) {
    463   if (bind_request_failed_servers_.find(stun_server_addr) !=
    464           bind_request_failed_servers_.end()) {
    465     return;
    466   }
    467   bind_request_failed_servers_.insert(stun_server_addr);
    468   MaybeSetPortCompleteOrError();
    469 }
    470 
    471 void UDPPort::MaybeSetPortCompleteOrError() {
    472   if (ready_)
    473     return;
    474 
    475   // Do not set port ready if we are still waiting for bind responses.
    476   const size_t servers_done_bind_request = bind_request_failed_servers_.size() +
    477       bind_request_succeeded_servers_.size();
    478   if (server_addresses_.size() != servers_done_bind_request) {
    479     return;
    480   }
    481 
    482   // Setting ready status.
    483   ready_ = true;
    484 
    485   // The port is "completed" if there is no stun server provided, or the bind
    486   // request succeeded for any stun server, or the socket is shared.
    487   if (server_addresses_.empty() ||
    488       bind_request_succeeded_servers_.size() > 0 ||
    489       SharedSocket()) {
    490     SignalPortComplete(this);
    491   } else {
    492     SignalPortError(this);
    493   }
    494 }
    495 
    496 // TODO: merge this with SendTo above.
    497 void UDPPort::OnSendPacket(const void* data, size_t size, StunRequest* req) {
    498   StunBindingRequest* sreq = static_cast<StunBindingRequest*>(req);
    499   rtc::PacketOptions options(DefaultDscpValue());
    500   if (socket_->SendTo(data, size, sreq->server_addr(), options) < 0)
    501     PLOG(LERROR, socket_->GetError()) << "sendto";
    502 }
    503 
    504 bool UDPPort::HasCandidateWithAddress(const rtc::SocketAddress& addr) const {
    505   const std::vector<Candidate>& existing_candidates = Candidates();
    506   std::vector<Candidate>::const_iterator it = existing_candidates.begin();
    507   for (; it != existing_candidates.end(); ++it) {
    508     if (it->address() == addr)
    509       return true;
    510   }
    511   return false;
    512 }
    513 
    514 }  // namespace cricket
    515