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: StunBindingRequest(UDPPort * port,const rtc::SocketAddress & addr,uint32_t deadline)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 ~StunBindingRequest()43 virtual ~StunBindingRequest() { 44 } 45 server_addr() const46 const rtc::SocketAddress& server_addr() const { return server_addr_; } 47 Prepare(StunMessage * request)48 virtual void Prepare(StunMessage* request) override { 49 request->SetType(STUN_BINDING_REQUEST); 50 } 51 OnResponse(StunMessage * response)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 OnErrorResponse(StunMessage * response)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 OnTimeout()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 AddressResolver(rtc::PacketSocketFactory * factory)110 UDPPort::AddressResolver::AddressResolver( 111 rtc::PacketSocketFactory* factory) 112 : socket_factory_(factory) {} 113 ~AddressResolver()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 Resolve(const rtc::SocketAddress & address)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 GetResolvedAddress(const rtc::SocketAddress & input,int family,rtc::SocketAddress * output) const141 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 OnResolveResult(rtc::AsyncResolverInterface * resolver)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 UDPPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const std::string & origin,bool emit_local_for_anyaddress)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 UDPPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const std::string & origin,bool emit_local_for_anyaddress)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 Init()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 ~UDPPort()232 UDPPort::~UDPPort() { 233 if (!SharedSocket()) 234 delete socket_; 235 } 236 PrepareAddress()237 void UDPPort::PrepareAddress() { 238 ASSERT(requests_.empty()); 239 if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) { 240 OnLocalAddressReady(socket_, socket_->GetLocalAddress()); 241 } 242 } 243 MaybePrepareStunCandidate()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 CreateConnection(const Candidate & address,CandidateOrigin origin)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 SendTo(const void * data,size_t size,const rtc::SocketAddress & addr,const rtc::PacketOptions & options,bool payload)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 SetOption(rtc::Socket::Option opt,int value)288 int UDPPort::SetOption(rtc::Socket::Option opt, int value) { 289 return socket_->SetOption(opt, value); 290 } 291 GetOption(rtc::Socket::Option opt,int * value)292 int UDPPort::GetOption(rtc::Socket::Option opt, int* value) { 293 return socket_->GetOption(opt, value); 294 } 295 GetError()296 int UDPPort::GetError() { 297 return error_; 298 } 299 OnLocalAddressReady(rtc::AsyncPacketSocket * socket,const rtc::SocketAddress & address)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 OnReadPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)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 OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & sent_packet)341 void UDPPort::OnSentPacket(rtc::AsyncPacketSocket* socket, 342 const rtc::SentPacket& sent_packet) { 343 PortInterface::SignalSentPacket(sent_packet); 344 } 345 OnReadyToSend(rtc::AsyncPacketSocket * socket)346 void UDPPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) { 347 Port::OnReadyToSend(); 348 } 349 SendStunBindingRequests()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 ResolveStunAddress(const rtc::SocketAddress & stun_addr)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 OnResolveResult(const rtc::SocketAddress & input,int error)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 SendStunBindingRequest(const rtc::SocketAddress & stun_addr)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 MaybeSetDefaultLocalAddress(rtc::SocketAddress * addr) const411 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 OnStunBindingRequestSucceeded(const rtc::SocketAddress & stun_server_addr,const rtc::SocketAddress & stun_reflected_addr)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 OnStunBindingOrResolveRequestFailed(const rtc::SocketAddress & stun_server_addr)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 MaybeSetPortCompleteOrError()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. OnSendPacket(const void * data,size_t size,StunRequest * req)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 HasCandidateWithAddress(const rtc::SocketAddress & addr) const504 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