Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / turnserver.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/turnserver.h"
29
30 #include "talk/base/bytebuffer.h"
31 #include "talk/base/helpers.h"
32 #include "talk/base/logging.h"
33 #include "talk/base/messagedigest.h"
34 #include "talk/base/socketadapters.h"
35 #include "talk/base/stringencode.h"
36 #include "talk/base/thread.h"
37 #include "talk/p2p/base/asyncstuntcpsocket.h"
38 #include "talk/p2p/base/common.h"
39 #include "talk/p2p/base/packetsocketfactory.h"
40 #include "talk/p2p/base/stun.h"
41
42 namespace cricket {
43
44 // TODO(juberti): Move this all to a future turnmessage.h
45 //static const int IPPROTO_UDP = 17;
46 static const int kNonceTimeout = 60 * 60 * 1000;              // 60 minutes
47 static const int kDefaultAllocationTimeout = 10 * 60 * 1000;  // 10 minutes
48 static const int kPermissionTimeout = 5 * 60 * 1000;          //  5 minutes
49 static const int kChannelTimeout = 10 * 60 * 1000;            // 10 minutes
50
51 static const int kMinChannelNumber = 0x4000;
52 static const int kMaxChannelNumber = 0x7FFF;
53
54 static const size_t kNonceKeySize = 16;
55 static const size_t kNonceSize = 40;
56
57 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
58
59 // TODO(mallinath) - Move these to a common place.
60 inline bool IsTurnChannelData(uint16 msg_type) {
61   // The first two bits of a channel data message are 0b01.
62   return ((msg_type & 0xC000) == 0x4000);
63 }
64
65 // IDs used for posted messages.
66 enum {
67   MSG_TIMEOUT,
68 };
69
70 // Encapsulates a TURN allocation.
71 // The object is created when an allocation request is received, and then
72 // handles TURN messages (via HandleTurnMessage) and channel data messages
73 // (via HandleChannelData) for this allocation when received by the server.
74 // The object self-deletes and informs the server if its lifetime timer expires.
75 class TurnServer::Allocation : public talk_base::MessageHandler,
76                                public sigslot::has_slots<> {
77  public:
78   Allocation(TurnServer* server_,
79              talk_base::Thread* thread, const Connection& conn,
80              talk_base::AsyncPacketSocket* server_socket,
81              const std::string& key);
82   virtual ~Allocation();
83
84   Connection* conn() { return &conn_; }
85   const std::string& key() const { return key_; }
86   const std::string& transaction_id() const { return transaction_id_; }
87   const std::string& username() const { return username_; }
88   const std::string& last_nonce() const { return last_nonce_; }
89   void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
90
91   std::string ToString() const;
92
93   void HandleTurnMessage(const TurnMessage* msg);
94   void HandleChannelData(const char* data, size_t size);
95
96   sigslot::signal1<Allocation*> SignalDestroyed;
97
98  private:
99   typedef std::list<Permission*> PermissionList;
100   typedef std::list<Channel*> ChannelList;
101
102   void HandleAllocateRequest(const TurnMessage* msg);
103   void HandleRefreshRequest(const TurnMessage* msg);
104   void HandleSendIndication(const TurnMessage* msg);
105   void HandleCreatePermissionRequest(const TurnMessage* msg);
106   void HandleChannelBindRequest(const TurnMessage* msg);
107
108   void OnExternalPacket(talk_base::AsyncPacketSocket* socket,
109                         const char* data, size_t size,
110                         const talk_base::SocketAddress& addr,
111                         const talk_base::PacketTime& packet_time);
112
113   static int ComputeLifetime(const TurnMessage* msg);
114   bool HasPermission(const talk_base::IPAddress& addr);
115   void AddPermission(const talk_base::IPAddress& addr);
116   Permission* FindPermission(const talk_base::IPAddress& addr) const;
117   Channel* FindChannel(int channel_id) const;
118   Channel* FindChannel(const talk_base::SocketAddress& addr) const;
119
120   void SendResponse(TurnMessage* msg);
121   void SendBadRequestResponse(const TurnMessage* req);
122   void SendErrorResponse(const TurnMessage* req, int code,
123                          const std::string& reason);
124   void SendExternal(const void* data, size_t size,
125                     const talk_base::SocketAddress& peer);
126
127   void OnPermissionDestroyed(Permission* perm);
128   void OnChannelDestroyed(Channel* channel);
129   virtual void OnMessage(talk_base::Message* msg);
130
131   TurnServer* server_;
132   talk_base::Thread* thread_;
133   Connection conn_;
134   talk_base::scoped_ptr<talk_base::AsyncPacketSocket> external_socket_;
135   std::string key_;
136   std::string transaction_id_;
137   std::string username_;
138   std::string last_nonce_;
139   PermissionList perms_;
140   ChannelList channels_;
141 };
142
143 // Encapsulates a TURN permission.
144 // The object is created when a create permission request is received by an
145 // allocation, and self-deletes when its lifetime timer expires.
146 class TurnServer::Permission : public talk_base::MessageHandler {
147  public:
148   Permission(talk_base::Thread* thread, const talk_base::IPAddress& peer);
149   ~Permission();
150
151   const talk_base::IPAddress& peer() const { return peer_; }
152   void Refresh();
153
154   sigslot::signal1<Permission*> SignalDestroyed;
155
156  private:
157   virtual void OnMessage(talk_base::Message* msg);
158
159   talk_base::Thread* thread_;
160   talk_base::IPAddress peer_;
161 };
162
163 // Encapsulates a TURN channel binding.
164 // The object is created when a channel bind request is received by an
165 // allocation, and self-deletes when its lifetime timer expires.
166 class TurnServer::Channel : public talk_base::MessageHandler {
167  public:
168   Channel(talk_base::Thread* thread, int id,
169                      const talk_base::SocketAddress& peer);
170   ~Channel();
171
172   int id() const { return id_; }
173   const talk_base::SocketAddress& peer() const { return peer_; }
174   void Refresh();
175
176   sigslot::signal1<Channel*> SignalDestroyed;
177
178  private:
179   virtual void OnMessage(talk_base::Message* msg);
180
181   talk_base::Thread* thread_;
182   int id_;
183   talk_base::SocketAddress peer_;
184 };
185
186 static bool InitResponse(const StunMessage* req, StunMessage* resp) {
187   int resp_type = (req) ? GetStunSuccessResponseType(req->type()) : -1;
188   if (resp_type == -1)
189     return false;
190   resp->SetType(resp_type);
191   resp->SetTransactionID(req->transaction_id());
192   return true;
193 }
194
195 static bool InitErrorResponse(const StunMessage* req, int code,
196                               const std::string& reason, StunMessage* resp) {
197   int resp_type = (req) ? GetStunErrorResponseType(req->type()) : -1;
198   if (resp_type == -1)
199     return false;
200   resp->SetType(resp_type);
201   resp->SetTransactionID(req->transaction_id());
202   VERIFY(resp->AddAttribute(new cricket::StunErrorCodeAttribute(
203       STUN_ATTR_ERROR_CODE, code, reason)));
204   return true;
205 }
206
207 TurnServer::TurnServer(talk_base::Thread* thread)
208     : thread_(thread),
209       nonce_key_(talk_base::CreateRandomString(kNonceKeySize)),
210       auth_hook_(NULL),
211       enable_otu_nonce_(false) {
212 }
213
214 TurnServer::~TurnServer() {
215   for (AllocationMap::iterator it = allocations_.begin();
216        it != allocations_.end(); ++it) {
217     delete it->second;
218   }
219
220   for (InternalSocketMap::iterator it = server_sockets_.begin();
221        it != server_sockets_.end(); ++it) {
222     talk_base::AsyncPacketSocket* socket = it->first;
223     delete socket;
224   }
225
226   for (ServerSocketMap::iterator it = server_listen_sockets_.begin();
227        it != server_listen_sockets_.end(); ++it) {
228     talk_base::AsyncSocket* socket = it->first;
229     delete socket;
230   }
231 }
232
233 void TurnServer::AddInternalSocket(talk_base::AsyncPacketSocket* socket,
234                                    ProtocolType proto) {
235   ASSERT(server_sockets_.end() == server_sockets_.find(socket));
236   server_sockets_[socket] = proto;
237   socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket);
238 }
239
240 void TurnServer::AddInternalServerSocket(talk_base::AsyncSocket* socket,
241                                          ProtocolType proto) {
242   ASSERT(server_listen_sockets_.end() ==
243       server_listen_sockets_.find(socket));
244   server_listen_sockets_[socket] = proto;
245   socket->SignalReadEvent.connect(this, &TurnServer::OnNewInternalConnection);
246 }
247
248 void TurnServer::SetExternalSocketFactory(
249     talk_base::PacketSocketFactory* factory,
250     const talk_base::SocketAddress& external_addr) {
251   external_socket_factory_.reset(factory);
252   external_addr_ = external_addr;
253 }
254
255 void TurnServer::OnNewInternalConnection(talk_base::AsyncSocket* socket) {
256   ASSERT(server_listen_sockets_.find(socket) != server_listen_sockets_.end());
257   AcceptConnection(socket);
258 }
259
260 void TurnServer::AcceptConnection(talk_base::AsyncSocket* server_socket) {
261   // Check if someone is trying to connect to us.
262   talk_base::SocketAddress accept_addr;
263   talk_base::AsyncSocket* accepted_socket = server_socket->Accept(&accept_addr);
264   if (accepted_socket != NULL) {
265     ProtocolType proto = server_listen_sockets_[server_socket];
266     cricket::AsyncStunTCPSocket* tcp_socket =
267         new cricket::AsyncStunTCPSocket(accepted_socket, false);
268
269     tcp_socket->SignalClose.connect(this, &TurnServer::OnInternalSocketClose);
270     // Finally add the socket so it can start communicating with the client.
271     AddInternalSocket(tcp_socket, proto);
272   }
273 }
274
275 void TurnServer::OnInternalSocketClose(talk_base::AsyncPacketSocket* socket,
276                                        int err) {
277   DestroyInternalSocket(socket);
278 }
279
280 void TurnServer::OnInternalPacket(talk_base::AsyncPacketSocket* socket,
281                                   const char* data, size_t size,
282                                   const talk_base::SocketAddress& addr,
283                                   const talk_base::PacketTime& packet_time) {
284   // Fail if the packet is too small to even contain a channel header.
285   if (size < TURN_CHANNEL_HEADER_SIZE) {
286    return;
287   }
288   InternalSocketMap::iterator iter = server_sockets_.find(socket);
289   ASSERT(iter != server_sockets_.end());
290   Connection conn(addr, iter->second, socket);
291   uint16 msg_type = talk_base::GetBE16(data);
292   if (!IsTurnChannelData(msg_type)) {
293     // This is a STUN message.
294     HandleStunMessage(&conn, data, size);
295   } else {
296     // This is a channel message; let the allocation handle it.
297     Allocation* allocation = FindAllocation(&conn);
298     if (allocation) {
299       allocation->HandleChannelData(data, size);
300     }
301   }
302 }
303
304 void TurnServer::HandleStunMessage(Connection* conn, const char* data,
305                                    size_t size) {
306   TurnMessage msg;
307   talk_base::ByteBuffer buf(data, size);
308   if (!msg.Read(&buf) || (buf.Length() > 0)) {
309     LOG(LS_WARNING) << "Received invalid STUN message";
310     return;
311   }
312
313   // If it's a STUN binding request, handle that specially.
314   if (msg.type() == STUN_BINDING_REQUEST) {
315     HandleBindingRequest(conn, &msg);
316     return;
317   }
318
319   // Look up the key that we'll use to validate the M-I. If we have an
320   // existing allocation, the key will already be cached.
321   Allocation* allocation = FindAllocation(conn);
322   std::string key;
323   if (!allocation) {
324     GetKey(&msg, &key);
325   } else {
326     key = allocation->key();
327   }
328
329   // Ensure the message is authorized; only needed for requests.
330   if (IsStunRequestType(msg.type())) {
331     if (!CheckAuthorization(conn, &msg, data, size, key)) {
332       return;
333     }
334   }
335
336   if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) {
337     // This is a new allocate request.
338     HandleAllocateRequest(conn, &msg, key);
339   } else if (allocation &&
340              (msg.type() != STUN_ALLOCATE_REQUEST ||
341               msg.transaction_id() == allocation->transaction_id())) {
342     // This is a non-allocate request, or a retransmit of an allocate.
343     // Check that the username matches the previous username used.
344     if (IsStunRequestType(msg.type()) &&
345         msg.GetByteString(STUN_ATTR_USERNAME)->GetString() !=
346             allocation->username()) {
347       SendErrorResponse(conn, &msg, STUN_ERROR_WRONG_CREDENTIALS,
348                         STUN_ERROR_REASON_WRONG_CREDENTIALS);
349       return;
350     }
351     allocation->HandleTurnMessage(&msg);
352   } else {
353     // Allocation mismatch.
354     SendErrorResponse(conn, &msg, STUN_ERROR_ALLOCATION_MISMATCH,
355                       STUN_ERROR_REASON_ALLOCATION_MISMATCH);
356   }
357 }
358
359 bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
360   const StunByteStringAttribute* username_attr =
361       msg->GetByteString(STUN_ATTR_USERNAME);
362   if (!username_attr) {
363     return false;
364   }
365
366   std::string username = username_attr->GetString();
367   return (auth_hook_ != NULL && auth_hook_->GetKey(username, realm_, key));
368 }
369
370 bool TurnServer::CheckAuthorization(Connection* conn,
371                                     const StunMessage* msg,
372                                     const char* data, size_t size,
373                                     const std::string& key) {
374   // RFC 5389, 10.2.2.
375   ASSERT(IsStunRequestType(msg->type()));
376   const StunByteStringAttribute* mi_attr =
377       msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
378   const StunByteStringAttribute* username_attr =
379       msg->GetByteString(STUN_ATTR_USERNAME);
380   const StunByteStringAttribute* realm_attr =
381       msg->GetByteString(STUN_ATTR_REALM);
382   const StunByteStringAttribute* nonce_attr =
383       msg->GetByteString(STUN_ATTR_NONCE);
384
385   // Fail if no M-I.
386   if (!mi_attr) {
387     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
388                                        STUN_ERROR_REASON_UNAUTHORIZED);
389     return false;
390   }
391
392   // Fail if there is M-I but no username, nonce, or realm.
393   if (!username_attr || !realm_attr || !nonce_attr) {
394     SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
395                       STUN_ERROR_REASON_BAD_REQUEST);
396     return false;
397   }
398
399   // Fail if bad nonce.
400   if (!ValidateNonce(nonce_attr->GetString())) {
401     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
402                                        STUN_ERROR_REASON_STALE_NONCE);
403     return false;
404   }
405
406   // Fail if bad username or M-I.
407   // We need |data| and |size| for the call to ValidateMessageIntegrity.
408   if (key.empty() || !StunMessage::ValidateMessageIntegrity(data, size, key)) {
409     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
410                                        STUN_ERROR_REASON_UNAUTHORIZED);
411     return false;
412   }
413
414   // Fail if one-time-use nonce feature is enabled.
415   Allocation* allocation = FindAllocation(conn);
416   if (enable_otu_nonce_ && allocation &&
417       allocation->last_nonce() == nonce_attr->GetString()) {
418     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
419                                        STUN_ERROR_REASON_STALE_NONCE);
420     return false;
421   }
422
423   if (allocation) {
424     allocation->set_last_nonce(nonce_attr->GetString());
425   }
426   // Success.
427   return true;
428 }
429
430 void TurnServer::HandleBindingRequest(Connection* conn,
431                                       const StunMessage* req) {
432   StunMessage response;
433   InitResponse(req, &response);
434
435   // Tell the user the address that we received their request from.
436   StunAddressAttribute* mapped_addr_attr;
437   mapped_addr_attr = new StunXorAddressAttribute(
438       STUN_ATTR_XOR_MAPPED_ADDRESS, conn->src());
439   VERIFY(response.AddAttribute(mapped_addr_attr));
440
441   SendStun(conn, &response);
442 }
443
444 void TurnServer::HandleAllocateRequest(Connection* conn,
445                                        const TurnMessage* msg,
446                                        const std::string& key) {
447   // Check the parameters in the request.
448   const StunUInt32Attribute* transport_attr =
449       msg->GetUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
450   if (!transport_attr) {
451     SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
452                       STUN_ERROR_REASON_BAD_REQUEST);
453     return;
454   }
455
456   // Only UDP is supported right now.
457   int proto = transport_attr->value() >> 24;
458   if (proto != IPPROTO_UDP) {
459     SendErrorResponse(conn, msg, STUN_ERROR_UNSUPPORTED_PROTOCOL,
460                       STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL);
461     return;
462   }
463
464   // Create the allocation and let it send the success response.
465   // If the actual socket allocation fails, send an internal error.
466   Allocation* alloc = CreateAllocation(conn, proto, key);
467   if (alloc) {
468     alloc->HandleTurnMessage(msg);
469   } else {
470     SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR,
471                       "Failed to allocate socket");
472   }
473 }
474
475 std::string TurnServer::GenerateNonce() const {
476   // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
477   uint32 now = talk_base::Time();
478   std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
479   std::string nonce = talk_base::hex_encode(input.c_str(), input.size());
480   nonce += talk_base::ComputeHmac(talk_base::DIGEST_MD5, nonce_key_, input);
481   ASSERT(nonce.size() == kNonceSize);
482   return nonce;
483 }
484
485 bool TurnServer::ValidateNonce(const std::string& nonce) const {
486   // Check the size.
487   if (nonce.size() != kNonceSize) {
488     return false;
489   }
490
491   // Decode the timestamp.
492   uint32 then;
493   char* p = reinterpret_cast<char*>(&then);
494   size_t len = talk_base::hex_decode(p, sizeof(then),
495       nonce.substr(0, sizeof(then) * 2));
496   if (len != sizeof(then)) {
497     return false;
498   }
499
500   // Verify the HMAC.
501   if (nonce.substr(sizeof(then) * 2) != talk_base::ComputeHmac(
502       talk_base::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) {
503     return false;
504   }
505
506   // Validate the timestamp.
507   return talk_base::TimeSince(then) < kNonceTimeout;
508 }
509
510 TurnServer::Allocation* TurnServer::FindAllocation(Connection* conn) {
511   AllocationMap::const_iterator it = allocations_.find(*conn);
512   return (it != allocations_.end()) ? it->second : NULL;
513 }
514
515 TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
516                                                      int proto,
517                                                      const std::string& key) {
518   talk_base::AsyncPacketSocket* external_socket = (external_socket_factory_) ?
519       external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0) : NULL;
520   if (!external_socket) {
521     return NULL;
522   }
523
524   // The Allocation takes ownership of the socket.
525   Allocation* allocation = new Allocation(this,
526       thread_, *conn, external_socket, key);
527   allocation->SignalDestroyed.connect(this, &TurnServer::OnAllocationDestroyed);
528   allocations_[*conn] = allocation;
529   return allocation;
530 }
531
532 void TurnServer::SendErrorResponse(Connection* conn,
533                                    const StunMessage* req,
534                                    int code, const std::string& reason) {
535   TurnMessage resp;
536   InitErrorResponse(req, code, reason, &resp);
537   LOG(LS_INFO) << "Sending error response, type=" << resp.type()
538                << ", code=" << code << ", reason=" << reason;
539   SendStun(conn, &resp);
540 }
541
542 void TurnServer::SendErrorResponseWithRealmAndNonce(
543     Connection* conn, const StunMessage* msg,
544     int code, const std::string& reason) {
545   TurnMessage resp;
546   InitErrorResponse(msg, code, reason, &resp);
547   VERIFY(resp.AddAttribute(new StunByteStringAttribute(
548       STUN_ATTR_NONCE, GenerateNonce())));
549   VERIFY(resp.AddAttribute(new StunByteStringAttribute(
550       STUN_ATTR_REALM, realm_)));
551   SendStun(conn, &resp);
552 }
553
554 void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
555   talk_base::ByteBuffer buf;
556   // Add a SOFTWARE attribute if one is set.
557   if (!software_.empty()) {
558     VERIFY(msg->AddAttribute(
559         new StunByteStringAttribute(STUN_ATTR_SOFTWARE, software_)));
560   }
561   msg->Write(&buf);
562   Send(conn, buf);
563 }
564
565 void TurnServer::Send(Connection* conn,
566                       const talk_base::ByteBuffer& buf) {
567   talk_base::PacketOptions options;
568   conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
569 }
570
571 void TurnServer::OnAllocationDestroyed(Allocation* allocation) {
572   // Removing the internal socket if the connection is not udp.
573   talk_base::AsyncPacketSocket* socket = allocation->conn()->socket();
574   InternalSocketMap::iterator iter = server_sockets_.find(socket);
575   ASSERT(iter != server_sockets_.end());
576   // Skip if the socket serving this allocation is UDP, as this will be shared
577   // by all allocations.
578   if (iter->second != cricket::PROTO_UDP) {
579     DestroyInternalSocket(socket);
580   }
581
582   AllocationMap::iterator it = allocations_.find(*(allocation->conn()));
583   if (it != allocations_.end())
584     allocations_.erase(it);
585 }
586
587 void TurnServer::DestroyInternalSocket(talk_base::AsyncPacketSocket* socket) {
588   InternalSocketMap::iterator iter = server_sockets_.find(socket);
589   if (iter != server_sockets_.end()) {
590     talk_base::AsyncPacketSocket* socket = iter->first;
591     delete socket;
592     server_sockets_.erase(iter);
593   }
594 }
595
596 TurnServer::Connection::Connection(const talk_base::SocketAddress& src,
597                                    ProtocolType proto,
598                                    talk_base::AsyncPacketSocket* socket)
599     : src_(src),
600       dst_(socket->GetRemoteAddress()),
601       proto_(proto),
602       socket_(socket) {
603 }
604
605 bool TurnServer::Connection::operator==(const Connection& c) const {
606   return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
607 }
608
609 bool TurnServer::Connection::operator<(const Connection& c) const {
610   return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_;
611 }
612
613 std::string TurnServer::Connection::ToString() const {
614   const char* const kProtos[] = {
615       "unknown", "udp", "tcp", "ssltcp"
616   };
617   std::ostringstream ost;
618   ost << src_.ToString() << "-" << dst_.ToString() << ":"<< kProtos[proto_];
619   return ost.str();
620 }
621
622 TurnServer::Allocation::Allocation(TurnServer* server,
623                                    talk_base::Thread* thread,
624                                    const Connection& conn,
625                                    talk_base::AsyncPacketSocket* socket,
626                                    const std::string& key)
627     : server_(server),
628       thread_(thread),
629       conn_(conn),
630       external_socket_(socket),
631       key_(key) {
632   external_socket_->SignalReadPacket.connect(
633       this, &TurnServer::Allocation::OnExternalPacket);
634 }
635
636 TurnServer::Allocation::~Allocation() {
637   for (ChannelList::iterator it = channels_.begin();
638        it != channels_.end(); ++it) {
639     delete *it;
640   }
641   for (PermissionList::iterator it = perms_.begin();
642        it != perms_.end(); ++it) {
643     delete *it;
644   }
645   thread_->Clear(this, MSG_TIMEOUT);
646   LOG_J(LS_INFO, this) << "Allocation destroyed";
647 }
648
649 std::string TurnServer::Allocation::ToString() const {
650   std::ostringstream ost;
651   ost << "Alloc[" << conn_.ToString() << "]";
652   return ost.str();
653 }
654
655 void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
656   ASSERT(msg != NULL);
657   switch (msg->type()) {
658     case STUN_ALLOCATE_REQUEST:
659       HandleAllocateRequest(msg);
660       break;
661     case TURN_REFRESH_REQUEST:
662       HandleRefreshRequest(msg);
663       break;
664     case TURN_SEND_INDICATION:
665       HandleSendIndication(msg);
666       break;
667     case TURN_CREATE_PERMISSION_REQUEST:
668       HandleCreatePermissionRequest(msg);
669       break;
670     case TURN_CHANNEL_BIND_REQUEST:
671       HandleChannelBindRequest(msg);
672       break;
673     default:
674       // Not sure what to do with this, just eat it.
675       LOG_J(LS_WARNING, this) << "Invalid TURN message type received: "
676                               << msg->type();
677   }
678 }
679
680 void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
681   // Copy the important info from the allocate request.
682   transaction_id_ = msg->transaction_id();
683   const StunByteStringAttribute* username_attr =
684       msg->GetByteString(STUN_ATTR_USERNAME);
685   ASSERT(username_attr != NULL);
686   username_ = username_attr->GetString();
687
688   // Figure out the lifetime and start the allocation timer.
689   int lifetime_secs = ComputeLifetime(msg);
690   thread_->PostDelayed(lifetime_secs * 1000, this, MSG_TIMEOUT);
691
692   LOG_J(LS_INFO, this) << "Created allocation, lifetime=" << lifetime_secs;
693
694   // We've already validated all the important bits; just send a response here.
695   TurnMessage response;
696   InitResponse(msg, &response);
697
698   StunAddressAttribute* mapped_addr_attr =
699       new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, conn_.src());
700   StunAddressAttribute* relayed_addr_attr =
701       new StunXorAddressAttribute(STUN_ATTR_XOR_RELAYED_ADDRESS,
702           external_socket_->GetLocalAddress());
703   StunUInt32Attribute* lifetime_attr =
704       new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
705   VERIFY(response.AddAttribute(mapped_addr_attr));
706   VERIFY(response.AddAttribute(relayed_addr_attr));
707   VERIFY(response.AddAttribute(lifetime_attr));
708
709   SendResponse(&response);
710 }
711
712 void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
713   // Figure out the new lifetime.
714   int lifetime_secs = ComputeLifetime(msg);
715
716   // Reset the expiration timer.
717   thread_->Clear(this, MSG_TIMEOUT);
718   thread_->PostDelayed(lifetime_secs * 1000, this, MSG_TIMEOUT);
719
720   LOG_J(LS_INFO, this) << "Refreshed allocation, lifetime=" << lifetime_secs;
721
722   // Send a success response with a LIFETIME attribute.
723   TurnMessage response;
724   InitResponse(msg, &response);
725
726   StunUInt32Attribute* lifetime_attr =
727       new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
728   VERIFY(response.AddAttribute(lifetime_attr));
729
730   SendResponse(&response);
731 }
732
733 void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
734   // Check mandatory attributes.
735   const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
736   const StunAddressAttribute* peer_attr =
737       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
738   if (!data_attr || !peer_attr) {
739     LOG_J(LS_WARNING, this) << "Received invalid send indication";
740     return;
741   }
742
743   // If a permission exists, send the data on to the peer.
744   if (HasPermission(peer_attr->GetAddress().ipaddr())) {
745     SendExternal(data_attr->bytes(), data_attr->length(),
746                  peer_attr->GetAddress());
747   } else {
748     LOG_J(LS_WARNING, this) << "Received send indication without permission"
749                             << "peer=" << peer_attr->GetAddress();
750   }
751 }
752
753 void TurnServer::Allocation::HandleCreatePermissionRequest(
754     const TurnMessage* msg) {
755   // Check mandatory attributes.
756   const StunAddressAttribute* peer_attr =
757       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
758   if (!peer_attr) {
759     SendBadRequestResponse(msg);
760     return;
761   }
762
763   // Add this permission.
764   AddPermission(peer_attr->GetAddress().ipaddr());
765
766   LOG_J(LS_INFO, this) << "Created permission, peer="
767                        << peer_attr->GetAddress();
768
769   // Send a success response.
770   TurnMessage response;
771   InitResponse(msg, &response);
772   SendResponse(&response);
773 }
774
775 void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
776   // Check mandatory attributes.
777   const StunUInt32Attribute* channel_attr =
778       msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
779   const StunAddressAttribute* peer_attr =
780       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
781   if (!channel_attr || !peer_attr) {
782     SendBadRequestResponse(msg);
783     return;
784   }
785
786   // Check that channel id is valid.
787   int channel_id = channel_attr->value() >> 16;
788   if (channel_id < kMinChannelNumber || channel_id > kMaxChannelNumber) {
789     SendBadRequestResponse(msg);
790     return;
791   }
792
793   // Check that this channel id isn't bound to another transport address, and
794   // that this transport address isn't bound to another channel id.
795   Channel* channel1 = FindChannel(channel_id);
796   Channel* channel2 = FindChannel(peer_attr->GetAddress());
797   if (channel1 != channel2) {
798     SendBadRequestResponse(msg);
799     return;
800   }
801
802   // Add or refresh this channel.
803   if (!channel1) {
804     channel1 = new Channel(thread_, channel_id, peer_attr->GetAddress());
805     channel1->SignalDestroyed.connect(this,
806         &TurnServer::Allocation::OnChannelDestroyed);
807     channels_.push_back(channel1);
808   } else {
809     channel1->Refresh();
810   }
811
812   // Channel binds also refresh permissions.
813   AddPermission(peer_attr->GetAddress().ipaddr());
814
815   LOG_J(LS_INFO, this) << "Bound channel, id=" << channel_id
816                        << ", peer=" << peer_attr->GetAddress();
817
818   // Send a success response.
819   TurnMessage response;
820   InitResponse(msg, &response);
821   SendResponse(&response);
822 }
823
824 void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
825   // Extract the channel number from the data.
826   uint16 channel_id = talk_base::GetBE16(data);
827   Channel* channel = FindChannel(channel_id);
828   if (channel) {
829     // Send the data to the peer address.
830     SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
831                  size - TURN_CHANNEL_HEADER_SIZE, channel->peer());
832   } else {
833     LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id="
834                             << channel_id;
835   }
836 }
837
838 void TurnServer::Allocation::OnExternalPacket(
839     talk_base::AsyncPacketSocket* socket,
840     const char* data, size_t size,
841     const talk_base::SocketAddress& addr,
842     const talk_base::PacketTime& packet_time) {
843   ASSERT(external_socket_.get() == socket);
844   Channel* channel = FindChannel(addr);
845   if (channel) {
846     // There is a channel bound to this address. Send as a channel message.
847     talk_base::ByteBuffer buf;
848     buf.WriteUInt16(channel->id());
849     buf.WriteUInt16(static_cast<uint16>(size));
850     buf.WriteBytes(data, size);
851     server_->Send(&conn_, buf);
852   } else if (HasPermission(addr.ipaddr())) {
853     // No channel, but a permission exists. Send as a data indication.
854     TurnMessage msg;
855     msg.SetType(TURN_DATA_INDICATION);
856     msg.SetTransactionID(
857         talk_base::CreateRandomString(kStunTransactionIdLength));
858     VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
859         STUN_ATTR_XOR_PEER_ADDRESS, addr)));
860     VERIFY(msg.AddAttribute(new StunByteStringAttribute(
861         STUN_ATTR_DATA, data, size)));
862     server_->SendStun(&conn_, &msg);
863   } else {
864     LOG_J(LS_WARNING, this) << "Received external packet without permission, "
865                             << "peer=" << addr;
866   }
867 }
868
869 int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
870   // Return the smaller of our default lifetime and the requested lifetime.
871   uint32 lifetime = kDefaultAllocationTimeout / 1000;  // convert to seconds
872   const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME);
873   if (lifetime_attr && lifetime_attr->value() < lifetime) {
874     lifetime = lifetime_attr->value();
875   }
876   return lifetime;
877 }
878
879 bool TurnServer::Allocation::HasPermission(const talk_base::IPAddress& addr) {
880   return (FindPermission(addr) != NULL);
881 }
882
883 void TurnServer::Allocation::AddPermission(const talk_base::IPAddress& addr) {
884   Permission* perm = FindPermission(addr);
885   if (!perm) {
886     perm = new Permission(thread_, addr);
887     perm->SignalDestroyed.connect(
888         this, &TurnServer::Allocation::OnPermissionDestroyed);
889     perms_.push_back(perm);
890   } else {
891     perm->Refresh();
892   }
893 }
894
895 TurnServer::Permission* TurnServer::Allocation::FindPermission(
896     const talk_base::IPAddress& addr) const {
897   for (PermissionList::const_iterator it = perms_.begin();
898        it != perms_.end(); ++it) {
899     if ((*it)->peer() == addr)
900       return *it;
901   }
902   return NULL;
903 }
904
905 TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
906   for (ChannelList::const_iterator it = channels_.begin();
907        it != channels_.end(); ++it) {
908     if ((*it)->id() == channel_id)
909       return *it;
910   }
911   return NULL;
912 }
913
914 TurnServer::Channel* TurnServer::Allocation::FindChannel(
915     const talk_base::SocketAddress& addr) const {
916   for (ChannelList::const_iterator it = channels_.begin();
917        it != channels_.end(); ++it) {
918     if ((*it)->peer() == addr)
919       return *it;
920   }
921   return NULL;
922 }
923
924 void TurnServer::Allocation::SendResponse(TurnMessage* msg) {
925   // Success responses always have M-I.
926   msg->AddMessageIntegrity(key_);
927   server_->SendStun(&conn_, msg);
928 }
929
930 void TurnServer::Allocation::SendBadRequestResponse(const TurnMessage* req) {
931   SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
932 }
933
934 void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code,
935                                        const std::string& reason) {
936   server_->SendErrorResponse(&conn_, req, code, reason);
937 }
938
939 void TurnServer::Allocation::SendExternal(const void* data, size_t size,
940                                   const talk_base::SocketAddress& peer) {
941   talk_base::PacketOptions options;
942   external_socket_->SendTo(data, size, peer, options);
943 }
944
945 void TurnServer::Allocation::OnMessage(talk_base::Message* msg) {
946   ASSERT(msg->message_id == MSG_TIMEOUT);
947   SignalDestroyed(this);
948   delete this;
949 }
950
951 void TurnServer::Allocation::OnPermissionDestroyed(Permission* perm) {
952   PermissionList::iterator it = std::find(perms_.begin(), perms_.end(), perm);
953   ASSERT(it != perms_.end());
954   perms_.erase(it);
955 }
956
957 void TurnServer::Allocation::OnChannelDestroyed(Channel* channel) {
958   ChannelList::iterator it =
959       std::find(channels_.begin(), channels_.end(), channel);
960   ASSERT(it != channels_.end());
961   channels_.erase(it);
962 }
963
964 TurnServer::Permission::Permission(talk_base::Thread* thread,
965                                    const talk_base::IPAddress& peer)
966     : thread_(thread), peer_(peer) {
967   Refresh();
968 }
969
970 TurnServer::Permission::~Permission() {
971   thread_->Clear(this, MSG_TIMEOUT);
972 }
973
974 void TurnServer::Permission::Refresh() {
975   thread_->Clear(this, MSG_TIMEOUT);
976   thread_->PostDelayed(kPermissionTimeout, this, MSG_TIMEOUT);
977 }
978
979 void TurnServer::Permission::OnMessage(talk_base::Message* msg) {
980   ASSERT(msg->message_id == MSG_TIMEOUT);
981   SignalDestroyed(this);
982   delete this;
983 }
984
985 TurnServer::Channel::Channel(talk_base::Thread* thread, int id,
986                              const talk_base::SocketAddress& peer)
987     : thread_(thread), id_(id), peer_(peer) {
988   Refresh();
989 }
990
991 TurnServer::Channel::~Channel() {
992   thread_->Clear(this, MSG_TIMEOUT);
993 }
994
995 void TurnServer::Channel::Refresh() {
996   thread_->Clear(this, MSG_TIMEOUT);
997   thread_->PostDelayed(kChannelTimeout, this, MSG_TIMEOUT);
998 }
999
1000 void TurnServer::Channel::OnMessage(talk_base::Message* msg) {
1001   ASSERT(msg->message_id == MSG_TIMEOUT);
1002   SignalDestroyed(this);
1003   delete this;
1004 }
1005
1006 }  // namespace cricket