diff options
Diffstat (limited to 'p2p/base/turnserver.cc')
-rw-r--r-- | p2p/base/turnserver.cc | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/p2p/base/turnserver.cc b/p2p/base/turnserver.cc index abc065a..dbcbcd4 100644 --- a/p2p/base/turnserver.cc +++ b/p2p/base/turnserver.cc @@ -62,9 +62,9 @@ inline bool IsTurnChannelData(uint16 msg_type) { return ((msg_type & 0xC000) == 0x4000); } -// IDs used for posted messages. +// IDs used for posted messages for TurnServer::Allocation. enum { - MSG_TIMEOUT, + MSG_ALLOCATION_TIMEOUT, }; // Encapsulates a TURN allocation. @@ -208,6 +208,7 @@ TurnServer::TurnServer(rtc::Thread* thread) : thread_(thread), nonce_key_(rtc::CreateRandomString(kNonceKeySize)), auth_hook_(NULL), + redirect_hook_(NULL), enable_otu_nonce_(false) { } @@ -316,6 +317,15 @@ void TurnServer::HandleStunMessage(Connection* conn, const char* data, return; } + if (redirect_hook_ != NULL && msg.type() == STUN_ALLOCATE_REQUEST) { + rtc::SocketAddress address; + if (redirect_hook_->ShouldRedirect(conn->src(), &address)) { + SendErrorResponseWithAlternateServer( + conn, &msg, address); + return; + } + } + // Look up the key that we'll use to validate the M-I. If we have an // existing allocation, the key will already be cached. Allocation* allocation = FindAllocation(conn); @@ -334,7 +344,6 @@ void TurnServer::HandleStunMessage(Connection* conn, const char* data, } if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) { - // This is a new allocate request. HandleAllocateRequest(conn, &msg, key); } else if (allocation && (msg.type() != STUN_ALLOCATE_REQUEST || @@ -551,6 +560,17 @@ void TurnServer::SendErrorResponseWithRealmAndNonce( SendStun(conn, &resp); } +void TurnServer::SendErrorResponseWithAlternateServer( + Connection* conn, const StunMessage* msg, + const rtc::SocketAddress& addr) { + TurnMessage resp; + InitErrorResponse(msg, STUN_ERROR_TRY_ALTERNATE, + STUN_ERROR_REASON_TRY_ALTERNATE_SERVER, &resp); + VERIFY(resp.AddAttribute(new StunAddressAttribute( + STUN_ATTR_ALTERNATE_SERVER, addr))); + SendStun(conn, &resp); +} + void TurnServer::SendStun(Connection* conn, StunMessage* msg) { rtc::ByteBuffer buf; // Add a SOFTWARE attribute if one is set. @@ -588,7 +608,9 @@ void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) { InternalSocketMap::iterator iter = server_sockets_.find(socket); if (iter != server_sockets_.end()) { rtc::AsyncPacketSocket* socket = iter->first; - delete socket; + // We must destroy the socket async to avoid invalidating the sigslot + // callback list iterator inside a sigslot callback. + rtc::Thread::Current()->Dispose(socket); server_sockets_.erase(iter); } } @@ -642,7 +664,7 @@ TurnServer::Allocation::~Allocation() { it != perms_.end(); ++it) { delete *it; } - thread_->Clear(this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); LOG_J(LS_INFO, this) << "Allocation destroyed"; } @@ -687,7 +709,7 @@ void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) { // Figure out the lifetime and start the allocation timer. int lifetime_secs = ComputeLifetime(msg); - thread_->PostDelayed(lifetime_secs * 1000, this, MSG_TIMEOUT); + thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT); LOG_J(LS_INFO, this) << "Created allocation, lifetime=" << lifetime_secs; @@ -714,8 +736,8 @@ void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) { int lifetime_secs = ComputeLifetime(msg); // Reset the expiration timer. - thread_->Clear(this, MSG_TIMEOUT); - thread_->PostDelayed(lifetime_secs * 1000, this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); + thread_->PostDelayed(lifetime_secs * 1000, this, MSG_ALLOCATION_TIMEOUT); LOG_J(LS_INFO, this) << "Refreshed allocation, lifetime=" << lifetime_secs; @@ -943,7 +965,7 @@ void TurnServer::Allocation::SendExternal(const void* data, size_t size, } void TurnServer::Allocation::OnMessage(rtc::Message* msg) { - ASSERT(msg->message_id == MSG_TIMEOUT); + ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); SignalDestroyed(this); delete this; } @@ -968,16 +990,16 @@ TurnServer::Permission::Permission(rtc::Thread* thread, } TurnServer::Permission::~Permission() { - thread_->Clear(this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); } void TurnServer::Permission::Refresh() { - thread_->Clear(this, MSG_TIMEOUT); - thread_->PostDelayed(kPermissionTimeout, this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); + thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT); } void TurnServer::Permission::OnMessage(rtc::Message* msg) { - ASSERT(msg->message_id == MSG_TIMEOUT); + ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); SignalDestroyed(this); delete this; } @@ -989,16 +1011,16 @@ TurnServer::Channel::Channel(rtc::Thread* thread, int id, } TurnServer::Channel::~Channel() { - thread_->Clear(this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); } void TurnServer::Channel::Refresh() { - thread_->Clear(this, MSG_TIMEOUT); - thread_->PostDelayed(kChannelTimeout, this, MSG_TIMEOUT); + thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); + thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT); } void TurnServer::Channel::OnMessage(rtc::Message* msg) { - ASSERT(msg->message_id == MSG_TIMEOUT); + ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); SignalDestroyed(this); delete this; } |