3 * Copyright 2012, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #include "webrtc/p2p/base/turnserver.h"
30 #include "webrtc/p2p/base/asyncstuntcpsocket.h"
31 #include "webrtc/p2p/base/common.h"
32 #include "webrtc/p2p/base/packetsocketfactory.h"
33 #include "webrtc/p2p/base/stun.h"
34 #include "webrtc/base/bytebuffer.h"
35 #include "webrtc/base/helpers.h"
36 #include "webrtc/base/logging.h"
37 #include "webrtc/base/messagedigest.h"
38 #include "webrtc/base/socketadapters.h"
39 #include "webrtc/base/stringencode.h"
40 #include "webrtc/base/thread.h"
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
51 static const int kMinChannelNumber = 0x4000;
52 static const int kMaxChannelNumber = 0x7FFF;
54 static const size_t kNonceKeySize = 16;
55 static const size_t kNonceSize = 40;
57 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
59 // TODO(mallinath) - Move these to a common place.
60 inline bool IsTurnChannelData(uint16 msg_type) {
61 // The first two bits of a channel data message are 0b01.
62 return ((msg_type & 0xC000) == 0x4000);
65 // IDs used for posted messages for TurnServer::Allocation.
67 MSG_ALLOCATION_TIMEOUT,
70 // Encapsulates a TURN allocation.
71 // The object is created when an allocation request is received, and then
72 // handles TURN messages (via HandleTurnMessage) and channel data messages
73 // (via HandleChannelData) for this allocation when received by the server.
74 // The object self-deletes and informs the server if its lifetime timer expires.
75 class TurnServer::Allocation : public rtc::MessageHandler,
76 public sigslot::has_slots<> {
78 Allocation(TurnServer* server_,
79 rtc::Thread* thread, const Connection& conn,
80 rtc::AsyncPacketSocket* server_socket,
81 const std::string& key);
82 virtual ~Allocation();
84 Connection* conn() { return &conn_; }
85 const std::string& key() const { return key_; }
86 const std::string& transaction_id() const { return transaction_id_; }
87 const std::string& username() const { return username_; }
88 const std::string& last_nonce() const { return last_nonce_; }
89 void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
91 std::string ToString() const;
93 void HandleTurnMessage(const TurnMessage* msg);
94 void HandleChannelData(const char* data, size_t size);
96 sigslot::signal1<Allocation*> SignalDestroyed;
99 typedef std::list<Permission*> PermissionList;
100 typedef std::list<Channel*> ChannelList;
102 void HandleAllocateRequest(const TurnMessage* msg);
103 void HandleRefreshRequest(const TurnMessage* msg);
104 void HandleSendIndication(const TurnMessage* msg);
105 void HandleCreatePermissionRequest(const TurnMessage* msg);
106 void HandleChannelBindRequest(const TurnMessage* msg);
108 void OnExternalPacket(rtc::AsyncPacketSocket* socket,
109 const char* data, size_t size,
110 const rtc::SocketAddress& addr,
111 const rtc::PacketTime& packet_time);
113 static int ComputeLifetime(const TurnMessage* msg);
114 bool HasPermission(const rtc::IPAddress& addr);
115 void AddPermission(const rtc::IPAddress& addr);
116 Permission* FindPermission(const rtc::IPAddress& addr) const;
117 Channel* FindChannel(int channel_id) const;
118 Channel* FindChannel(const rtc::SocketAddress& addr) const;
120 void SendResponse(TurnMessage* msg);
121 void SendBadRequestResponse(const TurnMessage* req);
122 void SendErrorResponse(const TurnMessage* req, int code,
123 const std::string& reason);
124 void SendExternal(const void* data, size_t size,
125 const rtc::SocketAddress& peer);
127 void OnPermissionDestroyed(Permission* perm);
128 void OnChannelDestroyed(Channel* channel);
129 virtual void OnMessage(rtc::Message* msg);
132 rtc::Thread* thread_;
134 rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
136 std::string transaction_id_;
137 std::string username_;
138 std::string last_nonce_;
139 PermissionList perms_;
140 ChannelList channels_;
143 // Encapsulates a TURN permission.
144 // The object is created when a create permission request is received by an
145 // allocation, and self-deletes when its lifetime timer expires.
146 class TurnServer::Permission : public rtc::MessageHandler {
148 Permission(rtc::Thread* thread, const rtc::IPAddress& peer);
151 const rtc::IPAddress& peer() const { return peer_; }
154 sigslot::signal1<Permission*> SignalDestroyed;
157 virtual void OnMessage(rtc::Message* msg);
159 rtc::Thread* thread_;
160 rtc::IPAddress peer_;
163 // Encapsulates a TURN channel binding.
164 // The object is created when a channel bind request is received by an
165 // allocation, and self-deletes when its lifetime timer expires.
166 class TurnServer::Channel : public rtc::MessageHandler {
168 Channel(rtc::Thread* thread, int id,
169 const rtc::SocketAddress& peer);
172 int id() const { return id_; }
173 const rtc::SocketAddress& peer() const { return peer_; }
176 sigslot::signal1<Channel*> SignalDestroyed;
179 virtual void OnMessage(rtc::Message* msg);
181 rtc::Thread* thread_;
183 rtc::SocketAddress peer_;
186 static bool InitResponse(const StunMessage* req, StunMessage* resp) {
187 int resp_type = (req) ? GetStunSuccessResponseType(req->type()) : -1;
190 resp->SetType(resp_type);
191 resp->SetTransactionID(req->transaction_id());
195 static bool InitErrorResponse(const StunMessage* req, int code,
196 const std::string& reason, StunMessage* resp) {
197 int resp_type = (req) ? GetStunErrorResponseType(req->type()) : -1;
200 resp->SetType(resp_type);
201 resp->SetTransactionID(req->transaction_id());
202 VERIFY(resp->AddAttribute(new cricket::StunErrorCodeAttribute(
203 STUN_ATTR_ERROR_CODE, code, reason)));
207 TurnServer::TurnServer(rtc::Thread* thread)
209 nonce_key_(rtc::CreateRandomString(kNonceKeySize)),
211 redirect_hook_(NULL),
212 enable_otu_nonce_(false) {
215 TurnServer::~TurnServer() {
216 for (AllocationMap::iterator it = allocations_.begin();
217 it != allocations_.end(); ++it) {
221 for (InternalSocketMap::iterator it = server_sockets_.begin();
222 it != server_sockets_.end(); ++it) {
223 rtc::AsyncPacketSocket* socket = it->first;
227 for (ServerSocketMap::iterator it = server_listen_sockets_.begin();
228 it != server_listen_sockets_.end(); ++it) {
229 rtc::AsyncSocket* socket = it->first;
234 void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
235 ProtocolType proto) {
236 ASSERT(server_sockets_.end() == server_sockets_.find(socket));
237 server_sockets_[socket] = proto;
238 socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket);
241 void TurnServer::AddInternalServerSocket(rtc::AsyncSocket* socket,
242 ProtocolType proto) {
243 ASSERT(server_listen_sockets_.end() ==
244 server_listen_sockets_.find(socket));
245 server_listen_sockets_[socket] = proto;
246 socket->SignalReadEvent.connect(this, &TurnServer::OnNewInternalConnection);
249 void TurnServer::SetExternalSocketFactory(
250 rtc::PacketSocketFactory* factory,
251 const rtc::SocketAddress& external_addr) {
252 external_socket_factory_.reset(factory);
253 external_addr_ = external_addr;
256 void TurnServer::OnNewInternalConnection(rtc::AsyncSocket* socket) {
257 ASSERT(server_listen_sockets_.find(socket) != server_listen_sockets_.end());
258 AcceptConnection(socket);
261 void TurnServer::AcceptConnection(rtc::AsyncSocket* server_socket) {
262 // Check if someone is trying to connect to us.
263 rtc::SocketAddress accept_addr;
264 rtc::AsyncSocket* accepted_socket = server_socket->Accept(&accept_addr);
265 if (accepted_socket != NULL) {
266 ProtocolType proto = server_listen_sockets_[server_socket];
267 cricket::AsyncStunTCPSocket* tcp_socket =
268 new cricket::AsyncStunTCPSocket(accepted_socket, false);
270 tcp_socket->SignalClose.connect(this, &TurnServer::OnInternalSocketClose);
271 // Finally add the socket so it can start communicating with the client.
272 AddInternalSocket(tcp_socket, proto);
276 void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
278 DestroyInternalSocket(socket);
281 void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
282 const char* data, size_t size,
283 const rtc::SocketAddress& addr,
284 const rtc::PacketTime& packet_time) {
285 // Fail if the packet is too small to even contain a channel header.
286 if (size < TURN_CHANNEL_HEADER_SIZE) {
289 InternalSocketMap::iterator iter = server_sockets_.find(socket);
290 ASSERT(iter != server_sockets_.end());
291 Connection conn(addr, iter->second, socket);
292 uint16 msg_type = rtc::GetBE16(data);
293 if (!IsTurnChannelData(msg_type)) {
294 // This is a STUN message.
295 HandleStunMessage(&conn, data, size);
297 // This is a channel message; let the allocation handle it.
298 Allocation* allocation = FindAllocation(&conn);
300 allocation->HandleChannelData(data, size);
305 void TurnServer::HandleStunMessage(Connection* conn, const char* data,
308 rtc::ByteBuffer buf(data, size);
309 if (!msg.Read(&buf) || (buf.Length() > 0)) {
310 LOG(LS_WARNING) << "Received invalid STUN message";
314 // If it's a STUN binding request, handle that specially.
315 if (msg.type() == STUN_BINDING_REQUEST) {
316 HandleBindingRequest(conn, &msg);
320 if (redirect_hook_ != NULL && msg.type() == STUN_ALLOCATE_REQUEST) {
321 rtc::SocketAddress address;
322 if (redirect_hook_->ShouldRedirect(conn->src(), &address)) {
323 SendErrorResponseWithAlternateServer(
324 conn, &msg, address);
329 // Look up the key that we'll use to validate the M-I. If we have an
330 // existing allocation, the key will already be cached.
331 Allocation* allocation = FindAllocation(conn);
336 key = allocation->key();
339 // Ensure the message is authorized; only needed for requests.
340 if (IsStunRequestType(msg.type())) {
341 if (!CheckAuthorization(conn, &msg, data, size, key)) {
346 if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) {
347 HandleAllocateRequest(conn, &msg, key);
348 } else if (allocation &&
349 (msg.type() != STUN_ALLOCATE_REQUEST ||
350 msg.transaction_id() == allocation->transaction_id())) {
351 // This is a non-allocate request, or a retransmit of an allocate.
352 // Check that the username matches the previous username used.
353 if (IsStunRequestType(msg.type()) &&
354 msg.GetByteString(STUN_ATTR_USERNAME)->GetString() !=
355 allocation->username()) {
356 SendErrorResponse(conn, &msg, STUN_ERROR_WRONG_CREDENTIALS,
357 STUN_ERROR_REASON_WRONG_CREDENTIALS);
360 allocation->HandleTurnMessage(&msg);
362 // Allocation mismatch.
363 SendErrorResponse(conn, &msg, STUN_ERROR_ALLOCATION_MISMATCH,
364 STUN_ERROR_REASON_ALLOCATION_MISMATCH);
368 bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
369 const StunByteStringAttribute* username_attr =
370 msg->GetByteString(STUN_ATTR_USERNAME);
371 if (!username_attr) {
375 std::string username = username_attr->GetString();
376 return (auth_hook_ != NULL && auth_hook_->GetKey(username, realm_, key));
379 bool TurnServer::CheckAuthorization(Connection* conn,
380 const StunMessage* msg,
381 const char* data, size_t size,
382 const std::string& key) {
384 ASSERT(IsStunRequestType(msg->type()));
385 const StunByteStringAttribute* mi_attr =
386 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
387 const StunByteStringAttribute* username_attr =
388 msg->GetByteString(STUN_ATTR_USERNAME);
389 const StunByteStringAttribute* realm_attr =
390 msg->GetByteString(STUN_ATTR_REALM);
391 const StunByteStringAttribute* nonce_attr =
392 msg->GetByteString(STUN_ATTR_NONCE);
396 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
397 STUN_ERROR_REASON_UNAUTHORIZED);
401 // Fail if there is M-I but no username, nonce, or realm.
402 if (!username_attr || !realm_attr || !nonce_attr) {
403 SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
404 STUN_ERROR_REASON_BAD_REQUEST);
408 // Fail if bad nonce.
409 if (!ValidateNonce(nonce_attr->GetString())) {
410 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
411 STUN_ERROR_REASON_STALE_NONCE);
415 // Fail if bad username or M-I.
416 // We need |data| and |size| for the call to ValidateMessageIntegrity.
417 if (key.empty() || !StunMessage::ValidateMessageIntegrity(data, size, key)) {
418 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
419 STUN_ERROR_REASON_UNAUTHORIZED);
423 // Fail if one-time-use nonce feature is enabled.
424 Allocation* allocation = FindAllocation(conn);
425 if (enable_otu_nonce_ && allocation &&
426 allocation->last_nonce() == nonce_attr->GetString()) {
427 SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
428 STUN_ERROR_REASON_STALE_NONCE);
433 allocation->set_last_nonce(nonce_attr->GetString());
439 void TurnServer::HandleBindingRequest(Connection* conn,
440 const StunMessage* req) {
441 StunMessage response;
442 InitResponse(req, &response);
444 // Tell the user the address that we received their request from.
445 StunAddressAttribute* mapped_addr_attr;
446 mapped_addr_attr = new StunXorAddressAttribute(
447 STUN_ATTR_XOR_MAPPED_ADDRESS, conn->src());
448 VERIFY(response.AddAttribute(mapped_addr_attr));
450 SendStun(conn, &response);
453 void TurnServer::HandleAllocateRequest(Connection* conn,
454 const TurnMessage* msg,
455 const std::string& key) {
456 // Check the parameters in the request.
457 const StunUInt32Attribute* transport_attr =
458 msg->GetUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
459 if (!transport_attr) {
460 SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
461 STUN_ERROR_REASON_BAD_REQUEST);
465 // Only UDP is supported right now.
466 int proto = transport_attr->value() >> 24;
467 if (proto != IPPROTO_UDP) {
468 SendErrorResponse(conn, msg, STUN_ERROR_UNSUPPORTED_PROTOCOL,
469 STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL);
473 // Create the allocation and let it send the success response.
474 // If the actual socket allocation fails, send an internal error.
475 Allocation* alloc = CreateAllocation(conn, proto, key);
477 alloc->HandleTurnMessage(msg);
479 SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR,
480 "Failed to allocate socket");
484 std::string TurnServer::GenerateNonce() const {
485 // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
486 uint32 now = rtc::Time();
487 std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
488 std::string nonce = rtc::hex_encode(input.c_str(), input.size());
489 nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input);
490 ASSERT(nonce.size() == kNonceSize);
494 bool TurnServer::ValidateNonce(const std::string& nonce) const {
496 if (nonce.size() != kNonceSize) {
500 // Decode the timestamp.
502 char* p = reinterpret_cast<char*>(&then);
503 size_t len = rtc::hex_decode(p, sizeof(then),
504 nonce.substr(0, sizeof(then) * 2));
505 if (len != sizeof(then)) {
510 if (nonce.substr(sizeof(then) * 2) != rtc::ComputeHmac(
511 rtc::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) {
515 // Validate the timestamp.
516 return rtc::TimeSince(then) < kNonceTimeout;
519 TurnServer::Allocation* TurnServer::FindAllocation(Connection* conn) {
520 AllocationMap::const_iterator it = allocations_.find(*conn);
521 return (it != allocations_.end()) ? it->second : NULL;
524 TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
526 const std::string& key) {
527 rtc::AsyncPacketSocket* external_socket = (external_socket_factory_) ?
528 external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0) : NULL;
529 if (!external_socket) {
533 // The Allocation takes ownership of the socket.
534 Allocation* allocation = new Allocation(this,
535 thread_, *conn, external_socket, key);
536 allocation->SignalDestroyed.connect(this, &TurnServer::OnAllocationDestroyed);
537 allocations_[*conn] = allocation;
541 void TurnServer::SendErrorResponse(Connection* conn,
542 const StunMessage* req,
543 int code, const std::string& reason) {
545 InitErrorResponse(req, code, reason, &resp);
546 LOG(LS_INFO) << "Sending error response, type=" << resp.type()
547 << ", code=" << code << ", reason=" << reason;
548 SendStun(conn, &resp);
551 void TurnServer::SendErrorResponseWithRealmAndNonce(
552 Connection* conn, const StunMessage* msg,
553 int code, const std::string& reason) {
555 InitErrorResponse(msg, code, reason, &resp);
556 VERIFY(resp.AddAttribute(new StunByteStringAttribute(
557 STUN_ATTR_NONCE, GenerateNonce())));
558 VERIFY(resp.AddAttribute(new StunByteStringAttribute(
559 STUN_ATTR_REALM, realm_)));
560 SendStun(conn, &resp);
563 void TurnServer::SendErrorResponseWithAlternateServer(
564 Connection* conn, const StunMessage* msg,
565 const rtc::SocketAddress& addr) {
567 InitErrorResponse(msg, STUN_ERROR_TRY_ALTERNATE,
568 STUN_ERROR_REASON_TRY_ALTERNATE_SERVER, &resp);
569 VERIFY(resp.AddAttribute(new StunAddressAttribute(
570 STUN_ATTR_ALTERNATE_SERVER, addr)));
571 SendStun(conn, &resp);
574 void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
576 // Add a SOFTWARE attribute if one is set.
577 if (!software_.empty()) {
578 VERIFY(msg->AddAttribute(
579 new StunByteStringAttribute(STUN_ATTR_SOFTWARE, software_)));
585 void TurnServer::Send(Connection* conn,
586 const rtc::ByteBuffer& buf) {
587 rtc::PacketOptions options;
588 conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
591 void TurnServer::OnAllocationDestroyed(Allocation* allocation) {
592 // Removing the internal socket if the connection is not udp.
593 rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
594 InternalSocketMap::iterator iter = server_sockets_.find(socket);
595 ASSERT(iter != server_sockets_.end());
596 // Skip if the socket serving this allocation is UDP, as this will be shared
597 // by all allocations.
598 if (iter->second != cricket::PROTO_UDP) {
599 DestroyInternalSocket(socket);
602 AllocationMap::iterator it = allocations_.find(*(allocation->conn()));
603 if (it != allocations_.end())
604 allocations_.erase(it);
607 void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
608 InternalSocketMap::iterator iter = server_sockets_.find(socket);
609 if (iter != server_sockets_.end()) {
610 rtc::AsyncPacketSocket* socket = iter->first;
611 // We must destroy the socket async to avoid invalidating the sigslot
612 // callback list iterator inside a sigslot callback.
613 rtc::Thread::Current()->Dispose(socket);
614 server_sockets_.erase(iter);
618 TurnServer::Connection::Connection(const rtc::SocketAddress& src,
620 rtc::AsyncPacketSocket* socket)
622 dst_(socket->GetRemoteAddress()),
627 bool TurnServer::Connection::operator==(const Connection& c) const {
628 return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
631 bool TurnServer::Connection::operator<(const Connection& c) const {
632 return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_;
635 std::string TurnServer::Connection::ToString() const {
636 const char* const kProtos[] = {
637 "unknown", "udp", "tcp", "ssltcp"
639 std::ostringstream ost;
640 ost << src_.ToString() << "-" << dst_.ToString() << ":"<< kProtos[proto_];
644 TurnServer::Allocation::Allocation(TurnServer* server,
646 const Connection& conn,
647 rtc::AsyncPacketSocket* socket,
648 const std::string& key)
652 external_socket_(socket),
654 external_socket_->SignalReadPacket.connect(
655 this, &TurnServer::Allocation::OnExternalPacket);
658 TurnServer::Allocation::~Allocation() {
659 for (ChannelList::iterator it = channels_.begin();
660 it != channels_.end(); ++it) {
663 for (PermissionList::iterator it = perms_.begin();
664 it != perms_.end(); ++it) {
667 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
668 LOG_J(LS_INFO, this) << "Allocation destroyed";
671 std::string TurnServer::Allocation::ToString() const {
672 std::ostringstream ost;
673 ost << "Alloc[" << conn_.ToString() << "]";
677 void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
679 switch (msg->type()) {
680 case STUN_ALLOCATE_REQUEST:
681 HandleAllocateRequest(msg);
683 case TURN_REFRESH_REQUEST:
684 HandleRefreshRequest(msg);
686 case TURN_SEND_INDICATION:
687 HandleSendIndication(msg);
689 case TURN_CREATE_PERMISSION_REQUEST:
690 HandleCreatePermissionRequest(msg);
692 case TURN_CHANNEL_BIND_REQUEST:
693 HandleChannelBindRequest(msg);
696 // Not sure what to do with this, just eat it.
697 LOG_J(LS_WARNING, this) << "Invalid TURN message type received: "
702 void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
703 // Copy the important info from the allocate request.
704 transaction_id_ = msg->transaction_id();
705 const StunByteStringAttribute* username_attr =
706 msg->GetByteString(STUN_ATTR_USERNAME);
707 ASSERT(username_attr != NULL);
708 username_ = username_attr->GetString();
710 // Figure out the lifetime and start the allocation timer.
711 int lifetime_secs = ComputeLifetime(msg);
712 thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
714 LOG_J(LS_INFO, this) << "Created allocation, lifetime=" << lifetime_secs;
716 // We've already validated all the important bits; just send a response here.
717 TurnMessage response;
718 InitResponse(msg, &response);
720 StunAddressAttribute* mapped_addr_attr =
721 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, conn_.src());
722 StunAddressAttribute* relayed_addr_attr =
723 new StunXorAddressAttribute(STUN_ATTR_XOR_RELAYED_ADDRESS,
724 external_socket_->GetLocalAddress());
725 StunUInt32Attribute* lifetime_attr =
726 new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
727 VERIFY(response.AddAttribute(mapped_addr_attr));
728 VERIFY(response.AddAttribute(relayed_addr_attr));
729 VERIFY(response.AddAttribute(lifetime_attr));
731 SendResponse(&response);
734 void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
735 // Figure out the new lifetime.
736 int lifetime_secs = ComputeLifetime(msg);
738 // Reset the expiration timer.
739 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
740 thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT);
742 LOG_J(LS_INFO, this) << "Refreshed allocation, lifetime=" << lifetime_secs;
744 // Send a success response with a LIFETIME attribute.
745 TurnMessage response;
746 InitResponse(msg, &response);
748 StunUInt32Attribute* lifetime_attr =
749 new StunUInt32Attribute(STUN_ATTR_LIFETIME, lifetime_secs);
750 VERIFY(response.AddAttribute(lifetime_attr));
752 SendResponse(&response);
755 void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
756 // Check mandatory attributes.
757 const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
758 const StunAddressAttribute* peer_attr =
759 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
760 if (!data_attr || !peer_attr) {
761 LOG_J(LS_WARNING, this) << "Received invalid send indication";
765 // If a permission exists, send the data on to the peer.
766 if (HasPermission(peer_attr->GetAddress().ipaddr())) {
767 SendExternal(data_attr->bytes(), data_attr->length(),
768 peer_attr->GetAddress());
770 LOG_J(LS_WARNING, this) << "Received send indication without permission"
771 << "peer=" << peer_attr->GetAddress();
775 void TurnServer::Allocation::HandleCreatePermissionRequest(
776 const TurnMessage* msg) {
777 // Check mandatory attributes.
778 const StunAddressAttribute* peer_attr =
779 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
781 SendBadRequestResponse(msg);
785 // Add this permission.
786 AddPermission(peer_attr->GetAddress().ipaddr());
788 LOG_J(LS_INFO, this) << "Created permission, peer="
789 << peer_attr->GetAddress();
791 // Send a success response.
792 TurnMessage response;
793 InitResponse(msg, &response);
794 SendResponse(&response);
797 void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
798 // Check mandatory attributes.
799 const StunUInt32Attribute* channel_attr =
800 msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
801 const StunAddressAttribute* peer_attr =
802 msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
803 if (!channel_attr || !peer_attr) {
804 SendBadRequestResponse(msg);
808 // Check that channel id is valid.
809 int channel_id = channel_attr->value() >> 16;
810 if (channel_id < kMinChannelNumber || channel_id > kMaxChannelNumber) {
811 SendBadRequestResponse(msg);
815 // Check that this channel id isn't bound to another transport address, and
816 // that this transport address isn't bound to another channel id.
817 Channel* channel1 = FindChannel(channel_id);
818 Channel* channel2 = FindChannel(peer_attr->GetAddress());
819 if (channel1 != channel2) {
820 SendBadRequestResponse(msg);
824 // Add or refresh this channel.
826 channel1 = new Channel(thread_, channel_id, peer_attr->GetAddress());
827 channel1->SignalDestroyed.connect(this,
828 &TurnServer::Allocation::OnChannelDestroyed);
829 channels_.push_back(channel1);
834 // Channel binds also refresh permissions.
835 AddPermission(peer_attr->GetAddress().ipaddr());
837 LOG_J(LS_INFO, this) << "Bound channel, id=" << channel_id
838 << ", peer=" << peer_attr->GetAddress();
840 // Send a success response.
841 TurnMessage response;
842 InitResponse(msg, &response);
843 SendResponse(&response);
846 void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
847 // Extract the channel number from the data.
848 uint16 channel_id = rtc::GetBE16(data);
849 Channel* channel = FindChannel(channel_id);
851 // Send the data to the peer address.
852 SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
853 size - TURN_CHANNEL_HEADER_SIZE, channel->peer());
855 LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id="
860 void TurnServer::Allocation::OnExternalPacket(
861 rtc::AsyncPacketSocket* socket,
862 const char* data, size_t size,
863 const rtc::SocketAddress& addr,
864 const rtc::PacketTime& packet_time) {
865 ASSERT(external_socket_.get() == socket);
866 Channel* channel = FindChannel(addr);
868 // There is a channel bound to this address. Send as a channel message.
870 buf.WriteUInt16(channel->id());
871 buf.WriteUInt16(static_cast<uint16>(size));
872 buf.WriteBytes(data, size);
873 server_->Send(&conn_, buf);
874 } else if (HasPermission(addr.ipaddr())) {
875 // No channel, but a permission exists. Send as a data indication.
877 msg.SetType(TURN_DATA_INDICATION);
878 msg.SetTransactionID(
879 rtc::CreateRandomString(kStunTransactionIdLength));
880 VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
881 STUN_ATTR_XOR_PEER_ADDRESS, addr)));
882 VERIFY(msg.AddAttribute(new StunByteStringAttribute(
883 STUN_ATTR_DATA, data, size)));
884 server_->SendStun(&conn_, &msg);
886 LOG_J(LS_WARNING, this) << "Received external packet without permission, "
891 int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
892 // Return the smaller of our default lifetime and the requested lifetime.
893 uint32 lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds
894 const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME);
895 if (lifetime_attr && lifetime_attr->value() < lifetime) {
896 lifetime = lifetime_attr->value();
901 bool TurnServer::Allocation::HasPermission(const rtc::IPAddress& addr) {
902 return (FindPermission(addr) != NULL);
905 void TurnServer::Allocation::AddPermission(const rtc::IPAddress& addr) {
906 Permission* perm = FindPermission(addr);
908 perm = new Permission(thread_, addr);
909 perm->SignalDestroyed.connect(
910 this, &TurnServer::Allocation::OnPermissionDestroyed);
911 perms_.push_back(perm);
917 TurnServer::Permission* TurnServer::Allocation::FindPermission(
918 const rtc::IPAddress& addr) const {
919 for (PermissionList::const_iterator it = perms_.begin();
920 it != perms_.end(); ++it) {
921 if ((*it)->peer() == addr)
927 TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
928 for (ChannelList::const_iterator it = channels_.begin();
929 it != channels_.end(); ++it) {
930 if ((*it)->id() == channel_id)
936 TurnServer::Channel* TurnServer::Allocation::FindChannel(
937 const rtc::SocketAddress& addr) const {
938 for (ChannelList::const_iterator it = channels_.begin();
939 it != channels_.end(); ++it) {
940 if ((*it)->peer() == addr)
946 void TurnServer::Allocation::SendResponse(TurnMessage* msg) {
947 // Success responses always have M-I.
948 msg->AddMessageIntegrity(key_);
949 server_->SendStun(&conn_, msg);
952 void TurnServer::Allocation::SendBadRequestResponse(const TurnMessage* req) {
953 SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
956 void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code,
957 const std::string& reason) {
958 server_->SendErrorResponse(&conn_, req, code, reason);
961 void TurnServer::Allocation::SendExternal(const void* data, size_t size,
962 const rtc::SocketAddress& peer) {
963 rtc::PacketOptions options;
964 external_socket_->SendTo(data, size, peer, options);
967 void TurnServer::Allocation::OnMessage(rtc::Message* msg) {
968 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
969 SignalDestroyed(this);
973 void TurnServer::Allocation::OnPermissionDestroyed(Permission* perm) {
974 PermissionList::iterator it = std::find(perms_.begin(), perms_.end(), perm);
975 ASSERT(it != perms_.end());
979 void TurnServer::Allocation::OnChannelDestroyed(Channel* channel) {
980 ChannelList::iterator it =
981 std::find(channels_.begin(), channels_.end(), channel);
982 ASSERT(it != channels_.end());
986 TurnServer::Permission::Permission(rtc::Thread* thread,
987 const rtc::IPAddress& peer)
988 : thread_(thread), peer_(peer) {
992 TurnServer::Permission::~Permission() {
993 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
996 void TurnServer::Permission::Refresh() {
997 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
998 thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT);
1001 void TurnServer::Permission::OnMessage(rtc::Message* msg) {
1002 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
1003 SignalDestroyed(this);
1007 TurnServer::Channel::Channel(rtc::Thread* thread, int id,
1008 const rtc::SocketAddress& peer)
1009 : thread_(thread), id_(id), peer_(peer) {
1013 TurnServer::Channel::~Channel() {
1014 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
1017 void TurnServer::Channel::Refresh() {
1018 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
1019 thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT);
1022 void TurnServer::Channel::OnMessage(rtc::Message* msg) {
1023 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
1024 SignalDestroyed(this);
1028 } // namespace cricket