Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / turnport.cc
1 /*
2  * libjingle
3  * Copyright 2012, 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 "talk/p2p/base/turnport.h"
29
30 #include <functional>
31
32 #include "talk/base/asyncpacketsocket.h"
33 #include "talk/base/byteorder.h"
34 #include "talk/base/common.h"
35 #include "talk/base/logging.h"
36 #include "talk/base/nethelpers.h"
37 #include "talk/base/socketaddress.h"
38 #include "talk/base/stringencode.h"
39 #include "talk/p2p/base/common.h"
40 #include "talk/p2p/base/stun.h"
41
42 namespace cricket {
43
44 // TODO(juberti): Move to stun.h when relay messages have been renamed.
45 static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
46
47 // TODO(juberti): Extract to turnmessage.h
48 static const int TURN_DEFAULT_PORT = 3478;
49 static const int TURN_CHANNEL_NUMBER_START = 0x4000;
50 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000;  // 5 minutes
51
52 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
53
54 inline bool IsTurnChannelData(uint16 msg_type) {
55   return ((msg_type & 0xC000) == 0x4000);  // MSB are 0b01
56 }
57
58 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) {
59   int relay_preference = ICE_TYPE_PREFERENCE_RELAY;
60   if (proto == cricket::PROTO_TCP) {
61     relay_preference -= 1;
62     if (secure)
63       relay_preference -= 1;
64   }
65
66   ASSERT(relay_preference >= 0);
67   return relay_preference;
68 }
69
70 class TurnAllocateRequest : public StunRequest {
71  public:
72   explicit TurnAllocateRequest(TurnPort* port);
73   virtual void Prepare(StunMessage* request);
74   virtual void OnResponse(StunMessage* response);
75   virtual void OnErrorResponse(StunMessage* response);
76   virtual void OnTimeout();
77
78  private:
79   // Handles authentication challenge from the server.
80   void OnAuthChallenge(StunMessage* response, int code);
81   void OnUnknownAttribute(StunMessage* response);
82
83   TurnPort* port_;
84 };
85
86 class TurnRefreshRequest : public StunRequest {
87  public:
88   explicit TurnRefreshRequest(TurnPort* port);
89   virtual void Prepare(StunMessage* request);
90   virtual void OnResponse(StunMessage* response);
91   virtual void OnErrorResponse(StunMessage* response);
92   virtual void OnTimeout();
93
94  private:
95   TurnPort* port_;
96 };
97
98 class TurnCreatePermissionRequest : public StunRequest,
99                                     public sigslot::has_slots<> {
100  public:
101   TurnCreatePermissionRequest(TurnPort* port, TurnEntry* entry,
102                               const talk_base::SocketAddress& ext_addr);
103   virtual void Prepare(StunMessage* request);
104   virtual void OnResponse(StunMessage* response);
105   virtual void OnErrorResponse(StunMessage* response);
106   virtual void OnTimeout();
107
108  private:
109   void OnEntryDestroyed(TurnEntry* entry);
110
111   TurnPort* port_;
112   TurnEntry* entry_;
113   talk_base::SocketAddress ext_addr_;
114 };
115
116 class TurnChannelBindRequest : public StunRequest,
117                                public sigslot::has_slots<> {
118  public:
119   TurnChannelBindRequest(TurnPort* port, TurnEntry* entry, int channel_id,
120                          const talk_base::SocketAddress& ext_addr);
121   virtual void Prepare(StunMessage* request);
122   virtual void OnResponse(StunMessage* response);
123   virtual void OnErrorResponse(StunMessage* response);
124   virtual void OnTimeout();
125
126  private:
127   void OnEntryDestroyed(TurnEntry* entry);
128
129   TurnPort* port_;
130   TurnEntry* entry_;
131   int channel_id_;
132   talk_base::SocketAddress ext_addr_;
133 };
134
135 // Manages a "connection" to a remote destination. We will attempt to bring up
136 // a channel for this remote destination to reduce the overhead of sending data.
137 class TurnEntry : public sigslot::has_slots<> {
138  public:
139   enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
140   TurnEntry(TurnPort* port, int channel_id,
141             const talk_base::SocketAddress& ext_addr);
142
143   TurnPort* port() { return port_; }
144
145   int channel_id() const { return channel_id_; }
146   const talk_base::SocketAddress& address() const { return ext_addr_; }
147   BindState state() const { return state_; }
148
149   // Helper methods to send permission and channel bind requests.
150   void SendCreatePermissionRequest();
151   void SendChannelBindRequest(int delay);
152   // Sends a packet to the given destination address.
153   // This will wrap the packet in STUN if necessary.
154   int Send(const void* data, size_t size, bool payload,
155            const talk_base::PacketOptions& options);
156
157   void OnCreatePermissionSuccess();
158   void OnCreatePermissionError(StunMessage* response, int code);
159   void OnChannelBindSuccess();
160   void OnChannelBindError(StunMessage* response, int code);
161   // Signal sent when TurnEntry is destroyed.
162   sigslot::signal1<TurnEntry*> SignalDestroyed;
163
164  private:
165   TurnPort* port_;
166   int channel_id_;
167   talk_base::SocketAddress ext_addr_;
168   BindState state_;
169 };
170
171 TurnPort::TurnPort(talk_base::Thread* thread,
172                    talk_base::PacketSocketFactory* factory,
173                    talk_base::Network* network,
174                    talk_base::AsyncPacketSocket* socket,
175                    const std::string& username,
176                    const std::string& password,
177                    const ProtocolAddress& server_address,
178                    const RelayCredentials& credentials)
179     : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
180            username, password),
181       server_address_(server_address),
182       credentials_(credentials),
183       socket_(socket),
184       resolver_(NULL),
185       error_(0),
186       request_manager_(thread),
187       next_channel_number_(TURN_CHANNEL_NUMBER_START),
188       connected_(false) {
189   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
190 }
191
192 TurnPort::TurnPort(talk_base::Thread* thread,
193                    talk_base::PacketSocketFactory* factory,
194                    talk_base::Network* network,
195                    const talk_base::IPAddress& ip,
196                    int min_port, int max_port,
197                    const std::string& username,
198                    const std::string& password,
199                    const ProtocolAddress& server_address,
200                    const RelayCredentials& credentials)
201     : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port,
202            username, password),
203       server_address_(server_address),
204       credentials_(credentials),
205       socket_(NULL),
206       resolver_(NULL),
207       error_(0),
208       request_manager_(thread),
209       next_channel_number_(TURN_CHANNEL_NUMBER_START),
210       connected_(false) {
211   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
212 }
213
214 TurnPort::~TurnPort() {
215   // TODO(juberti): Should this even be necessary?
216   while (!entries_.empty()) {
217     DestroyEntry(entries_.front()->address());
218   }
219   if (resolver_) {
220     resolver_->Destroy(false);
221   }
222   if (!SharedSocket()) {
223     delete socket_;
224   }
225 }
226
227 void TurnPort::PrepareAddress() {
228   if (credentials_.username.empty() ||
229       credentials_.password.empty()) {
230     LOG(LS_ERROR) << "Allocation can't be started without setting the"
231                   << " TURN server credentials for the user.";
232     OnAllocateError();
233     return;
234   }
235
236   if (!server_address_.address.port()) {
237     // We will set default TURN port, if no port is set in the address.
238     server_address_.address.SetPort(TURN_DEFAULT_PORT);
239   }
240
241   if (server_address_.address.IsUnresolved()) {
242     ResolveTurnAddress(server_address_.address);
243   } else {
244     // If protocol family of server address doesn't match with local, return.
245     if (!IsCompatibleAddress(server_address_.address)) {
246       LOG(LS_ERROR) << "Server IP address family does not match with "
247                     << "local host address family type";
248       OnAllocateError();
249       return;
250     }
251
252     LOG_J(LS_INFO, this) << "Trying to connect to TURN server via "
253                          << ProtoToString(server_address_.proto) << " @ "
254                          << server_address_.address.ToSensitiveString();
255     if (server_address_.proto == PROTO_UDP && !SharedSocket()) {
256       socket_ = socket_factory()->CreateUdpSocket(
257           talk_base::SocketAddress(ip(), 0), min_port(), max_port());
258     } else if (server_address_.proto == PROTO_TCP) {
259       ASSERT(!SharedSocket());
260       int opts = talk_base::PacketSocketFactory::OPT_STUN;
261       // If secure bit is enabled in server address, use TLS over TCP.
262       if (server_address_.secure) {
263         opts |= talk_base::PacketSocketFactory::OPT_TLS;
264       }
265       socket_ = socket_factory()->CreateClientTcpSocket(
266           talk_base::SocketAddress(ip(), 0), server_address_.address,
267           proxy(), user_agent(), opts);
268     }
269
270     if (!socket_) {
271       OnAllocateError();
272       return;
273     }
274
275     // Apply options if any.
276     for (SocketOptionsMap::iterator iter = socket_options_.begin();
277          iter != socket_options_.end(); ++iter) {
278       socket_->SetOption(iter->first, iter->second);
279     }
280
281     if (!SharedSocket()) {
282       // If socket is shared, AllocationSequence will receive the packet.
283       socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
284     }
285
286     socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
287
288     if (server_address_.proto == PROTO_TCP) {
289       socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
290       socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
291     } else {
292       // If its UDP, send AllocateRequest now.
293       // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
294       SendRequest(new TurnAllocateRequest(this), 0);
295     }
296   }
297 }
298
299 void TurnPort::OnSocketConnect(talk_base::AsyncPacketSocket* socket) {
300   ASSERT(server_address_.proto == PROTO_TCP);
301   // Do not use this port if the socket bound to a different address than
302   // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
303   // given a binding address, and the platform is expected to pick the
304   // correct local address.
305   if (socket->GetLocalAddress().ipaddr() != ip()) {
306     LOG(LS_WARNING) << "Socket is bound to a different address then the "
307                     << "local port. Discarding TURN port.";
308     OnAllocateError();
309     return;
310   }
311
312   LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress()
313                << " using tcp.";
314   SendRequest(new TurnAllocateRequest(this), 0);
315 }
316
317 void TurnPort::OnSocketClose(talk_base::AsyncPacketSocket* socket, int error) {
318   LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error;
319   if (!connected_) {
320     OnAllocateError();
321   }
322 }
323
324 Connection* TurnPort::CreateConnection(const Candidate& address,
325                                        CandidateOrigin origin) {
326   // TURN-UDP can only connect to UDP candidates.
327   if (address.protocol() != UDP_PROTOCOL_NAME) {
328     return NULL;
329   }
330
331   if (!IsCompatibleAddress(address.address())) {
332     return NULL;
333   }
334
335   // Create an entry, if needed, so we can get our permissions set up correctly.
336   CreateEntry(address.address());
337
338   // A TURN port will have two candiates, STUN and TURN. STUN may not
339   // present in all cases. If present stun candidate will be added first
340   // and TURN candidate later.
341   for (size_t index = 0; index < Candidates().size(); ++index) {
342     if (Candidates()[index].type() == RELAY_PORT_TYPE) {
343       ProxyConnection* conn = new ProxyConnection(this, index, address);
344       conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed);
345       AddConnection(conn);
346       return conn;
347     }
348   }
349   return NULL;
350 }
351
352 int TurnPort::SetOption(talk_base::Socket::Option opt, int value) {
353   if (!socket_) {
354     // If socket is not created yet, these options will be applied during socket
355     // creation.
356     socket_options_[opt] = value;
357     return 0;
358   }
359   return socket_->SetOption(opt, value);
360 }
361
362 int TurnPort::GetOption(talk_base::Socket::Option opt, int* value) {
363   if (!socket_) {
364     SocketOptionsMap::const_iterator it = socket_options_.find(opt);
365     if (it == socket_options_.end()) {
366       return -1;
367     }
368     *value = it->second;
369     return 0;
370   }
371
372   return socket_->GetOption(opt, value);
373 }
374
375 int TurnPort::GetError() {
376   return error_;
377 }
378
379 int TurnPort::SendTo(const void* data, size_t size,
380                      const talk_base::SocketAddress& addr,
381                      const talk_base::PacketOptions& options,
382                      bool payload) {
383   // Try to find an entry for this specific address; we should have one.
384   TurnEntry* entry = FindEntry(addr);
385   ASSERT(entry != NULL);
386   if (!entry) {
387     return 0;
388   }
389
390   if (!connected()) {
391     error_ = EWOULDBLOCK;
392     return SOCKET_ERROR;
393   }
394
395   // Send the actual contents to the server using the usual mechanism.
396   int sent = entry->Send(data, size, payload, options);
397   if (sent <= 0) {
398     return SOCKET_ERROR;
399   }
400
401   // The caller of the function is expecting the number of user data bytes,
402   // rather than the size of the packet.
403   return static_cast<int>(size);
404 }
405
406 void TurnPort::OnReadPacket(
407     talk_base::AsyncPacketSocket* socket, const char* data, size_t size,
408     const talk_base::SocketAddress& remote_addr,
409     const talk_base::PacketTime& packet_time) {
410   ASSERT(socket == socket_);
411   ASSERT(remote_addr == server_address_.address);
412
413   // The message must be at least the size of a channel header.
414   if (size < TURN_CHANNEL_HEADER_SIZE) {
415     LOG_J(LS_WARNING, this) << "Received TURN message that was too short";
416     return;
417   }
418
419   // Check the message type, to see if is a Channel Data message.
420   // The message will either be channel data, a TURN data indication, or
421   // a response to a previous request.
422   uint16 msg_type = talk_base::GetBE16(data);
423   if (IsTurnChannelData(msg_type)) {
424     HandleChannelData(msg_type, data, size, packet_time);
425   } else if (msg_type == TURN_DATA_INDICATION) {
426     HandleDataIndication(data, size, packet_time);
427   } else {
428     // This must be a response for one of our requests.
429     // Check success responses, but not errors, for MESSAGE-INTEGRITY.
430     if (IsStunSuccessResponseType(msg_type) &&
431         !StunMessage::ValidateMessageIntegrity(data, size, hash())) {
432       LOG_J(LS_WARNING, this) << "Received TURN message with invalid "
433                               << "message integrity, msg_type=" << msg_type;
434       return;
435     }
436     request_manager_.CheckResponse(data, size);
437   }
438 }
439
440 void TurnPort::OnReadyToSend(talk_base::AsyncPacketSocket* socket) {
441   if (connected_) {
442     Port::OnReadyToSend();
443   }
444 }
445
446 void TurnPort::ResolveTurnAddress(const talk_base::SocketAddress& address) {
447   if (resolver_)
448     return;
449
450   resolver_ = socket_factory()->CreateAsyncResolver();
451   resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
452   resolver_->Start(address);
453 }
454
455 void TurnPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) {
456   ASSERT(resolver == resolver_);
457   // Copy the original server address in |resolved_address|. For TLS based
458   // sockets we need hostname along with resolved address.
459   talk_base::SocketAddress resolved_address = server_address_.address;
460   if (resolver_->GetError() != 0 ||
461       !resolver_->GetResolvedAddress(ip().family(), &resolved_address)) {
462     LOG_J(LS_WARNING, this) << "TURN host lookup received error "
463                             << resolver_->GetError();
464     OnAllocateError();
465     return;
466   }
467   // Signal needs both resolved and unresolved address. After signal is sent
468   // we can copy resolved address back into |server_address_|.
469   SignalResolvedServerAddress(this, server_address_.address,
470                               resolved_address);
471   server_address_.address = resolved_address;
472   PrepareAddress();
473 }
474
475 void TurnPort::OnSendStunPacket(const void* data, size_t size,
476                                 StunRequest* request) {
477   talk_base::PacketOptions options(DefaultDscpValue());
478   if (Send(data, size, options) < 0) {
479     LOG_J(LS_ERROR, this) << "Failed to send TURN message, err="
480                           << socket_->GetError();
481   }
482 }
483
484 void TurnPort::OnStunAddress(const talk_base::SocketAddress& address) {
485   // STUN Port will discover STUN candidate, as it's supplied with first TURN
486   // server address.
487   // Why not using this address? - P2PTransportChannel will start creating
488   // connections after first candidate, which means it could start creating the
489   // connections before TURN candidate added. For that to handle, we need to
490   // supply STUN candidate from this port to UDPPort, and TurnPort should have
491   // handle to UDPPort to pass back the address.
492 }
493
494 void TurnPort::OnAllocateSuccess(const talk_base::SocketAddress& address,
495                                  const talk_base::SocketAddress& stun_address) {
496   connected_ = true;
497   // For relayed candidate, Base is the candidate itself.
498   AddAddress(address,  // Candidate address.
499              address,  // Base address.
500              stun_address,  // Related address.
501              UDP_PROTOCOL_NAME,
502              RELAY_PORT_TYPE,
503              GetRelayPreference(server_address_.proto, server_address_.secure),
504              true);
505 }
506
507 void TurnPort::OnAllocateError() {
508   // We will send SignalPortError asynchronously as this can be sent during
509   // port initialization. This way it will not be blocking other port
510   // creation.
511   thread()->Post(this, MSG_ERROR);
512 }
513
514 void TurnPort::OnMessage(talk_base::Message* message) {
515   if (message->message_id == MSG_ERROR) {
516     SignalPortError(this);
517     return;
518   }
519
520   Port::OnMessage(message);
521 }
522
523 void TurnPort::OnAllocateRequestTimeout() {
524   OnAllocateError();
525 }
526
527 void TurnPort::HandleDataIndication(const char* data, size_t size,
528                                     const talk_base::PacketTime& packet_time) {
529   // Read in the message, and process according to RFC5766, Section 10.4.
530   talk_base::ByteBuffer buf(data, size);
531   TurnMessage msg;
532   if (!msg.Read(&buf)) {
533     LOG_J(LS_WARNING, this) << "Received invalid TURN data indication";
534     return;
535   }
536
537   // Check mandatory attributes.
538   const StunAddressAttribute* addr_attr =
539       msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
540   if (!addr_attr) {
541     LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_XOR_PEER_ADDRESS attribute "
542                             << "in data indication.";
543     return;
544   }
545
546   const StunByteStringAttribute* data_attr =
547       msg.GetByteString(STUN_ATTR_DATA);
548   if (!data_attr) {
549     LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_DATA attribute in "
550                             << "data indication.";
551     return;
552   }
553
554   // Verify that the data came from somewhere we think we have a permission for.
555   talk_base::SocketAddress ext_addr(addr_attr->GetAddress());
556   if (!HasPermission(ext_addr.ipaddr())) {
557     LOG_J(LS_WARNING, this) << "Received TURN data indication with invalid "
558                             << "peer address, addr="
559                             << ext_addr.ToSensitiveString();
560     return;
561   }
562
563   DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr,
564                  PROTO_UDP, packet_time);
565 }
566
567 void TurnPort::HandleChannelData(int channel_id, const char* data,
568                                  size_t size,
569                                  const talk_base::PacketTime& packet_time) {
570   // Read the message, and process according to RFC5766, Section 11.6.
571   //    0                   1                   2                   3
572   //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
573   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
574   //   |         Channel Number        |            Length             |
575   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
576   //   |                                                               |
577   //   /                       Application Data                        /
578   //   /                                                               /
579   //   |                                                               |
580   //   |                               +-------------------------------+
581   //   |                               |
582   //   +-------------------------------+
583
584   // Extract header fields from the message.
585   uint16 len = talk_base::GetBE16(data + 2);
586   if (len > size - TURN_CHANNEL_HEADER_SIZE) {
587     LOG_J(LS_WARNING, this) << "Received TURN channel data message with "
588                             << "incorrect length, len=" << len;
589     return;
590   }
591   // Allowing messages larger than |len|, as ChannelData can be padded.
592
593   TurnEntry* entry = FindEntry(channel_id);
594   if (!entry) {
595     LOG_J(LS_WARNING, this) << "Received TURN channel data message for invalid "
596                             << "channel, channel_id=" << channel_id;
597     return;
598   }
599
600   DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(),
601                  PROTO_UDP, packet_time);
602 }
603
604 void TurnPort::DispatchPacket(const char* data, size_t size,
605     const talk_base::SocketAddress& remote_addr,
606     ProtocolType proto, const talk_base::PacketTime& packet_time) {
607   if (Connection* conn = GetConnection(remote_addr)) {
608     conn->OnReadPacket(data, size, packet_time);
609   } else {
610     Port::OnReadPacket(data, size, remote_addr, proto);
611   }
612 }
613
614 bool TurnPort::ScheduleRefresh(int lifetime) {
615   // Lifetime is in seconds; we schedule a refresh for one minute less.
616   if (lifetime < 2 * 60) {
617     LOG_J(LS_WARNING, this) << "Received response with lifetime that was "
618                             << "too short, lifetime=" << lifetime;
619     return false;
620   }
621
622   SendRequest(new TurnRefreshRequest(this), (lifetime - 60) * 1000);
623   return true;
624 }
625
626 void TurnPort::SendRequest(StunRequest* req, int delay) {
627   request_manager_.SendDelayed(req, delay);
628 }
629
630 void TurnPort::AddRequestAuthInfo(StunMessage* msg) {
631   // If we've gotten the necessary data from the server, add it to our request.
632   VERIFY(!hash_.empty());
633   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
634       STUN_ATTR_USERNAME, credentials_.username)));
635   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
636       STUN_ATTR_REALM, realm_)));
637   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
638       STUN_ATTR_NONCE, nonce_)));
639   VERIFY(msg->AddMessageIntegrity(hash()));
640 }
641
642 int TurnPort::Send(const void* data, size_t len,
643                    const talk_base::PacketOptions& options) {
644   return socket_->SendTo(data, len, server_address_.address, options);
645 }
646
647 void TurnPort::UpdateHash() {
648   VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
649                                    credentials_.password, &hash_));
650 }
651
652 bool TurnPort::UpdateNonce(StunMessage* response) {
653   // When stale nonce error received, we should update
654   // hash and store realm and nonce.
655   // Check the mandatory attributes.
656   const StunByteStringAttribute* realm_attr =
657       response->GetByteString(STUN_ATTR_REALM);
658   if (!realm_attr) {
659     LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in "
660                   << "stale nonce error response.";
661     return false;
662   }
663   set_realm(realm_attr->GetString());
664
665   const StunByteStringAttribute* nonce_attr =
666       response->GetByteString(STUN_ATTR_NONCE);
667   if (!nonce_attr) {
668     LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in "
669                   << "stale nonce error response.";
670     return false;
671   }
672   set_nonce(nonce_attr->GetString());
673   return true;
674 }
675
676 static bool MatchesIP(TurnEntry* e, talk_base::IPAddress ipaddr) {
677   return e->address().ipaddr() == ipaddr;
678 }
679 bool TurnPort::HasPermission(const talk_base::IPAddress& ipaddr) const {
680   return (std::find_if(entries_.begin(), entries_.end(),
681       std::bind2nd(std::ptr_fun(MatchesIP), ipaddr)) != entries_.end());
682 }
683
684 static bool MatchesAddress(TurnEntry* e, talk_base::SocketAddress addr) {
685   return e->address() == addr;
686 }
687 TurnEntry* TurnPort::FindEntry(const talk_base::SocketAddress& addr) const {
688   EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
689       std::bind2nd(std::ptr_fun(MatchesAddress), addr));
690   return (it != entries_.end()) ? *it : NULL;
691 }
692
693 static bool MatchesChannelId(TurnEntry* e, int id) {
694   return e->channel_id() == id;
695 }
696 TurnEntry* TurnPort::FindEntry(int channel_id) const {
697   EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
698       std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id));
699   return (it != entries_.end()) ? *it : NULL;
700 }
701
702 TurnEntry* TurnPort::CreateEntry(const talk_base::SocketAddress& addr) {
703   ASSERT(FindEntry(addr) == NULL);
704   TurnEntry* entry = new TurnEntry(this, next_channel_number_++, addr);
705   entries_.push_back(entry);
706   return entry;
707 }
708
709 void TurnPort::DestroyEntry(const talk_base::SocketAddress& addr) {
710   TurnEntry* entry = FindEntry(addr);
711   ASSERT(entry != NULL);
712   entry->SignalDestroyed(entry);
713   entries_.remove(entry);
714   delete entry;
715 }
716
717 void TurnPort::OnConnectionDestroyed(Connection* conn) {
718   // Destroying TurnEntry for the connection, which is already destroyed.
719   DestroyEntry(conn->remote_candidate().address());
720 }
721
722 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
723     : StunRequest(new TurnMessage()),
724       port_(port) {
725 }
726
727 void TurnAllocateRequest::Prepare(StunMessage* request) {
728   // Create the request as indicated in RFC 5766, Section 6.1.
729   request->SetType(TURN_ALLOCATE_REQUEST);
730   StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32(
731       STUN_ATTR_REQUESTED_TRANSPORT);
732   transport_attr->SetValue(IPPROTO_UDP << 24);
733   VERIFY(request->AddAttribute(transport_attr));
734   if (!port_->hash().empty()) {
735     port_->AddRequestAuthInfo(request);
736   }
737 }
738
739 void TurnAllocateRequest::OnResponse(StunMessage* response) {
740   // Check mandatory attributes as indicated in RFC5766, Section 6.3.
741   const StunAddressAttribute* mapped_attr =
742       response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
743   if (!mapped_attr) {
744     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
745                              << "attribute in allocate success response";
746     return;
747   }
748   // Using XOR-Mapped-Address for stun.
749   port_->OnStunAddress(mapped_attr->GetAddress());
750
751   const StunAddressAttribute* relayed_attr =
752       response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
753   if (!relayed_attr) {
754     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
755                              << "attribute in allocate success response";
756     return;
757   }
758
759   const StunUInt32Attribute* lifetime_attr =
760       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
761   if (!lifetime_attr) {
762     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
763                              << "allocate success response";
764     return;
765   }
766   // Notify the port the allocate succeeded, and schedule a refresh request.
767   port_->OnAllocateSuccess(relayed_attr->GetAddress(),
768                            mapped_attr->GetAddress());
769   port_->ScheduleRefresh(lifetime_attr->value());
770 }
771
772 void TurnAllocateRequest::OnErrorResponse(StunMessage* response) {
773   // Process error response according to RFC5766, Section 6.4.
774   const StunErrorCodeAttribute* error_code = response->GetErrorCode();
775   switch (error_code->code()) {
776     case STUN_ERROR_UNAUTHORIZED:       // Unauthrorized.
777       OnAuthChallenge(response, error_code->code());
778       break;
779     default:
780       LOG_J(LS_WARNING, port_) << "Allocate response error, code="
781                                << error_code->code();
782       port_->OnAllocateError();
783   }
784 }
785
786 void TurnAllocateRequest::OnTimeout() {
787   LOG_J(LS_WARNING, port_) << "Allocate request timeout";
788   port_->OnAllocateRequestTimeout();
789 }
790
791 void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) {
792   // If we failed to authenticate even after we sent our credentials, fail hard.
793   if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) {
794     LOG_J(LS_WARNING, port_) << "Failed to authenticate with the server "
795                              << "after challenge.";
796     port_->OnAllocateError();
797     return;
798   }
799
800   // Check the mandatory attributes.
801   const StunByteStringAttribute* realm_attr =
802       response->GetByteString(STUN_ATTR_REALM);
803   if (!realm_attr) {
804     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_REALM attribute in "
805                              << "allocate unauthorized response.";
806     return;
807   }
808   port_->set_realm(realm_attr->GetString());
809
810   const StunByteStringAttribute* nonce_attr =
811       response->GetByteString(STUN_ATTR_NONCE);
812   if (!nonce_attr) {
813     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_NONCE attribute in "
814                              << "allocate unauthorized response.";
815     return;
816   }
817   port_->set_nonce(nonce_attr->GetString());
818
819   // Send another allocate request, with the received realm and nonce values.
820   port_->SendRequest(new TurnAllocateRequest(port_), 0);
821 }
822
823 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
824     : StunRequest(new TurnMessage()),
825       port_(port) {
826 }
827
828 void TurnRefreshRequest::Prepare(StunMessage* request) {
829   // Create the request as indicated in RFC 5766, Section 7.1.
830   // No attributes need to be included.
831   request->SetType(TURN_REFRESH_REQUEST);
832   port_->AddRequestAuthInfo(request);
833 }
834
835 void TurnRefreshRequest::OnResponse(StunMessage* response) {
836   // Check mandatory attributes as indicated in RFC5766, Section 7.3.
837   const StunUInt32Attribute* lifetime_attr =
838       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
839   if (!lifetime_attr) {
840     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
841                              << "refresh success response.";
842     return;
843   }
844
845   // Schedule a refresh based on the returned lifetime value.
846   port_->ScheduleRefresh(lifetime_attr->value());
847 }
848
849 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) {
850   // TODO(juberti): Handle 437 error response as a success.
851   const StunErrorCodeAttribute* error_code = response->GetErrorCode();
852   LOG_J(LS_WARNING, port_) << "Refresh response error, code="
853                            << error_code->code();
854
855   if (error_code->code() == STUN_ERROR_STALE_NONCE) {
856     if (port_->UpdateNonce(response)) {
857       // Send RefreshRequest immediately.
858       port_->SendRequest(new TurnRefreshRequest(port_), 0);
859     }
860   }
861 }
862
863 void TurnRefreshRequest::OnTimeout() {
864 }
865
866 TurnCreatePermissionRequest::TurnCreatePermissionRequest(
867     TurnPort* port, TurnEntry* entry,
868     const talk_base::SocketAddress& ext_addr)
869     : StunRequest(new TurnMessage()),
870       port_(port),
871       entry_(entry),
872       ext_addr_(ext_addr) {
873   entry_->SignalDestroyed.connect(
874       this, &TurnCreatePermissionRequest::OnEntryDestroyed);
875 }
876
877 void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
878   // Create the request as indicated in RFC5766, Section 9.1.
879   request->SetType(TURN_CREATE_PERMISSION_REQUEST);
880   VERIFY(request->AddAttribute(new StunXorAddressAttribute(
881       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
882   port_->AddRequestAuthInfo(request);
883 }
884
885 void TurnCreatePermissionRequest::OnResponse(StunMessage* response) {
886   if (entry_) {
887     entry_->OnCreatePermissionSuccess();
888   }
889 }
890
891 void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) {
892   if (entry_) {
893     const StunErrorCodeAttribute* error_code = response->GetErrorCode();
894     entry_->OnCreatePermissionError(response, error_code->code());
895   }
896 }
897
898 void TurnCreatePermissionRequest::OnTimeout() {
899   LOG_J(LS_WARNING, port_) << "Create permission timeout";
900 }
901
902 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
903   ASSERT(entry_ == entry);
904   entry_ = NULL;
905 }
906
907 TurnChannelBindRequest::TurnChannelBindRequest(
908     TurnPort* port, TurnEntry* entry,
909     int channel_id, const talk_base::SocketAddress& ext_addr)
910     : StunRequest(new TurnMessage()),
911       port_(port),
912       entry_(entry),
913       channel_id_(channel_id),
914       ext_addr_(ext_addr) {
915   entry_->SignalDestroyed.connect(
916       this, &TurnChannelBindRequest::OnEntryDestroyed);
917 }
918
919 void TurnChannelBindRequest::Prepare(StunMessage* request) {
920   // Create the request as indicated in RFC5766, Section 11.1.
921   request->SetType(TURN_CHANNEL_BIND_REQUEST);
922   VERIFY(request->AddAttribute(new StunUInt32Attribute(
923       STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16)));
924   VERIFY(request->AddAttribute(new StunXorAddressAttribute(
925       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
926   port_->AddRequestAuthInfo(request);
927 }
928
929 void TurnChannelBindRequest::OnResponse(StunMessage* response) {
930   if (entry_) {
931     entry_->OnChannelBindSuccess();
932     // Refresh the channel binding just under the permission timeout
933     // threshold. The channel binding has a longer lifetime, but
934     // this is the easiest way to keep both the channel and the
935     // permission from expiring.
936     entry_->SendChannelBindRequest(TURN_PERMISSION_TIMEOUT - 60 * 1000);
937   }
938 }
939
940 void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) {
941   if (entry_) {
942     const StunErrorCodeAttribute* error_code = response->GetErrorCode();
943     entry_->OnChannelBindError(response, error_code->code());
944   }
945 }
946
947 void TurnChannelBindRequest::OnTimeout() {
948   LOG_J(LS_WARNING, port_) << "Channel bind timeout";
949 }
950
951 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
952   ASSERT(entry_ == entry);
953   entry_ = NULL;
954 }
955
956 TurnEntry::TurnEntry(TurnPort* port, int channel_id,
957                      const talk_base::SocketAddress& ext_addr)
958     : port_(port),
959       channel_id_(channel_id),
960       ext_addr_(ext_addr),
961       state_(STATE_UNBOUND) {
962   // Creating permission for |ext_addr_|.
963   SendCreatePermissionRequest();
964 }
965
966 void TurnEntry::SendCreatePermissionRequest() {
967   port_->SendRequest(new TurnCreatePermissionRequest(
968       port_, this, ext_addr_), 0);
969 }
970
971 void TurnEntry::SendChannelBindRequest(int delay) {
972   port_->SendRequest(new TurnChannelBindRequest(
973       port_, this, channel_id_, ext_addr_), delay);
974 }
975
976 int TurnEntry::Send(const void* data, size_t size, bool payload,
977                     const talk_base::PacketOptions& options) {
978   talk_base::ByteBuffer buf;
979   if (state_ != STATE_BOUND) {
980     // If we haven't bound the channel yet, we have to use a Send Indication.
981     TurnMessage msg;
982     msg.SetType(TURN_SEND_INDICATION);
983     msg.SetTransactionID(
984         talk_base::CreateRandomString(kStunTransactionIdLength));
985     VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
986         STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
987     VERIFY(msg.AddAttribute(new StunByteStringAttribute(
988         STUN_ATTR_DATA, data, size)));
989     VERIFY(msg.Write(&buf));
990
991     // If we're sending real data, request a channel bind that we can use later.
992     if (state_ == STATE_UNBOUND && payload) {
993       SendChannelBindRequest(0);
994       state_ = STATE_BINDING;
995     }
996   } else {
997     // If the channel is bound, we can send the data as a Channel Message.
998     buf.WriteUInt16(channel_id_);
999     buf.WriteUInt16(static_cast<uint16>(size));
1000     buf.WriteBytes(reinterpret_cast<const char*>(data), size);
1001   }
1002   return port_->Send(buf.Data(), buf.Length(), options);
1003 }
1004
1005 void TurnEntry::OnCreatePermissionSuccess() {
1006   LOG_J(LS_INFO, port_) << "Create permission for "
1007                         << ext_addr_.ToSensitiveString()
1008                         << " succeeded";
1009   // For success result code will be 0.
1010   port_->SignalCreatePermissionResult(port_, ext_addr_, 0);
1011 }
1012
1013 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
1014   LOG_J(LS_WARNING, port_) << "Create permission for "
1015                            << ext_addr_.ToSensitiveString()
1016                            << " failed, code=" << code;
1017   if (code == STUN_ERROR_STALE_NONCE) {
1018     if (port_->UpdateNonce(response)) {
1019       SendCreatePermissionRequest();
1020     }
1021   } else {
1022     // Send signal with error code.
1023     port_->SignalCreatePermissionResult(port_, ext_addr_, code);
1024   }
1025 }
1026
1027 void TurnEntry::OnChannelBindSuccess() {
1028   LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString()
1029                         << " succeeded";
1030   ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND);
1031   state_ = STATE_BOUND;
1032 }
1033
1034 void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
1035   // TODO(mallinath) - Implement handling of error response for channel
1036   // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3
1037   LOG_J(LS_WARNING, port_) << "Channel bind for "
1038                            << ext_addr_.ToSensitiveString()
1039                            << " failed, code=" << code;
1040   if (code == STUN_ERROR_STALE_NONCE) {
1041     if (port_->UpdateNonce(response)) {
1042       // Send channel bind request with fresh nonce.
1043       SendChannelBindRequest(0);
1044     }
1045   }
1046 }
1047
1048 }  // namespace cricket