Log how often DTLS negotiation failed because of incompatible ciphersuites.
Log the DTLS handshake error code in OpenSSLStreamAdapter. Forward the error code to WebRTCSession with the Signals. This part is only for the WebRTC native code. To make it work, need another CL for Chromium. BUG=webrtc:5959 Review-Url: https://codereview.webrtc.org/2167363002 Cr-Commit-Position: refs/heads/master@{#13940}
This commit is contained in:
parent
3026ee81d3
commit
d82eee0675
@ -32,6 +32,7 @@ enum PeerConnectionEnumCounterType {
|
||||
kEnumCounterVideoSslCipher,
|
||||
kEnumCounterDataSrtpCipher,
|
||||
kEnumCounterDataSslCipher,
|
||||
kEnumCounterDtlsHandshakeError,
|
||||
kPeerConnectionEnumCounterMax
|
||||
};
|
||||
|
||||
|
||||
@ -493,6 +493,8 @@ WebRtcSession::WebRtcSession(
|
||||
this, &WebRtcSession::OnTransportControllerCandidatesGathered);
|
||||
transport_controller_->SignalCandidatesRemoved.connect(
|
||||
this, &WebRtcSession::OnTransportControllerCandidatesRemoved);
|
||||
transport_controller_->SignalDtlsHandshakeError.connect(
|
||||
this, &WebRtcSession::OnDtlsHandshakeError);
|
||||
}
|
||||
|
||||
WebRtcSession::~WebRtcSession() {
|
||||
@ -2073,4 +2075,12 @@ const std::string WebRtcSession::GetTransportName(
|
||||
}
|
||||
return channel->transport_name();
|
||||
}
|
||||
|
||||
void WebRtcSession::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
|
||||
if (metrics_observer_) {
|
||||
metrics_observer_->IncrementEnumCounter(
|
||||
webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error),
|
||||
static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -461,6 +461,8 @@ class WebRtcSession :
|
||||
|
||||
const std::string GetTransportName(const std::string& content_name);
|
||||
|
||||
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
||||
|
||||
rtc::Thread* const network_thread_;
|
||||
rtc::Thread* const worker_thread_;
|
||||
rtc::Thread* const signaling_thread_;
|
||||
|
||||
@ -839,6 +839,12 @@ int OpenSSLStreamAdapter::ContinueSSL() {
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
default:
|
||||
LOG(LS_VERBOSE) << " -- error " << code;
|
||||
SSLHandshakeError ssl_handshake_err = SSLHandshakeError::UNKNOWN;
|
||||
int err_code = ERR_peek_last_error();
|
||||
if (err_code != 0 && ERR_GET_REASON(err_code) == SSL_R_NO_SHARED_CIPHER) {
|
||||
ssl_handshake_err = SSLHandshakeError::INCOMPATIBLE_CIPHERSUITE;
|
||||
}
|
||||
SignalSSLHandshakeError(ssl_handshake_err);
|
||||
return (ssl_error != 0) ? ssl_error : -1;
|
||||
}
|
||||
|
||||
|
||||
@ -108,6 +108,13 @@ SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) {
|
||||
#endif // SSL_USE_OPENSSL
|
||||
}
|
||||
|
||||
SSLStreamAdapter::SSLStreamAdapter(StreamInterface* stream)
|
||||
: StreamAdapterInterface(stream),
|
||||
ignore_bad_cert_(false),
|
||||
client_auth_enabled_(true) {}
|
||||
|
||||
SSLStreamAdapter::~SSLStreamAdapter() {}
|
||||
|
||||
bool SSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -110,6 +110,9 @@ enum SSLProtocolVersion {
|
||||
// Errors for Read -- in the high range so no conflict with OpenSSL.
|
||||
enum { SSE_MSG_TRUNC = 0xff0001 };
|
||||
|
||||
// Used to send back UMA histogram value. Logged when Dtls handshake fails.
|
||||
enum class SSLHandshakeError { UNKNOWN, INCOMPATIBLE_CIPHERSUITE, MAX_VALUE };
|
||||
|
||||
class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
public:
|
||||
// Instantiate an SSLStreamAdapter wrapping the given stream,
|
||||
@ -117,9 +120,8 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
// Caller is responsible for freeing the returned object.
|
||||
static SSLStreamAdapter* Create(StreamInterface* stream);
|
||||
|
||||
explicit SSLStreamAdapter(StreamInterface* stream)
|
||||
: StreamAdapterInterface(stream), ignore_bad_cert_(false),
|
||||
client_auth_enabled_(true) { }
|
||||
explicit SSLStreamAdapter(StreamInterface* stream);
|
||||
~SSLStreamAdapter() override;
|
||||
|
||||
void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
|
||||
bool ignore_bad_cert() const { return ignore_bad_cert_; }
|
||||
@ -225,6 +227,8 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
// depending on specific SSL implementation.
|
||||
static std::string SslCipherSuiteToName(int cipher_suite);
|
||||
|
||||
sigslot::signal1<SSLHandshakeError> SignalSSLHandshakeError;
|
||||
|
||||
private:
|
||||
// If true, the server certificate need not match the configured
|
||||
// server_name, and in fact missing certificate authority and other
|
||||
|
||||
@ -280,6 +280,8 @@ bool DtlsTransportChannelWrapper::SetupDtls() {
|
||||
dtls_->SetMaxProtocolVersion(ssl_max_version_);
|
||||
dtls_->SetServerRole(ssl_role_);
|
||||
dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
|
||||
dtls_->SignalSSLHandshakeError.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnDtlsHandshakeError);
|
||||
if (!dtls_->SetPeerCertificateDigest(
|
||||
remote_fingerprint_algorithm_,
|
||||
reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()),
|
||||
@ -676,4 +678,9 @@ void DtlsTransportChannelWrapper::OnChannelStateChanged(
|
||||
SignalStateChanged(this);
|
||||
}
|
||||
|
||||
void DtlsTransportChannelWrapper::OnDtlsHandshakeError(
|
||||
rtc::SSLHandshakeError error) {
|
||||
SignalDtlsHandshakeError(error);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -220,6 +220,7 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
|
||||
int last_sent_packet_id,
|
||||
bool ready_to_send);
|
||||
void OnChannelStateChanged(TransportChannelImpl* channel);
|
||||
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
||||
|
||||
rtc::Thread* worker_thread_; // Everything should occur on this thread.
|
||||
// Underlying channel, not owned by this class.
|
||||
|
||||
@ -100,6 +100,9 @@ class TransportChannelImpl : public TransportChannel {
|
||||
// Emitted whenever the transport channel state changed.
|
||||
sigslot::signal1<TransportChannelImpl*> SignalStateChanged;
|
||||
|
||||
// Emitted whenever the Dtls handshake failed on some transport channel.
|
||||
sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(TransportChannelImpl);
|
||||
};
|
||||
|
||||
@ -191,6 +191,8 @@ TransportChannel* TransportController::CreateTransportChannel_n(
|
||||
this, &TransportController::OnChannelRoleConflict_n);
|
||||
channel->SignalStateChanged.connect(
|
||||
this, &TransportController::OnChannelStateChanged_n);
|
||||
channel->SignalDtlsHandshakeError.connect(
|
||||
this, &TransportController::OnDtlsHandshakeError);
|
||||
channels_.insert(channels_.end(), RefCountedChannel(channel))->AddRef();
|
||||
// Adding a channel could cause aggregate state to change.
|
||||
UpdateAggregateStates_n();
|
||||
@ -685,4 +687,8 @@ void TransportController::UpdateAggregateStates_n() {
|
||||
}
|
||||
}
|
||||
|
||||
void TransportController::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
|
||||
SignalDtlsHandshakeError(error);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -119,6 +119,8 @@ class TransportController : public sigslot::has_slots<>,
|
||||
// for unit test
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate_for_testing();
|
||||
|
||||
sigslot::signal1<rtc::SSLHandshakeError> SignalDtlsHandshakeError;
|
||||
|
||||
protected:
|
||||
// Protected and virtual so we can override it in unit tests.
|
||||
virtual Transport* CreateTransport_n(const std::string& transport_name);
|
||||
@ -202,6 +204,8 @@ class TransportController : public sigslot::has_slots<>,
|
||||
|
||||
void UpdateAggregateStates_n();
|
||||
|
||||
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
||||
|
||||
rtc::Thread* const signaling_thread_ = nullptr;
|
||||
rtc::Thread* const network_thread_ = nullptr;
|
||||
typedef std::map<std::string, Transport*> TransportMap;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user