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