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