aboutsummaryrefslogtreecommitdiff
path: root/p2p/base/stun_request.cc
diff options
context:
space:
mode:
Diffstat (limited to 'p2p/base/stun_request.cc')
-rw-r--r--p2p/base/stun_request.cc46
1 files changed, 33 insertions, 13 deletions
diff --git a/p2p/base/stun_request.cc b/p2p/base/stun_request.cc
index 25d387cc3a..5bf7dfe69c 100644
--- a/p2p/base/stun_request.cc
+++ b/p2p/base/stun_request.cc
@@ -57,6 +57,10 @@ void StunRequestManager::Send(StunRequest* request) {
void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
RTC_DCHECK_RUN_ON(thread_);
RTC_DCHECK_EQ(this, request->manager());
+ RTC_DCHECK(!request->AuthenticationRequired() ||
+ request->msg()->integrity() !=
+ StunMessage::IntegrityStatus::kNotSet)
+ << "Sending request w/o integrity!";
auto [iter, was_inserted] =
requests_.emplace(request->id(), absl::WrapUnique(request));
RTC_DCHECK(was_inserted);
@@ -104,15 +108,23 @@ bool StunRequestManager::CheckResponse(StunMessage* msg) {
StunRequest* request = iter->second.get();
// Now that we know the request, we can see if the response is
- // integrity-protected or not.
- // For some tests, the message integrity is not set in the request.
- // Complain, and then don't check.
+ // integrity-protected or not. Some requests explicitly disables
+ // integrity checks using SetAuthenticationRequired.
+ // TODO(chromium:1177125): Remove below!
+ // And we suspect that for some tests, the message integrity is not set in the
+ // request. Complain, and then don't check.
bool skip_integrity_checking =
(request->msg()->integrity() == StunMessage::IntegrityStatus::kNotSet);
- if (skip_integrity_checking) {
+ if (!request->AuthenticationRequired()) {
+ // This is a STUN_BINDING to from stun_port.cc or
+ // the initial (unauthenticated) TURN_ALLOCATE_REQUEST.
+ } else if (skip_integrity_checking) {
+ // TODO(chromium:1177125): Remove below!
// This indicates lazy test writing (not adding integrity attribute).
// Complain, but only in debug mode (while developing).
- RTC_DLOG(LS_ERROR)
+ RTC_LOG(LS_ERROR)
+ << "CheckResponse called on a passwordless request. Fix test!";
+ RTC_DCHECK(false)
<< "CheckResponse called on a passwordless request. Fix test!";
} else {
if (msg->integrity() == StunMessage::IntegrityStatus::kNotSet) {
@@ -133,31 +145,39 @@ bool StunRequestManager::CheckResponse(StunMessage* msg) {
}
}
- bool success = true;
-
if (!msg->GetNonComprehendedAttributes().empty()) {
// If a response contains unknown comprehension-required attributes, it's
// simply discarded and the transaction is considered failed. See RFC5389
// sections 7.3.3 and 7.3.4.
RTC_LOG(LS_ERROR) << ": Discarding response due to unknown "
"comprehension-required attribute.";
- success = false;
+ requests_.erase(iter);
+ return false;
} else if (msg->type() == GetStunSuccessResponseType(request->type())) {
if (!msg->IntegrityOk() && !skip_integrity_checking) {
return false;
}
- request->OnResponse(msg);
+ // Erase element from hash before calling callback. This ensures
+ // that the callback can modify the StunRequestManager any way it
+ // sees fit.
+ std::unique_ptr<StunRequest> owned_request = std::move(iter->second);
+ requests_.erase(iter);
+ owned_request->OnResponse(msg);
+ return true;
} else if (msg->type() == GetStunErrorResponseType(request->type())) {
- request->OnErrorResponse(msg);
+ // Erase element from hash before calling callback. This ensures
+ // that the callback can modify the StunRequestManager any way it
+ // sees fit.
+ std::unique_ptr<StunRequest> owned_request = std::move(iter->second);
+ requests_.erase(iter);
+ owned_request->OnErrorResponse(msg);
+ return true;
} else {
RTC_LOG(LS_ERROR) << "Received response with wrong type: " << msg->type()
<< " (expecting "
<< GetStunSuccessResponseType(request->type()) << ")";
return false;
}
-
- requests_.erase(iter);
- return success;
}
bool StunRequestManager::empty() const {