Reset TURN port NONCE when a new socket is created.
For example, when the TURN port has an ALLOCATE_MISMATCH error. BUG=webrtc:5432 Review URL: https://codereview.webrtc.org/1595613004 Cr-Commit-Position: refs/heads/master@{#11453}
This commit is contained in:
parent
94291480b6
commit
c463e20069
@ -433,6 +433,7 @@ void TurnPort::OnAllocateMismatch() {
|
||||
}
|
||||
socket_ = NULL;
|
||||
|
||||
ResetNonce();
|
||||
PrepareAddress();
|
||||
++allocate_mismatch_retries_;
|
||||
}
|
||||
@ -933,6 +934,12 @@ bool TurnPort::UpdateNonce(StunMessage* response) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TurnPort::ResetNonce() {
|
||||
hash_.clear();
|
||||
nonce_.clear();
|
||||
realm_.clear();
|
||||
}
|
||||
|
||||
static bool MatchesIP(TurnEntry* e, rtc::IPAddress ipaddr) {
|
||||
return e->address().ipaddr() == ipaddr;
|
||||
}
|
||||
|
||||
@ -233,6 +233,7 @@ class TurnPort : public Port {
|
||||
const rtc::PacketOptions& options);
|
||||
void UpdateHash();
|
||||
bool UpdateNonce(StunMessage* response);
|
||||
void ResetNonce();
|
||||
|
||||
bool HasPermission(const rtc::IPAddress& ipaddr) const;
|
||||
TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
|
||||
|
||||
@ -605,6 +605,39 @@ TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
|
||||
ASSERT_EQ(0U, turn_port_->Candidates().size());
|
||||
}
|
||||
|
||||
// Tests that TURN port nonce will be reset when receiving an ALLOCATE MISMATCH
|
||||
// error.
|
||||
TEST_F(TurnPortTest, TestTurnAllocateNonceResetAfterAllocateMismatch) {
|
||||
// Do a normal allocation first.
|
||||
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
|
||||
turn_port_->PrepareAddress();
|
||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||
rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
|
||||
// Destroy the turnport while keeping the drop probability to 1 to
|
||||
// suppress the release of the allocation at the server.
|
||||
ss_->set_drop_probability(1.0);
|
||||
turn_port_.reset();
|
||||
rtc::Thread::Current()->ProcessMessages(0);
|
||||
ss_->set_drop_probability(0.0);
|
||||
|
||||
// Force the socket server to assign the same port.
|
||||
ss_->SetNextPortForTesting(first_addr.port());
|
||||
turn_ready_ = false;
|
||||
CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
|
||||
|
||||
// It is expected that the turn port will first get a nonce from the server
|
||||
// using timestamp |ts_before| but then get an allocate mismatch error and
|
||||
// receive an even newer nonce based on the system clock. |ts_before| is
|
||||
// chosen so that the two NONCEs generated by the server will be different.
|
||||
uint32_t ts_before = rtc::Time() - 1;
|
||||
std::string first_nonce =
|
||||
turn_server_.server()->SetTimestampForNextNonce(ts_before);
|
||||
turn_port_->PrepareAddress();
|
||||
|
||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||
EXPECT_NE(first_nonce, turn_port_->nonce());
|
||||
}
|
||||
|
||||
// Tests that a new local address is created after
|
||||
// STUN_ERROR_ALLOCATION_MISMATCH.
|
||||
TEST_F(TurnPortTest, TestTurnAllocateMismatch) {
|
||||
|
||||
@ -392,9 +392,8 @@ void TurnServer::HandleAllocateRequest(TurnServerConnection* conn,
|
||||
}
|
||||
}
|
||||
|
||||
std::string TurnServer::GenerateNonce() const {
|
||||
std::string TurnServer::GenerateNonce(uint32_t now) const {
|
||||
// Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
|
||||
uint32_t now = rtc::Time();
|
||||
std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
|
||||
std::string nonce = rtc::hex_encode(input.c_str(), input.size());
|
||||
nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input);
|
||||
@ -464,8 +463,14 @@ void TurnServer::SendErrorResponseWithRealmAndNonce(
|
||||
int code, const std::string& reason) {
|
||||
TurnMessage resp;
|
||||
InitErrorResponse(msg, code, reason, &resp);
|
||||
VERIFY(resp.AddAttribute(new StunByteStringAttribute(
|
||||
STUN_ATTR_NONCE, GenerateNonce())));
|
||||
|
||||
uint32_t timestamp = rtc::Time();
|
||||
if (ts_for_next_nonce_) {
|
||||
timestamp = ts_for_next_nonce_;
|
||||
ts_for_next_nonce_ = 0;
|
||||
}
|
||||
VERIFY(resp.AddAttribute(
|
||||
new StunByteStringAttribute(STUN_ATTR_NONCE, GenerateNonce(timestamp))));
|
||||
VERIFY(resp.AddAttribute(new StunByteStringAttribute(
|
||||
STUN_ATTR_REALM, realm_)));
|
||||
SendStun(conn, &resp);
|
||||
|
||||
@ -199,8 +199,14 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
// Specifies the factory to use for creating external sockets.
|
||||
void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
|
||||
const rtc::SocketAddress& address);
|
||||
// For testing only.
|
||||
std::string SetTimestampForNextNonce(uint32_t timestamp) {
|
||||
ts_for_next_nonce_ = timestamp;
|
||||
return GenerateNonce(timestamp);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GenerateNonce(uint32_t now) const;
|
||||
void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
|
||||
size_t size, const rtc::SocketAddress& address,
|
||||
const rtc::PacketTime& packet_time);
|
||||
@ -221,7 +227,6 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
|
||||
const char* data, size_t size,
|
||||
const std::string& key);
|
||||
std::string GenerateNonce() const;
|
||||
bool ValidateNonce(const std::string& nonce) const;
|
||||
|
||||
TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
|
||||
@ -270,6 +275,10 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
|
||||
AllocationMap allocations_;
|
||||
|
||||
// For testing only. If this is non-zero, the next NONCE will be generated
|
||||
// from this value, and it will be reset to 0 after generating the NONCE.
|
||||
uint32_t ts_for_next_nonce_ = 0;
|
||||
|
||||
friend class TurnServerAllocation;
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user