Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / stunport.cc
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "webrtc/p2p/base/stunport.h"
29
30 #include "webrtc/p2p/base/common.h"
31 #include "webrtc/p2p/base/portallocator.h"
32 #include "webrtc/p2p/base/stun.h"
33 #include "webrtc/base/common.h"
34 #include "webrtc/base/helpers.h"
35 #include "webrtc/base/logging.h"
36 #include "webrtc/base/nethelpers.h"
37
38 namespace cricket {
39
40 // TODO: Move these to a common place (used in relayport too)
41 const int KEEPALIVE_DELAY = 10 * 1000;  // 10 seconds - sort timeouts
42 const int RETRY_DELAY = 50;             // 50ms, from ICE spec
43 const int RETRY_TIMEOUT = 50 * 1000;    // ICE says 50 secs
44
45 // Handles a binding request sent to the STUN server.
46 class StunBindingRequest : public StunRequest {
47  public:
48   StunBindingRequest(UDPPort* port, bool keep_alive,
49                      const rtc::SocketAddress& addr)
50     : port_(port), keep_alive_(keep_alive), server_addr_(addr) {
51     start_time_ = rtc::Time();
52   }
53
54   virtual ~StunBindingRequest() {
55   }
56
57   const rtc::SocketAddress& server_addr() const { return server_addr_; }
58
59   virtual void Prepare(StunMessage* request) {
60     request->SetType(STUN_BINDING_REQUEST);
61   }
62
63   virtual void OnResponse(StunMessage* response) {
64     const StunAddressAttribute* addr_attr =
65         response->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
66     if (!addr_attr) {
67       LOG(LS_ERROR) << "Binding response missing mapped address.";
68     } else if (addr_attr->family() != STUN_ADDRESS_IPV4 &&
69                addr_attr->family() != STUN_ADDRESS_IPV6) {
70       LOG(LS_ERROR) << "Binding address has bad family";
71     } else {
72       rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
73       port_->OnStunBindingRequestSucceeded(server_addr_, addr);
74     }
75
76     // We will do a keep-alive regardless of whether this request succeeds.
77     // This should have almost no impact on network usage.
78     if (keep_alive_) {
79       port_->requests_.SendDelayed(
80           new StunBindingRequest(port_, true, server_addr_),
81           port_->stun_keepalive_delay());
82     }
83   }
84
85   virtual void OnErrorResponse(StunMessage* response) {
86     const StunErrorCodeAttribute* attr = response->GetErrorCode();
87     if (!attr) {
88       LOG(LS_ERROR) << "Bad allocate response error code";
89     } else {
90       LOG(LS_ERROR) << "Binding error response:"
91                  << " class=" << attr->eclass()
92                  << " number=" << attr->number()
93                  << " reason='" << attr->reason() << "'";
94     }
95
96     port_->OnStunBindingOrResolveRequestFailed(server_addr_);
97
98     if (keep_alive_
99         && (rtc::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
100       port_->requests_.SendDelayed(
101           new StunBindingRequest(port_, true, server_addr_),
102           port_->stun_keepalive_delay());
103     }
104   }
105
106   virtual void OnTimeout() {
107     LOG(LS_ERROR) << "Binding request timed out from "
108       << port_->GetLocalAddress().ToSensitiveString()
109       << " (" << port_->Network()->name() << ")";
110
111     port_->OnStunBindingOrResolveRequestFailed(server_addr_);
112
113     if (keep_alive_
114         && (rtc::TimeSince(start_time_) <= RETRY_TIMEOUT)) {
115       port_->requests_.SendDelayed(
116           new StunBindingRequest(port_, true, server_addr_),
117           RETRY_DELAY);
118     }
119   }
120
121  private:
122   UDPPort* port_;
123   bool keep_alive_;
124   const rtc::SocketAddress server_addr_;
125   uint32 start_time_;
126 };
127
128 UDPPort::AddressResolver::AddressResolver(
129     rtc::PacketSocketFactory* factory)
130     : socket_factory_(factory) {}
131
132 UDPPort::AddressResolver::~AddressResolver() {
133   for (ResolverMap::iterator it = resolvers_.begin();
134        it != resolvers_.end(); ++it) {
135     it->second->Destroy(true);
136   }
137 }
138
139 void UDPPort::AddressResolver::Resolve(
140     const rtc::SocketAddress& address) {
141   if (resolvers_.find(address) != resolvers_.end())
142     return;
143
144   rtc::AsyncResolverInterface* resolver =
145       socket_factory_->CreateAsyncResolver();
146   resolvers_.insert(
147       std::pair<rtc::SocketAddress, rtc::AsyncResolverInterface*>(
148           address, resolver));
149
150   resolver->SignalDone.connect(this,
151                                &UDPPort::AddressResolver::OnResolveResult);
152
153   resolver->Start(address);
154 }
155
156 bool UDPPort::AddressResolver::GetResolvedAddress(
157     const rtc::SocketAddress& input,
158     int family,
159     rtc::SocketAddress* output) const {
160   ResolverMap::const_iterator it = resolvers_.find(input);
161   if (it == resolvers_.end())
162     return false;
163
164   return it->second->GetResolvedAddress(family, output);
165 }
166
167 void UDPPort::AddressResolver::OnResolveResult(
168     rtc::AsyncResolverInterface* resolver) {
169   for (ResolverMap::iterator it = resolvers_.begin();
170        it != resolvers_.end(); ++it) {
171     if (it->second == resolver) {
172       SignalDone(it->first, resolver->GetError());
173       return;
174     }
175   }
176 }
177
178 UDPPort::UDPPort(rtc::Thread* thread,
179                  rtc::PacketSocketFactory* factory,
180                  rtc::Network* network,
181                  rtc::AsyncPacketSocket* socket,
182                  const std::string& username, const std::string& password)
183     : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
184            username, password),
185       requests_(thread),
186       socket_(socket),
187       error_(0),
188       ready_(false),
189       stun_keepalive_delay_(KEEPALIVE_DELAY) {
190 }
191
192 UDPPort::UDPPort(rtc::Thread* thread,
193                  rtc::PacketSocketFactory* factory,
194                  rtc::Network* network,
195                  const rtc::IPAddress& ip, int min_port, int max_port,
196                  const std::string& username, const std::string& password)
197     : Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port,
198            username, password),
199       requests_(thread),
200       socket_(NULL),
201       error_(0),
202       ready_(false),
203       stun_keepalive_delay_(KEEPALIVE_DELAY) {
204 }
205
206 bool UDPPort::Init() {
207   if (!SharedSocket()) {
208     ASSERT(socket_ == NULL);
209     socket_ = socket_factory()->CreateUdpSocket(
210         rtc::SocketAddress(ip(), 0), min_port(), max_port());
211     if (!socket_) {
212       LOG_J(LS_WARNING, this) << "UDP socket creation failed";
213       return false;
214     }
215     socket_->SignalReadPacket.connect(this, &UDPPort::OnReadPacket);
216   }
217   socket_->SignalReadyToSend.connect(this, &UDPPort::OnReadyToSend);
218   socket_->SignalAddressReady.connect(this, &UDPPort::OnLocalAddressReady);
219   requests_.SignalSendPacket.connect(this, &UDPPort::OnSendPacket);
220   return true;
221 }
222
223 UDPPort::~UDPPort() {
224   if (!SharedSocket())
225     delete socket_;
226 }
227
228 void UDPPort::PrepareAddress() {
229   ASSERT(requests_.empty());
230   if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
231     OnLocalAddressReady(socket_, socket_->GetLocalAddress());
232   }
233 }
234
235 void UDPPort::MaybePrepareStunCandidate() {
236   // Sending binding request to the STUN server if address is available to
237   // prepare STUN candidate.
238   if (!server_addresses_.empty()) {
239     SendStunBindingRequests();
240   } else {
241     // Port is done allocating candidates.
242     MaybeSetPortCompleteOrError();
243   }
244 }
245
246 Connection* UDPPort::CreateConnection(const Candidate& address,
247                                        CandidateOrigin origin) {
248   if (address.protocol() != "udp")
249     return NULL;
250
251   if (!IsCompatibleAddress(address.address())) {
252     return NULL;
253   }
254
255   if (SharedSocket() && Candidates()[0].type() != LOCAL_PORT_TYPE) {
256     ASSERT(false);
257     return NULL;
258   }
259
260   Connection* conn = new ProxyConnection(this, 0, address);
261   AddConnection(conn);
262   return conn;
263 }
264
265 int UDPPort::SendTo(const void* data, size_t size,
266                     const rtc::SocketAddress& addr,
267                     const rtc::PacketOptions& options,
268                     bool payload) {
269   int sent = socket_->SendTo(data, size, addr, options);
270   if (sent < 0) {
271     error_ = socket_->GetError();
272     LOG_J(LS_ERROR, this) << "UDP send of " << size
273                           << " bytes failed with error " << error_;
274   }
275   return sent;
276 }
277
278 int UDPPort::SetOption(rtc::Socket::Option opt, int value) {
279   return socket_->SetOption(opt, value);
280 }
281
282 int UDPPort::GetOption(rtc::Socket::Option opt, int* value) {
283   return socket_->GetOption(opt, value);
284 }
285
286 int UDPPort::GetError() {
287   return error_;
288 }
289
290 void UDPPort::OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
291                                   const rtc::SocketAddress& address) {
292   AddAddress(address, address, rtc::SocketAddress(),
293              UDP_PROTOCOL_NAME, "", LOCAL_PORT_TYPE,
294              ICE_TYPE_PREFERENCE_HOST, 0, false);
295   MaybePrepareStunCandidate();
296 }
297
298 void UDPPort::OnReadPacket(
299   rtc::AsyncPacketSocket* socket, const char* data, size_t size,
300   const rtc::SocketAddress& remote_addr,
301   const rtc::PacketTime& packet_time) {
302   ASSERT(socket == socket_);
303   ASSERT(!remote_addr.IsUnresolved());
304
305   // Look for a response from the STUN server.
306   // Even if the response doesn't match one of our outstanding requests, we
307   // will eat it because it might be a response to a retransmitted packet, and
308   // we already cleared the request when we got the first response.
309   if (server_addresses_.find(remote_addr) != server_addresses_.end()) {
310     requests_.CheckResponse(data, size);
311     return;
312   }
313
314   if (Connection* conn = GetConnection(remote_addr)) {
315     conn->OnReadPacket(data, size, packet_time);
316   } else {
317     Port::OnReadPacket(data, size, remote_addr, PROTO_UDP);
318   }
319 }
320
321 void UDPPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
322   Port::OnReadyToSend();
323 }
324
325 void UDPPort::SendStunBindingRequests() {
326   // We will keep pinging the stun server to make sure our NAT pin-hole stays
327   // open during the call.
328   ASSERT(requests_.empty());
329
330   for (ServerAddresses::const_iterator it = server_addresses_.begin();
331        it != server_addresses_.end(); ++it) {
332     SendStunBindingRequest(*it);
333   }
334 }
335
336 void UDPPort::ResolveStunAddress(const rtc::SocketAddress& stun_addr) {
337   if (!resolver_) {
338     resolver_.reset(new AddressResolver(socket_factory()));
339     resolver_->SignalDone.connect(this, &UDPPort::OnResolveResult);
340   }
341
342   resolver_->Resolve(stun_addr);
343 }
344
345 void UDPPort::OnResolveResult(const rtc::SocketAddress& input,
346                               int error) {
347   ASSERT(resolver_.get() != NULL);
348
349   rtc::SocketAddress resolved;
350   if (error != 0 ||
351       !resolver_->GetResolvedAddress(input, ip().family(), &resolved))  {
352     LOG_J(LS_WARNING, this) << "StunPort: stun host lookup received error "
353                             << error;
354     OnStunBindingOrResolveRequestFailed(input);
355     return;
356   }
357
358   server_addresses_.erase(input);
359
360   if (server_addresses_.find(resolved) == server_addresses_.end()) {
361     server_addresses_.insert(resolved);
362     SendStunBindingRequest(resolved);
363   }
364 }
365
366 void UDPPort::SendStunBindingRequest(
367     const rtc::SocketAddress& stun_addr) {
368   if (stun_addr.IsUnresolved()) {
369     ResolveStunAddress(stun_addr);
370
371   } else if (socket_->GetState() == rtc::AsyncPacketSocket::STATE_BOUND) {
372     // Check if |server_addr_| is compatible with the port's ip.
373     if (IsCompatibleAddress(stun_addr)) {
374       requests_.Send(new StunBindingRequest(this, true, stun_addr));
375     } else {
376       // Since we can't send stun messages to the server, we should mark this
377       // port ready.
378       LOG(LS_WARNING) << "STUN server address is incompatible.";
379       OnStunBindingOrResolveRequestFailed(stun_addr);
380     }
381   }
382 }
383
384 void UDPPort::OnStunBindingRequestSucceeded(
385     const rtc::SocketAddress& stun_server_addr,
386     const rtc::SocketAddress& stun_reflected_addr) {
387   if (bind_request_succeeded_servers_.find(stun_server_addr) !=
388           bind_request_succeeded_servers_.end()) {
389     return;
390   }
391   bind_request_succeeded_servers_.insert(stun_server_addr);
392
393   // If socket is shared and |stun_reflected_addr| is equal to local socket
394   // address, or if the same address has been added by another STUN server,
395   // then discarding the stun address.
396   // For STUN, related address is the local socket address.
397   if ((!SharedSocket() || stun_reflected_addr != socket_->GetLocalAddress()) &&
398       !HasCandidateWithAddress(stun_reflected_addr)) {
399
400     rtc::SocketAddress related_address = socket_->GetLocalAddress();
401     if (!(candidate_filter() & CF_HOST)) {
402       // If candidate filter doesn't have CF_HOST specified, empty raddr to
403       // avoid local address leakage.
404       related_address = rtc::EmptySocketAddressWithFamily(
405           related_address.family());
406     }
407
408     AddAddress(stun_reflected_addr, socket_->GetLocalAddress(),
409                related_address, UDP_PROTOCOL_NAME, "",
410                STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, 0, false);
411   }
412   MaybeSetPortCompleteOrError();
413 }
414
415 void UDPPort::OnStunBindingOrResolveRequestFailed(
416     const rtc::SocketAddress& stun_server_addr) {
417   if (bind_request_failed_servers_.find(stun_server_addr) !=
418           bind_request_failed_servers_.end()) {
419     return;
420   }
421   bind_request_failed_servers_.insert(stun_server_addr);
422   MaybeSetPortCompleteOrError();
423 }
424
425 void UDPPort::MaybeSetPortCompleteOrError() {
426   if (ready_)
427     return;
428
429   // Do not set port ready if we are still waiting for bind responses.
430   const size_t servers_done_bind_request = bind_request_failed_servers_.size() +
431       bind_request_succeeded_servers_.size();
432   if (server_addresses_.size() != servers_done_bind_request) {
433     return;
434   }
435
436   // Setting ready status.
437   ready_ = true;
438
439   // The port is "completed" if there is no stun server provided, or the bind
440   // request succeeded for any stun server, or the socket is shared.
441   if (server_addresses_.empty() ||
442       bind_request_succeeded_servers_.size() > 0 ||
443       SharedSocket()) {
444     SignalPortComplete(this);
445   } else {
446     SignalPortError(this);
447   }
448 }
449
450 // TODO: merge this with SendTo above.
451 void UDPPort::OnSendPacket(const void* data, size_t size, StunRequest* req) {
452   StunBindingRequest* sreq = static_cast<StunBindingRequest*>(req);
453   rtc::PacketOptions options(DefaultDscpValue());
454   if (socket_->SendTo(data, size, sreq->server_addr(), options) < 0)
455     PLOG(LERROR, socket_->GetError()) << "sendto";
456 }
457
458 bool UDPPort::HasCandidateWithAddress(const rtc::SocketAddress& addr) const {
459   const std::vector<Candidate>& existing_candidates = Candidates();
460   std::vector<Candidate>::const_iterator it = existing_candidates.begin();
461   for (; it != existing_candidates.end(); ++it) {
462     if (it->address() == addr)
463       return true;
464   }
465   return false;
466 }
467
468 }  // namespace cricket