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