Add UMA logging for STUN verification outcomes

This will allow us to see if bad integrity ever occurs, and where integrity
is not applied.

Bug: chromium:1177125
Change-Id: I7abdaba93088e4eef8121205e7dd76b21204cae8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/278400
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38330}
This commit is contained in:
Harald Alvestrand
2022-10-10 04:36:12 +00:00
committed by WebRTC LUCI CQ
parent ca7616f061
commit 38b3b5ef5f
3 changed files with 74 additions and 4 deletions

View File

@ -105,6 +105,7 @@ rtc_source_set("stun_types") {
"../../rtc_base:logging",
"../../rtc_base:rtc_base",
"../../rtc_base:socket_address",
"../../system_wrappers:metrics",
]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
}

View File

@ -24,6 +24,7 @@
#include "rtc_base/helpers.h"
#include "rtc_base/logging.h"
#include "rtc_base/message_digest.h"
#include "system_wrappers/include/metrics.h"
using rtc::ByteBufferReader;
using rtc::ByteBufferWriter;
@ -258,6 +259,71 @@ StunMessage::IntegrityStatus StunMessage::ValidateMessageIntegrity(
} else {
integrity_ = IntegrityStatus::kNoIntegrity;
}
// Log the result of integrity checking. See crbug.com/1177125 for background.
// Convert args to integer for the benefit of the macros.
int bucket_count = static_cast<int>(IntegrityStatus::kMaxValue) + 1;
int integrity = static_cast<int>(integrity_);
if (IsStunRequestType(type_)) {
RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Request", integrity,
bucket_count);
} else if (IsStunSuccessResponseType(type_)) {
RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Response", integrity,
bucket_count);
} else if (IsStunIndicationType(type_)) {
RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Indication", integrity,
bucket_count);
} else {
RTC_DCHECK(IsStunErrorResponseType(type_));
auto* error_attribute = GetErrorCode();
if (!error_attribute) {
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.NoErrorAttribute", integrity,
bucket_count);
} else {
switch (error_attribute->code()) {
case STUN_ERROR_TRY_ALTERNATE:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.TryAlternate", integrity,
bucket_count);
break;
case STUN_ERROR_BAD_REQUEST:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.BadRequest", integrity,
bucket_count);
break;
case STUN_ERROR_UNAUTHORIZED:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.Unauthorized", integrity,
bucket_count);
break;
case STUN_ERROR_UNKNOWN_ATTRIBUTE:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.UnknownAttribute", integrity,
bucket_count);
break;
case STUN_ERROR_STALE_NONCE:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.StaleNonce", integrity,
bucket_count);
break;
case STUN_ERROR_SERVER_ERROR:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.ServerError", integrity,
bucket_count);
break;
case STUN_ERROR_GLOBAL_FAILURE:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.GlobalFailure", integrity,
bucket_count);
break;
default:
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Stun.Integrity.ErrorResponse.ErrorOther", integrity,
bucket_count);
break;
}
}
}
return integrity_;
}

View File

@ -159,11 +159,14 @@ class StunMessage {
// The verification status of the message. This is checked on parsing,
// or set by AddMessageIntegrity.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class IntegrityStatus {
kNotSet,
kNoIntegrity, // Message-integrity attribute missing
kIntegrityOk, // Message-integrity checked OK
kIntegrityBad, // Message-integrity verification failed
kNotSet = 0,
kNoIntegrity = 1, // Message-integrity attribute missing
kIntegrityOk = 2, // Message-integrity checked OK
kIntegrityBad = 3, // Message-integrity verification failed
kMaxValue = kIntegrityBad,
};
int type() const { return type_; }