release the turn allocation by sending a refresh request with lifetime 0
BUG=406578 Patch originally from philipp.hancke@googlemail.com R=juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/41449004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8087 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
d7de1209ae
commit
fe672e3839
@ -44,7 +44,11 @@ void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
|
|||||||
request->set_origin(origin_);
|
request->set_origin(origin_);
|
||||||
request->Construct();
|
request->Construct();
|
||||||
requests_[request->id()] = request;
|
requests_[request->id()] = request;
|
||||||
thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
|
if (delay > 0) {
|
||||||
|
thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
|
||||||
|
} else {
|
||||||
|
thread_->Send(request, MSG_STUN_SEND, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StunRequestManager::Remove(StunRequest* request) {
|
void StunRequestManager::Remove(StunRequest* request) {
|
||||||
|
@ -78,9 +78,11 @@ class TurnRefreshRequest : public StunRequest {
|
|||||||
virtual void OnResponse(StunMessage* response);
|
virtual void OnResponse(StunMessage* response);
|
||||||
virtual void OnErrorResponse(StunMessage* response);
|
virtual void OnErrorResponse(StunMessage* response);
|
||||||
virtual void OnTimeout();
|
virtual void OnTimeout();
|
||||||
|
void set_lifetime(int lifetime) { lifetime_ = lifetime; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TurnPort* port_;
|
TurnPort* port_;
|
||||||
|
int lifetime_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TurnCreatePermissionRequest : public StunRequest,
|
class TurnCreatePermissionRequest : public StunRequest,
|
||||||
@ -212,6 +214,15 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
|||||||
|
|
||||||
TurnPort::~TurnPort() {
|
TurnPort::~TurnPort() {
|
||||||
// TODO(juberti): Should this even be necessary?
|
// TODO(juberti): Should this even be necessary?
|
||||||
|
|
||||||
|
// release the allocation by sending a refresh with
|
||||||
|
// lifetime 0.
|
||||||
|
if (connected_) {
|
||||||
|
TurnRefreshRequest bye(this);
|
||||||
|
bye.set_lifetime(0);
|
||||||
|
SendRequest(&bye, 0);
|
||||||
|
}
|
||||||
|
|
||||||
while (!entries_.empty()) {
|
while (!entries_.empty()) {
|
||||||
DestroyEntry(entries_.front()->address());
|
DestroyEntry(entries_.front()->address());
|
||||||
}
|
}
|
||||||
@ -352,6 +363,7 @@ void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
|
|||||||
if (!connected_) {
|
if (!connected_) {
|
||||||
OnAllocateError();
|
OnAllocateError();
|
||||||
}
|
}
|
||||||
|
connected_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurnPort::OnAllocateMismatch() {
|
void TurnPort::OnAllocateMismatch() {
|
||||||
@ -1020,13 +1032,19 @@ void TurnAllocateRequest::OnTryAlternate(StunMessage* response, int code) {
|
|||||||
|
|
||||||
TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
|
TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
|
||||||
: StunRequest(new TurnMessage()),
|
: StunRequest(new TurnMessage()),
|
||||||
port_(port) {
|
port_(port),
|
||||||
|
lifetime_(-1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TurnRefreshRequest::Prepare(StunMessage* request) {
|
void TurnRefreshRequest::Prepare(StunMessage* request) {
|
||||||
// Create the request as indicated in RFC 5766, Section 7.1.
|
// Create the request as indicated in RFC 5766, Section 7.1.
|
||||||
// No attributes need to be included.
|
// No attributes need to be included.
|
||||||
request->SetType(TURN_REFRESH_REQUEST);
|
request->SetType(TURN_REFRESH_REQUEST);
|
||||||
|
if (lifetime_ > -1) {
|
||||||
|
VERIFY(request->AddAttribute(new StunUInt32Attribute(
|
||||||
|
STUN_ATTR_LIFETIME, lifetime_)));
|
||||||
|
}
|
||||||
|
|
||||||
port_->AddRequestAuthInfo(request);
|
port_->AddRequestAuthInfo(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,6 +550,10 @@ TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
|
|||||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||||
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
||||||
|
|
||||||
|
// Clear connected_ flag on turnport to suppress the release of
|
||||||
|
// the allocation.
|
||||||
|
turn_port_->OnSocketClose(turn_port_->socket(), 0);
|
||||||
|
|
||||||
// Forces the socket server to assign the same port.
|
// Forces the socket server to assign the same port.
|
||||||
ss_->SetNextPortForTesting(first_addr.port());
|
ss_->SetNextPortForTesting(first_addr.port());
|
||||||
|
|
||||||
@ -575,6 +579,10 @@ TEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
|
|||||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||||
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
||||||
|
|
||||||
|
// Clear connected_ flag on turnport to suppress the release of
|
||||||
|
// the allocation.
|
||||||
|
turn_port_->OnSocketClose(turn_port_->socket(), 0);
|
||||||
|
|
||||||
turn_ready_ = false;
|
turn_ready_ = false;
|
||||||
CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
|
CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
|
||||||
|
|
||||||
@ -599,6 +607,10 @@ TEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
|
|||||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||||
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
||||||
|
|
||||||
|
// Clear connected_ flag on turnport to suppress the release of
|
||||||
|
// the allocation.
|
||||||
|
turn_port_->OnSocketClose(turn_port_->socket(), 0);
|
||||||
|
|
||||||
// Forces the socket server to assign the same port.
|
// Forces the socket server to assign the same port.
|
||||||
ss_->SetNextPortForTesting(first_addr.port());
|
ss_->SetNextPortForTesting(first_addr.port());
|
||||||
|
|
||||||
@ -747,6 +759,29 @@ TEST_F(TurnPortTest, TestOriginHeader) {
|
|||||||
EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
|
EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that a TURN allocation is released when the port is closed.
|
||||||
|
TEST_F(TurnPortTest, TestTurnReleaseAllocation) {
|
||||||
|
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
|
||||||
|
turn_port_->PrepareAddress();
|
||||||
|
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||||
|
|
||||||
|
ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
|
||||||
|
turn_port_.reset();
|
||||||
|
EXPECT_EQ_WAIT(0U, turn_server_.server()->allocations().size(), kTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a TURN TCP allocation is released when the port is closed.
|
||||||
|
TEST_F(TurnPortTest, DISABLED_TestTurnTCPReleaseAllocation) {
|
||||||
|
turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
|
||||||
|
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
|
||||||
|
turn_port_->PrepareAddress();
|
||||||
|
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||||
|
|
||||||
|
ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
|
||||||
|
turn_port_.reset();
|
||||||
|
EXPECT_EQ_WAIT(0U, turn_server_.server()->allocations().size(), kTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
// This test verifies any FD's are not leaked after TurnPort is destroyed.
|
// This test verifies any FD's are not leaked after TurnPort is destroyed.
|
||||||
// https://code.google.com/p/webrtc/issues/detail?id=2651
|
// https://code.google.com/p/webrtc/issues/detail?id=2651
|
||||||
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
|
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user