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