2 * Copyright 2012 The WebRTC Project Authors. All rights reserved.
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.
11 #include "webrtc/p2p/base/turnserver.h"
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"
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
34 static const int kMinChannelNumber = 0x4000;
35 static const int kMaxChannelNumber = 0x7FFF;
37 static const size_t kNonceKeySize = 16;
38 static const size_t kNonceSize = 40;
40 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
42 // TODO(mallinath) - Move these to a common place.
43 inline bool IsTurnChannelData(uint16 msg_type) {
44 // The first two bits of a channel data message are 0b01.
45 return ((msg_type & 0xC000) == 0x4000);
48 // IDs used for posted messages for TurnServer::Allocation.
50 MSG_ALLOCATION_TIMEOUT,
53 // Encapsulates a TURN allocation.
54 // The object is created when an allocation request is received, and then
55 // handles TURN messages (via HandleTurnMessage) and channel data messages
56 // (via HandleChannelData) for this allocation when received by the server.
57 // The object self-deletes and informs the server if its lifetime timer expires.
58 class TurnServer::Allocation : public rtc::MessageHandler,
59 public sigslot::has_slots<> {
61 Allocation(TurnServer* server_,
62 rtc::Thread* thread, const Connection& conn,
63 rtc::AsyncPacketSocket* server_socket,
64 const std::string& key);
65 virtual ~Allocation();
67 Connection* conn() { return &conn_; }
68 const std::string& key() const { return key_; }
69 const std::string& transaction_id() const { return transaction_id_; }
70 const std::string& username() const { return username_; }
71 const std::string& last_nonce() const { return last_nonce_; }
72 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
74 std::string ToString() const;
76 void HandleTurnMessage(const TurnMessage* msg);
77 void HandleChannelData(const char* data, size_t size);
79 sigslot::signal1<Allocation*> SignalDestroyed;
82 typedef std::list<Permission*> PermissionList;
83 typedef std::list<Channel*> ChannelList;
85 void HandleAllocateRequest(const TurnMessage* msg);
86 void HandleRefreshRequest(const TurnMessage* msg);
87 void HandleSendIndication(const TurnMessage* msg);
88 void HandleCreatePermissionRequest(const TurnMessage* msg);
89 void HandleChannelBindRequest(const TurnMessage* msg);
91 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
92 const char* data, size_t size,
93 const rtc::SocketAddress& addr,
94 const rtc::PacketTime& packet_time);
96 static int ComputeLifetime(const TurnMessage* msg);
97 bool HasPermission(const rtc::IPAddress& addr);
98 void AddPermission(const rtc::IPAddress& addr);
99 Permission* FindPermission(const rtc::IPAddress& addr) const;
100 Channel* FindChannel(int channel_id) const;
101 Channel* FindChannel(const rtc::SocketAddress& addr) const;
103 void SendResponse(TurnMessage* msg);
104 void SendBadRequestResponse(const TurnMessage* req);
105 void SendErrorResponse(const TurnMessage* req, int code,
106 const std::string& reason);
107 void SendExternal(const void* data, size_t size,
108 const rtc::SocketAddress& peer);
110 void OnPermissionDestroyed(Permission* perm);
111 void OnChannelDestroyed(Channel* channel);
112 virtual void OnMessage(rtc::Message* msg);
115 rtc::Thread* thread_;
117 rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
119 std::string transaction_id_;
120 std::string username_;
121 std::string last_nonce_;
122 PermissionList perms_;
123 ChannelList channels_;
126 // Encapsulates a TURN permission.
127 // The object is created when a create permission request is received by an
128 // allocation, and self-deletes when its lifetime timer expires.
129 class TurnServer::Permission : public rtc::MessageHandler {
131 Permission(rtc::Thread* thread, const rtc::IPAddress& peer);
134 const rtc::IPAddress& peer() const { return peer_; }
137 sigslot::signal1<Permission*> SignalDestroyed;
140 virtual void OnMessage(rtc::Message* msg);
142 rtc::Thread* thread_;
143 rtc::IPAddress peer_;
146 // Encapsulates a TURN channel binding.
147 // The object is created when a channel bind request is received by an
148 // allocation, and self-deletes when its lifetime timer expires.
149 class TurnServer::Channel : public rtc::MessageHandler {
151 Channel(rtc::Thread* thread, int id,
152 const rtc::SocketAddress& peer);
155 int id() const { return id_; }
156 const rtc::SocketAddress& peer() const { return peer_; }
159 sigslot::signal1<Channel*> SignalDestroyed;
162 virtual void OnMessage(rtc::Message* msg);
164 rtc::Thread* thread_;
166 rtc::SocketAddress peer_;
169 static bool InitResponse(const StunMessage* req, StunMessage* resp) {
170 int resp_type = (req) ? GetStunSuccessResponseType(req->type()) : -1;
173 resp->SetType(resp_type);
174 resp->SetTransactionID(req->transaction_id());
178 static bool InitErrorResponse(const StunMessage* req, int code,
179 const std::string& reason, StunMessage* resp) {
180 int resp_type = (req) ? GetStunErrorResponseType(req->type()) : -1;
183 resp->SetType(resp_type);
184 resp->SetTransactionID(req->transaction_id());
185 VERIFY(resp->AddAttribute(new cricket::StunErrorCodeAttribute(
186 STUN_ATTR_ERROR_CODE, code, reason)));
190 TurnServer::TurnServer(rtc::Thread* thread)
192 nonce_key_(rtc::CreateRandomString(kNonceKeySize)),
194 redirect_hook_(NULL),
195 enable_otu_nonce_(false) {
198 TurnServer::~TurnServer() {
199 for (AllocationMap::iterator it = allocations_.begin();
200 it != allocations_.end(); ++it) {
204 for (InternalSocketMap::iterator it = server_sockets_.begin();
205 it != server_sockets_.end(); ++it) {
206 rtc::AsyncPacketSocket* socket = it->first;
210 for (ServerSocketMap::iterator it = server_listen_sockets_.begin();
211 it != server_listen_sockets_.end(); ++it) {
212 rtc::AsyncSocket* socket = it->first;
217 void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
218 ProtocolType proto) {
219 ASSERT(server_sockets_.end() == server_sockets_.find(socket));
220 server_sockets_[socket] = proto;
221 socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket);
224 void TurnServer::AddInternalServerSocket(rtc::AsyncSocket* socket,
225 ProtocolType proto) {
226 ASSERT(server_listen_sockets_.end() ==
227 server_listen_sockets_.find(socket));
228 server_listen_sockets_[socket] = proto;
229 socket->SignalReadEvent.connect(this, &TurnServer::OnNewInternalConnection);
232 void TurnServer::SetExternalSocketFactory(
233 rtc::PacketSocketFactory* factory,
234 const rtc::SocketAddress& external_addr) {
235 external_socket_factory_.reset(factory);
236 external_addr_ = external_addr;
239 void TurnServer::OnNewInternalConnection(rtc::AsyncSocket* socket) {
240 ASSERT(server_listen_sockets_.find(socket) != server_listen_sockets_.end());
241 AcceptConnection(socket);
244 void TurnServer::AcceptConnection(rtc::AsyncSocket* server_socket) {
245 // Check if someone is trying to connect to us.
246 rtc::SocketAddress accept_addr;
247 rtc::AsyncSocket* accepted_socket = server_socket->Accept(&accept_addr);
248 if (accepted_socket != NULL) {
249 ProtocolType proto = server_listen_sockets_[server_socket];
250 cricket::AsyncStunTCPSocket* tcp_socket =
251 new cricket::AsyncStunTCPSocket(accepted_socket, false);
253 tcp_socket->SignalClose.connect(this, &TurnServer::OnInternalSocketClose);
254 // Finally add the socket so it can start communicating with the client.
255 AddInternalSocket(tcp_socket, proto);
259 void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
261 DestroyInternalSocket(socket);
264 void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
265 const char* data, size_t size,
266 const rtc::SocketAddress& addr,
267 const rtc::PacketTime& packet_time) {
268 // Fail if the packet is too small to even contain a channel header.
269 if (size < TURN_CHANNEL_HEADER_SIZE) {
272 InternalSocketMap::iterator iter = server_sockets_.find(socket);
273 ASSERT(iter != server_sockets_.end());
274 Connection conn(addr, iter->second, socket);
275 uint16 msg_type = rtc::GetBE16(data);
276 if (!IsTurnChannelData(msg_type)) {
277 // This is a STUN message.
278 HandleStunMessage(&conn, data, size);
280 // This is a channel message; let the allocation handle it.
281 Allocation* allocation = FindAllocation(&conn);
283 allocation->HandleChannelData(data, size);
288 void TurnServer::HandleStunMessage(Connection* conn, const char* data,
291 rtc::ByteBuffer buf(data, size);
292 if (!msg.Read(&buf) || (buf.Length() > 0)) {
293 LOG(LS_WARNING) << "Received invalid STUN message";
297 // If it's a STUN binding request, handle that specially.
298 if (msg.type() == STUN_BINDING_REQUEST) {
299 HandleBindingRequest(conn, &msg);
303 if (redirect_hook_ != NULL && msg.type() == STUN_ALLOCATE_REQUEST) {
304 rtc::SocketAddress address;
305 if (redirect_hook_->ShouldRedirect(conn->src(), &address)) {
306 SendErrorResponseWithAlternateServer(
307 conn, &msg, address);
312 // Look up the key that we'll use to validate the M-I. If we have an
313 // existing allocation, the key will already be cached.
314 Allocation* allocation = FindAllocation(conn);
319 key = allocation->key();
322 // Ensure the message is authorized; only needed for requests.
323 if (IsStunRequestType(msg.type())) {
324 if (!CheckAuthorization(conn, &msg, data, size, key)) {
329 if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) {
330 HandleAllocateRequest(conn, &msg, key);
331 } else if (allocation &&
332 (msg.type() != STUN_ALLOCATE_REQUEST ||
333 msg.transaction_id() == allocation->transaction_id())) {
334 // This is a non-allocate request, or a retransmit of an allocate.
335 // Check that the username matches the previous username used.
336 if (IsStunRequestType(msg.type()) &&
337 msg.GetByteString(STUN_ATTR_USERNAME)->GetString() !=
338 allocation->username()) {
339 SendErrorResponse(conn, &msg, STUN_ERROR_WRONG_CREDENTIALS,
340 STUN_ERROR_REASON_WRONG_CREDENTIALS);
343 allocation->HandleTurnMessage(&msg);
345 // Allocation mismatch.
346 SendErrorResponse(conn, &msg, STUN_ERROR_ALLOCATION_MISMATCH,
347 STUN_ERROR_REASON_ALLOCATION_MISMATCH);
351 bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
352 const StunByteStringAttribute* username_attr =
353 msg->GetByteString(STUN_ATTR_USERNAME);
354 if (!username_attr) {
358 std::string username = username_attr->GetString();
359 return (auth_hook_ != NULL && auth_hook_->GetKey(username, realm_, key));
362 bool TurnServer::CheckAuthorization(Connection* conn,
363 const StunMessage* msg,
364 const char* data, size_t size,
365 const std::string& key) {
367 ASSERT(IsStunRequestType(msg->type()));
368 const StunByteStringAttribute* mi_attr =
369 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
370 const StunByteStringAttribute* username_attr =
371 msg->GetByteString(STUN_ATTR_USERNAME);
372 const StunByteStringAttribute* realm_attr =
373 msg->GetByteString(STUN_ATTR_REALM);
374 const StunByteStringAttribute* nonce_attr =
375 msg->GetByteString(STUN_ATTR_NONCE);
379 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
380 STUN_ERROR_REASON_UNAUTHORIZED);
384 // Fail if there is M-I but no username, nonce, or realm.
385 if (!username_attr || !realm_attr || !nonce_attr) {
386 SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
387 STUN_ERROR_REASON_BAD_REQUEST);
391 // Fail if bad nonce.
392 if (!ValidateNonce(nonce_attr->GetString())) {
393 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
394 STUN_ERROR_REASON_STALE_NONCE);
398 // Fail if bad username or M-I.
399 // We need |data| and |size| for the call to ValidateMessageIntegrity.
400 if (key.empty() || !StunMessage::ValidateMessageIntegrity(data, size, key)) {
401 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
402 STUN_ERROR_REASON_UNAUTHORIZED);
406 // Fail if one-time-use nonce feature is enabled.
407 Allocation* allocation = FindAllocation(conn);
408 if (enable_otu_nonce_ && allocation &&
409 allocation->last_nonce() == nonce_attr->GetString()) {
410 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
411 STUN_ERROR_REASON_STALE_NONCE);
416 allocation->set_last_nonce(nonce_attr->GetString());
422 void TurnServer::HandleBindingRequest(Connection* conn,
423 const StunMessage* req) {
424 StunMessage response;
425 InitResponse(req, &response);
427 // Tell the user the address that we received their request from.
428 StunAddressAttribute* mapped_addr_attr;
429 mapped_addr_attr = new StunXorAddressAttribute(
430 STUN_ATTR_XOR_MAPPED_ADDRESS, conn->src());
431 VERIFY(response.AddAttribute(mapped_addr_attr));
433 SendStun(conn, &response);
436 void TurnServer::HandleAllocateRequest(Connection* conn,
437 const TurnMessage* msg,
438 const std::string& key) {
439 // Check the parameters in the request.
440 const StunUInt32Attribute* transport_attr =
441 msg->GetUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
442 if (!transport_attr) {
443 SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
444 STUN_ERROR_REASON_BAD_REQUEST);
448 // Only UDP is supported right now.
449 int proto = transport_attr->value() >> 24;
450 if (proto != IPPROTO_UDP) {
451 SendErrorResponse(conn, msg, STUN_ERROR_UNSUPPORTED_PROTOCOL,
452 STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL);
456 // Create the allocation and let it send the success response.
457 // If the actual socket allocation fails, send an internal error.
458 Allocation* alloc = CreateAllocation(conn, proto, key);
460 alloc->HandleTurnMessage(msg);
462 SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR,
463 "Failed to allocate socket");
467 std::string TurnServer::GenerateNonce() const {
468 // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
469 uint32 now = rtc::Time();
470 std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
471 std::string nonce = rtc::hex_encode(input.c_str(), input.size());
472 nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input);
473 ASSERT(nonce.size() == kNonceSize);
477 bool TurnServer::ValidateNonce(const std::string& nonce) const {
479 if (nonce.size() != kNonceSize) {
483 // Decode the timestamp.
485 char* p = reinterpret_cast<char*>(&then);
486 size_t len = rtc::hex_decode(p, sizeof(then),
487 nonce.substr(0, sizeof(then) * 2));
488 if (len != sizeof(then)) {
493 if (nonce.substr(sizeof(then) * 2) != rtc::ComputeHmac(
494 rtc::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) {
498 // Validate the timestamp.
499 return rtc::TimeSince(then) < kNonceTimeout;
502 TurnServer::Allocation* TurnServer::FindAllocation(Connection* conn) {
503 AllocationMap::const_iterator it = allocations_.find(*conn);
504 return (it != allocations_.end()) ? it->second : NULL;
507 TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
509 const std::string& key) {
510 rtc::AsyncPacketSocket* external_socket = (external_socket_factory_) ?
511 external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0) : NULL;
512 if (!external_socket) {
516 // The Allocation takes ownership of the socket.
517 Allocation* allocation = new Allocation(this,
518 thread_, *conn, external_socket, key);
519 allocation->SignalDestroyed.connect(this, &TurnServer::OnAllocationDestroyed);
520 allocations_[*conn] = allocation;
524 void TurnServer::SendErrorResponse(Connection* conn,
525 const StunMessage* req,
526 int code, const std::string& reason) {
528 InitErrorResponse(req, code, reason, &resp);
529 LOG(LS_INFO) << "Sending error response, type=" << resp.type()
530 << ", code=" << code << ", reason=" << reason;
531 SendStun(conn, &resp);
534 void TurnServer::SendErrorResponseWithRealmAndNonce(
535 Connection* conn, const StunMessage* msg,
536 int code, const std::string& reason) {
538 InitErrorResponse(msg, code, reason, &resp);
539 VERIFY(resp.AddAttribute(new StunByteStringAttribute(
540 STUN_ATTR_NONCE, GenerateNonce())));
541 VERIFY(resp.AddAttribute(new StunByteStringAttribute(
542 STUN_ATTR_REALM, realm_)));
543 SendStun(conn, &resp);
546 void TurnServer::SendErrorResponseWithAlternateServer(
547 Connection* conn, const StunMessage* msg,
548 const rtc::SocketAddress& addr) {
550 InitErrorResponse(msg, STUN_ERROR_TRY_ALTERNATE,
551 STUN_ERROR_REASON_TRY_ALTERNATE_SERVER, &resp);
552 VERIFY(resp.AddAttribute(new StunAddressAttribute(
553 STUN_ATTR_ALTERNATE_SERVER, addr)));
554 SendStun(conn, &resp);
557 void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
559 // Add a SOFTWARE attribute if one is set.
560 if (!software_.empty()) {
561 VERIFY(msg->AddAttribute(
562 new StunByteStringAttribute(STUN_ATTR_SOFTWARE, software_)));
568 void TurnServer::Send(Connection* conn,
569 const rtc::ByteBuffer& buf) {
570 rtc::PacketOptions options;
571 conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
574 void TurnServer::OnAllocationDestroyed(Allocation* allocation) {
575 // Removing the internal socket if the connection is not udp.
576 rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
577 InternalSocketMap::iterator iter = server_sockets_.find(socket);
578 ASSERT(iter != server_sockets_.end());
579 // Skip if the socket serving this allocation is UDP, as this will be shared
580 // by all allocations.
581 if (iter->second != cricket::PROTO_UDP) {
582 DestroyInternalSocket(socket);
585 AllocationMap::iterator it = allocations_.find(*(allocation->conn()));
586 if (it != allocations_.end())
587 allocations_.erase(it);
590 void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
591 InternalSocketMap::iterator iter = server_sockets_.find(socket);
592 if (iter != server_sockets_.end()) {
593 rtc::AsyncPacketSocket* socket = iter->first;
594 // We must destroy the socket async to avoid invalidating the sigslot
595 // callback list iterator inside a sigslot callback.
596 rtc::Thread::Current()->Dispose(socket);
597 server_sockets_.erase(iter);
601 TurnServer::Connection::Connection(const rtc::SocketAddress& src,
603 rtc::AsyncPacketSocket* socket)
605 dst_(socket->GetRemoteAddress()),
610 bool TurnServer::Connection::operator==(const Connection& c) const {
611 return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
614 bool TurnServer::Connection::operator<(const Connection& c) const {
615 return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_;
618 std::string TurnServer::Connection::ToString() const {
619 const char* const kProtos[] = {
620 "unknown", "udp", "tcp", "ssltcp"
622 std::ostringstream ost;
623 ost << src_.ToString() << "-" << dst_.ToString() << ":"<< kProtos[proto_];
627 TurnServer::Allocation::Allocation(TurnServer* server,
629 const Connection& conn,
630 rtc::AsyncPacketSocket* socket,
631 const std::string& key)
635 external_socket_(socket),
637 external_socket_->SignalReadPacket.connect(
638 this, &TurnServer::Allocation::OnExternalPacket);
641 TurnServer::Allocation::~Allocation() {
642 for (ChannelList::iterator it = channels_.begin();
643 it != channels_.end(); ++it) {
646 for (PermissionList::iterator it = perms_.begin();
647 it != perms_.end(); ++it) {
650 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
651 LOG_J(LS_INFO, this) << "Allocation destroyed";
654 std::string TurnServer::Allocation::ToString() const {
655 std::ostringstream ost;
656 ost << "Alloc[" << conn_.ToString() << "]";
660 void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
662 switch (msg->type()) {
663 case STUN_ALLOCATE_REQUEST:
664 HandleAllocateRequest(msg);
666 case TURN_REFRESH_REQUEST:
667 HandleRefreshRequest(msg);
669 case TURN_SEND_INDICATION:
670 HandleSendIndication(msg);
672 case TURN_CREATE_PERMISSION_REQUEST:
673 HandleCreatePermissionRequest(msg);
675 case TURN_CHANNEL_BIND_REQUEST:
676 HandleChannelBindRequest(msg);
679 // Not sure what to do with this, just eat it.
680 LOG_J(LS_WARNING, this) << "Invalid TURN message type received: "
685 void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
686 // Copy the important info from the allocate request.
687 transaction_id_ = msg->transaction_id();
688 const StunByteStringAttribute* username_attr =
689 msg->GetByteString(STUN_ATTR_USERNAME);
690 ASSERT(username_attr != NULL);
691 username_ = username_attr->GetString();
693 // Figure out the lifetime and start the allocation timer.
694 int lifetime_secs = ComputeLifetime(msg);
695 thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
697 LOG_J(LS_INFO, this) << "Created allocation, lifetime=" << lifetime_secs;
699 // We've already validated all the important bits; just send a response here.
700 TurnMessage response;
701 InitResponse(msg, &response);
703 StunAddressAttribute* mapped_addr_attr =
704 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, conn_.src());
705 StunAddressAttribute* relayed_addr_attr =
706 new StunXorAddressAttribute(STUN_ATTR_XOR_RELAYED_ADDRESS,
707 external_socket_->GetLocalAddress());
708 StunUInt32Attribute* lifetime_attr =
709 new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
710 VERIFY(response.AddAttribute(mapped_addr_attr));
711 VERIFY(response.AddAttribute(relayed_addr_attr));
712 VERIFY(response.AddAttribute(lifetime_attr));
714 SendResponse(&response);
717 void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
718 // Figure out the new lifetime.
719 int lifetime_secs = ComputeLifetime(msg);
721 // Reset the expiration timer.
722 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
723 thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
725 LOG_J(LS_INFO, this) << "Refreshed allocation, lifetime=" << lifetime_secs;
727 // Send a success response with a LIFETIME attribute.
728 TurnMessage response;
729 InitResponse(msg, &response);
731 StunUInt32Attribute* lifetime_attr =
732 new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
733 VERIFY(response.AddAttribute(lifetime_attr));
735 SendResponse(&response);
738 void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
739 // Check mandatory attributes.
740 const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
741 const StunAddressAttribute* peer_attr =
742 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
743 if (!data_attr || !peer_attr) {
744 LOG_J(LS_WARNING, this) << "Received invalid send indication";
748 // If a permission exists, send the data on to the peer.
749 if (HasPermission(peer_attr->GetAddress().ipaddr())) {
750 SendExternal(data_attr->bytes(), data_attr->length(),
751 peer_attr->GetAddress());
753 LOG_J(LS_WARNING, this) << "Received send indication without permission"
754 << "peer=" << peer_attr->GetAddress();
758 void TurnServer::Allocation::HandleCreatePermissionRequest(
759 const TurnMessage* msg) {
760 // Check mandatory attributes.
761 const StunAddressAttribute* peer_attr =
762 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
764 SendBadRequestResponse(msg);
768 // Add this permission.
769 AddPermission(peer_attr->GetAddress().ipaddr());
771 LOG_J(LS_INFO, this) << "Created permission, peer="
772 << peer_attr->GetAddress();
774 // Send a success response.
775 TurnMessage response;
776 InitResponse(msg, &response);
777 SendResponse(&response);
780 void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
781 // Check mandatory attributes.
782 const StunUInt32Attribute* channel_attr =
783 msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
784 const StunAddressAttribute* peer_attr =
785 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
786 if (!channel_attr || !peer_attr) {
787 SendBadRequestResponse(msg);
791 // Check that channel id is valid.
792 int channel_id = channel_attr->value() >> 16;
793 if (channel_id < kMinChannelNumber || channel_id > kMaxChannelNumber) {
794 SendBadRequestResponse(msg);
798 // Check that this channel id isn't bound to another transport address, and
799 // that this transport address isn't bound to another channel id.
800 Channel* channel1 = FindChannel(channel_id);
801 Channel* channel2 = FindChannel(peer_attr->GetAddress());
802 if (channel1 != channel2) {
803 SendBadRequestResponse(msg);
807 // Add or refresh this channel.
809 channel1 = new Channel(thread_, channel_id, peer_attr->GetAddress());
810 channel1->SignalDestroyed.connect(this,
811 &TurnServer::Allocation::OnChannelDestroyed);
812 channels_.push_back(channel1);
817 // Channel binds also refresh permissions.
818 AddPermission(peer_attr->GetAddress().ipaddr());
820 LOG_J(LS_INFO, this) << "Bound channel, id=" << channel_id
821 << ", peer=" << peer_attr->GetAddress();
823 // Send a success response.
824 TurnMessage response;
825 InitResponse(msg, &response);
826 SendResponse(&response);
829 void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
830 // Extract the channel number from the data.
831 uint16 channel_id = rtc::GetBE16(data);
832 Channel* channel = FindChannel(channel_id);
834 // Send the data to the peer address.
835 SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
836 size - TURN_CHANNEL_HEADER_SIZE, channel->peer());
838 LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id="
843 void TurnServer::Allocation::OnExternalPacket(
844 rtc::AsyncPacketSocket* socket,
845 const char* data, size_t size,
846 const rtc::SocketAddress& addr,
847 const rtc::PacketTime& packet_time) {
848 ASSERT(external_socket_.get() == socket);
849 Channel* channel = FindChannel(addr);
851 // There is a channel bound to this address. Send as a channel message.
853 buf.WriteUInt16(channel->id());
854 buf.WriteUInt16(static_cast<uint16>(size));
855 buf.WriteBytes(data, size);
856 server_->Send(&conn_, buf);
857 } else if (HasPermission(addr.ipaddr())) {
858 // No channel, but a permission exists. Send as a data indication.
860 msg.SetType(TURN_DATA_INDICATION);
861 msg.SetTransactionID(
862 rtc::CreateRandomString(kStunTransactionIdLength));
863 VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
864 STUN_ATTR_XOR_PEER_ADDRESS, addr)));
865 VERIFY(msg.AddAttribute(new StunByteStringAttribute(
866 STUN_ATTR_DATA, data, size)));
867 server_->SendStun(&conn_, &msg);
869 LOG_J(LS_WARNING, this) << "Received external packet without permission, "
874 int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
875 // Return the smaller of our default lifetime and the requested lifetime.
876 uint32 lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds
877 const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME);
878 if (lifetime_attr && lifetime_attr->value() < lifetime) {
879 lifetime = lifetime_attr->value();
884 bool TurnServer::Allocation::HasPermission(const rtc::IPAddress& addr) {
885 return (FindPermission(addr) != NULL);
888 void TurnServer::Allocation::AddPermission(const rtc::IPAddress& addr) {
889 Permission* perm = FindPermission(addr);
891 perm = new Permission(thread_, addr);
892 perm->SignalDestroyed.connect(
893 this, &TurnServer::Allocation::OnPermissionDestroyed);
894 perms_.push_back(perm);
900 TurnServer::Permission* TurnServer::Allocation::FindPermission(
901 const rtc::IPAddress& addr) const {
902 for (PermissionList::const_iterator it = perms_.begin();
903 it != perms_.end(); ++it) {
904 if ((*it)->peer() == addr)
910 TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
911 for (ChannelList::const_iterator it = channels_.begin();
912 it != channels_.end(); ++it) {
913 if ((*it)->id() == channel_id)
919 TurnServer::Channel* TurnServer::Allocation::FindChannel(
920 const rtc::SocketAddress& addr) const {
921 for (ChannelList::const_iterator it = channels_.begin();
922 it != channels_.end(); ++it) {
923 if ((*it)->peer() == addr)
929 void TurnServer::Allocation::SendResponse(TurnMessage* msg) {
930 // Success responses always have M-I.
931 msg->AddMessageIntegrity(key_);
932 server_->SendStun(&conn_, msg);
935 void TurnServer::Allocation::SendBadRequestResponse(const TurnMessage* req) {
936 SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
939 void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code,
940 const std::string& reason) {
941 server_->SendErrorResponse(&conn_, req, code, reason);
944 void TurnServer::Allocation::SendExternal(const void* data, size_t size,
945 const rtc::SocketAddress& peer) {
946 rtc::PacketOptions options;
947 external_socket_->SendTo(data, size, peer, options);
950 void TurnServer::Allocation::OnMessage(rtc::Message* msg) {
951 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
952 SignalDestroyed(this);
956 void TurnServer::Allocation::OnPermissionDestroyed(Permission* perm) {
957 PermissionList::iterator it = std::find(perms_.begin(), perms_.end(), perm);
958 ASSERT(it != perms_.end());
962 void TurnServer::Allocation::OnChannelDestroyed(Channel* channel) {
963 ChannelList::iterator it =
964 std::find(channels_.begin(), channels_.end(), channel);
965 ASSERT(it != channels_.end());
969 TurnServer::Permission::Permission(rtc::Thread* thread,
970 const rtc::IPAddress& peer)
971 : thread_(thread), peer_(peer) {
975 TurnServer::Permission::~Permission() {
976 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
979 void TurnServer::Permission::Refresh() {
980 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
981 thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT);
984 void TurnServer::Permission::OnMessage(rtc::Message* msg) {
985 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
986 SignalDestroyed(this);
990 TurnServer::Channel::Channel(rtc::Thread* thread, int id,
991 const rtc::SocketAddress& peer)
992 : thread_(thread), id_(id), peer_(peer) {
996 TurnServer::Channel::~Channel() {
997 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
1000 void TurnServer::Channel::Refresh() {
1001 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
1002 thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT);
1005 void TurnServer::Channel::OnMessage(rtc::Message* msg) {
1006 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
1007 SignalDestroyed(this);
1011 } // namespace cricket