xref: /aosp_15_r20/external/webrtc/p2p/base/dtls_transport.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "p2p/base/dtls_transport.h"
12 
13 #include <algorithm>
14 #include <memory>
15 #include <utility>
16 
17 #include "absl/memory/memory.h"
18 #include "absl/strings/string_view.h"
19 #include "api/array_view.h"
20 #include "api/dtls_transport_interface.h"
21 #include "api/rtc_event_log/rtc_event_log.h"
22 #include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
23 #include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
24 #include "p2p/base/packet_transport_internal.h"
25 #include "rtc_base/buffer.h"
26 #include "rtc_base/checks.h"
27 #include "rtc_base/dscp.h"
28 #include "rtc_base/logging.h"
29 #include "rtc_base/rtc_certificate.h"
30 #include "rtc_base/ssl_stream_adapter.h"
31 #include "rtc_base/stream.h"
32 #include "rtc_base/thread.h"
33 
34 namespace cricket {
35 
36 // We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
37 static const size_t kDtlsRecordHeaderLen = 13;
38 static const size_t kMaxDtlsPacketLen = 2048;
39 static const size_t kMinRtpPacketLen = 12;
40 
41 // Maximum number of pending packets in the queue. Packets are read immediately
42 // after they have been written, so a capacity of "1" is sufficient.
43 //
44 // However, this bug seems to indicate that's not the case: crbug.com/1063834
45 // So, temporarily increasing it to 2 to see if that makes a difference.
46 static const size_t kMaxPendingPackets = 2;
47 
48 // Minimum and maximum values for the initial DTLS handshake timeout. We'll pick
49 // an initial timeout based on ICE RTT estimates, but clamp it to this range.
50 static const int kMinHandshakeTimeout = 50;
51 static const int kMaxHandshakeTimeout = 3000;
52 
IsDtlsPacket(const char * data,size_t len)53 static bool IsDtlsPacket(const char* data, size_t len) {
54   const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
55   return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
56 }
IsDtlsClientHelloPacket(const char * data,size_t len)57 static bool IsDtlsClientHelloPacket(const char* data, size_t len) {
58   if (!IsDtlsPacket(data, len)) {
59     return false;
60   }
61   const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
62   return len > 17 && u[0] == 22 && u[13] == 1;
63 }
IsRtpPacket(const char * data,size_t len)64 static bool IsRtpPacket(const char* data, size_t len) {
65   const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
66   return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
67 }
68 
StreamInterfaceChannel(IceTransportInternal * ice_transport)69 StreamInterfaceChannel::StreamInterfaceChannel(
70     IceTransportInternal* ice_transport)
71     : ice_transport_(ice_transport),
72       state_(rtc::SS_OPEN),
73       packets_(kMaxPendingPackets, kMaxDtlsPacketLen) {}
74 
Read(rtc::ArrayView<uint8_t> buffer,size_t & read,int & error)75 rtc::StreamResult StreamInterfaceChannel::Read(rtc::ArrayView<uint8_t> buffer,
76                                                size_t& read,
77                                                int& error) {
78   RTC_DCHECK_RUN_ON(&sequence_checker_);
79 
80   if (state_ == rtc::SS_CLOSED)
81     return rtc::SR_EOS;
82   if (state_ == rtc::SS_OPENING)
83     return rtc::SR_BLOCK;
84 
85   if (!packets_.ReadFront(buffer.data(), buffer.size(), &read)) {
86     return rtc::SR_BLOCK;
87   }
88 
89   return rtc::SR_SUCCESS;
90 }
91 
Write(rtc::ArrayView<const uint8_t> data,size_t & written,int & error)92 rtc::StreamResult StreamInterfaceChannel::Write(
93     rtc::ArrayView<const uint8_t> data,
94     size_t& written,
95     int& error) {
96   RTC_DCHECK_RUN_ON(&sequence_checker_);
97   // Always succeeds, since this is an unreliable transport anyway.
98   // TODO(zhihuang): Should this block if ice_transport_'s temporarily
99   // unwritable?
100   rtc::PacketOptions packet_options;
101   ice_transport_->SendPacket(reinterpret_cast<const char*>(data.data()),
102                              data.size(), packet_options);
103   written = data.size();
104   return rtc::SR_SUCCESS;
105 }
106 
OnPacketReceived(const char * data,size_t size)107 bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) {
108   RTC_DCHECK_RUN_ON(&sequence_checker_);
109   if (packets_.size() > 0) {
110     RTC_LOG(LS_WARNING) << "Packet already in queue.";
111   }
112   bool ret = packets_.WriteBack(data, size, NULL);
113   if (!ret) {
114     // Somehow we received another packet before the SSLStreamAdapter read the
115     // previous one out of our temporary buffer. In this case, we'll log an
116     // error and still signal the read event, hoping that it will read the
117     // packet currently in packets_.
118     RTC_LOG(LS_ERROR) << "Failed to write packet to queue.";
119   }
120   SignalEvent(this, rtc::SE_READ, 0);
121   return ret;
122 }
123 
GetState() const124 rtc::StreamState StreamInterfaceChannel::GetState() const {
125   RTC_DCHECK_RUN_ON(&sequence_checker_);
126   return state_;
127 }
128 
Close()129 void StreamInterfaceChannel::Close() {
130   RTC_DCHECK_RUN_ON(&sequence_checker_);
131   packets_.Clear();
132   state_ = rtc::SS_CLOSED;
133 }
134 
DtlsTransport(IceTransportInternal * ice_transport,const webrtc::CryptoOptions & crypto_options,webrtc::RtcEventLog * event_log,rtc::SSLProtocolVersion max_version)135 DtlsTransport::DtlsTransport(IceTransportInternal* ice_transport,
136                              const webrtc::CryptoOptions& crypto_options,
137                              webrtc::RtcEventLog* event_log,
138                              rtc::SSLProtocolVersion max_version)
139     : component_(ice_transport->component()),
140       ice_transport_(ice_transport),
141       downward_(NULL),
142       srtp_ciphers_(crypto_options.GetSupportedDtlsSrtpCryptoSuites()),
143       ssl_max_version_(max_version),
144       event_log_(event_log) {
145   RTC_DCHECK(ice_transport_);
146   ConnectToIceTransport();
147 }
148 
149 DtlsTransport::~DtlsTransport() = default;
150 
dtls_state() const151 webrtc::DtlsTransportState DtlsTransport::dtls_state() const {
152   return dtls_state_;
153 }
154 
transport_name() const155 const std::string& DtlsTransport::transport_name() const {
156   return ice_transport_->transport_name();
157 }
158 
component() const159 int DtlsTransport::component() const {
160   return component_;
161 }
162 
IsDtlsActive() const163 bool DtlsTransport::IsDtlsActive() const {
164   return dtls_active_;
165 }
166 
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)167 bool DtlsTransport::SetLocalCertificate(
168     const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
169   if (dtls_active_) {
170     if (certificate == local_certificate_) {
171       // This may happen during renegotiation.
172       RTC_LOG(LS_INFO) << ToString() << ": Ignoring identical DTLS identity";
173       return true;
174     } else {
175       RTC_LOG(LS_ERROR) << ToString()
176                         << ": Can't change DTLS local identity in this state";
177       return false;
178     }
179   }
180 
181   if (certificate) {
182     local_certificate_ = certificate;
183     dtls_active_ = true;
184   } else {
185     RTC_LOG(LS_INFO) << ToString()
186                      << ": NULL DTLS identity supplied. Not doing DTLS";
187   }
188 
189   return true;
190 }
191 
GetLocalCertificate() const192 rtc::scoped_refptr<rtc::RTCCertificate> DtlsTransport::GetLocalCertificate()
193     const {
194   return local_certificate_;
195 }
196 
SetDtlsRole(rtc::SSLRole role)197 bool DtlsTransport::SetDtlsRole(rtc::SSLRole role) {
198   if (dtls_) {
199     RTC_DCHECK(dtls_role_);
200     if (*dtls_role_ != role) {
201       RTC_LOG(LS_ERROR)
202           << "SSL Role can't be reversed after the session is setup.";
203       return false;
204     }
205     return true;
206   }
207 
208   dtls_role_ = role;
209   return true;
210 }
211 
GetDtlsRole(rtc::SSLRole * role) const212 bool DtlsTransport::GetDtlsRole(rtc::SSLRole* role) const {
213   if (!dtls_role_) {
214     return false;
215   }
216   *role = *dtls_role_;
217   return true;
218 }
219 
GetSslCipherSuite(int * cipher)220 bool DtlsTransport::GetSslCipherSuite(int* cipher) {
221   if (dtls_state() != webrtc::DtlsTransportState::kConnected) {
222     return false;
223   }
224 
225   return dtls_->GetSslCipherSuite(cipher);
226 }
227 
SetRemoteParameters(absl::string_view digest_alg,const uint8_t * digest,size_t digest_len,absl::optional<rtc::SSLRole> role)228 webrtc::RTCError DtlsTransport::SetRemoteParameters(
229     absl::string_view digest_alg,
230     const uint8_t* digest,
231     size_t digest_len,
232     absl::optional<rtc::SSLRole> role) {
233   rtc::Buffer remote_fingerprint_value(digest, digest_len);
234   bool is_dtls_restart =
235       dtls_active_ && remote_fingerprint_value_ != remote_fingerprint_value;
236   // Set SSL role. Role must be set before fingerprint is applied, which
237   // initiates DTLS setup.
238   if (role) {
239     if (is_dtls_restart) {
240       dtls_role_ = *role;
241     } else {
242       if (!SetDtlsRole(*role)) {
243         return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
244                                 "Failed to set SSL role for the transport.");
245       }
246     }
247   }
248   // Apply remote fingerprint.
249   if (!SetRemoteFingerprint(digest_alg, digest, digest_len)) {
250     return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
251                             "Failed to apply remote fingerprint.");
252   }
253   return webrtc::RTCError::OK();
254 }
255 
SetRemoteFingerprint(absl::string_view digest_alg,const uint8_t * digest,size_t digest_len)256 bool DtlsTransport::SetRemoteFingerprint(absl::string_view digest_alg,
257                                          const uint8_t* digest,
258                                          size_t digest_len) {
259   rtc::Buffer remote_fingerprint_value(digest, digest_len);
260 
261   // Once we have the local certificate, the same remote fingerprint can be set
262   // multiple times.
263   if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value &&
264       !digest_alg.empty()) {
265     // This may happen during renegotiation.
266     RTC_LOG(LS_INFO) << ToString()
267                      << ": Ignoring identical remote DTLS fingerprint";
268     return true;
269   }
270 
271   // If the other side doesn't support DTLS, turn off `dtls_active_`.
272   // TODO(deadbeef): Remove this. It's dangerous, because it relies on higher
273   // level code to ensure DTLS is actually used, but there are tests that
274   // depend on it, for the case where an m= section is rejected. In that case
275   // SetRemoteFingerprint shouldn't even be called though.
276   if (digest_alg.empty()) {
277     RTC_DCHECK(!digest_len);
278     RTC_LOG(LS_INFO) << ToString() << ": Other side didn't support DTLS.";
279     dtls_active_ = false;
280     return true;
281   }
282 
283   // Otherwise, we must have a local certificate before setting remote
284   // fingerprint.
285   if (!dtls_active_) {
286     RTC_LOG(LS_ERROR) << ToString()
287                       << ": Can't set DTLS remote settings in this state.";
288     return false;
289   }
290 
291   // At this point we know we are doing DTLS
292   bool fingerprint_changing = remote_fingerprint_value_.size() > 0u;
293   remote_fingerprint_value_ = std::move(remote_fingerprint_value);
294   remote_fingerprint_algorithm_ = std::string(digest_alg);
295 
296   if (dtls_ && !fingerprint_changing) {
297     // This can occur if DTLS is set up before a remote fingerprint is
298     // received. For instance, if we set up DTLS due to receiving an early
299     // ClientHello.
300     rtc::SSLPeerCertificateDigestError err;
301     if (!dtls_->SetPeerCertificateDigest(
302             remote_fingerprint_algorithm_,
303             reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()),
304             remote_fingerprint_value_.size(), &err)) {
305       RTC_LOG(LS_ERROR) << ToString()
306                         << ": Couldn't set DTLS certificate digest.";
307       set_dtls_state(webrtc::DtlsTransportState::kFailed);
308       // If the error is "verification failed", don't return false, because
309       // this means the fingerprint was formatted correctly but didn't match
310       // the certificate from the DTLS handshake. Thus the DTLS state should go
311       // to "failed", but SetRemoteDescription shouldn't fail.
312       return err == rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED;
313     }
314     return true;
315   }
316 
317   // If the fingerprint is changing, we'll tear down the DTLS association and
318   // create a new one, resetting our state.
319   if (dtls_ && fingerprint_changing) {
320     dtls_.reset(nullptr);
321     set_dtls_state(webrtc::DtlsTransportState::kNew);
322     set_writable(false);
323   }
324 
325   if (!SetupDtls()) {
326     set_dtls_state(webrtc::DtlsTransportState::kFailed);
327     return false;
328   }
329 
330   return true;
331 }
332 
GetRemoteSSLCertChain() const333 std::unique_ptr<rtc::SSLCertChain> DtlsTransport::GetRemoteSSLCertChain()
334     const {
335   if (!dtls_) {
336     return nullptr;
337   }
338 
339   return dtls_->GetPeerSSLCertChain();
340 }
341 
ExportKeyingMaterial(absl::string_view label,const uint8_t * context,size_t context_len,bool use_context,uint8_t * result,size_t result_len)342 bool DtlsTransport::ExportKeyingMaterial(absl::string_view label,
343                                          const uint8_t* context,
344                                          size_t context_len,
345                                          bool use_context,
346                                          uint8_t* result,
347                                          size_t result_len) {
348   return (dtls_.get())
349              ? dtls_->ExportKeyingMaterial(label, context, context_len,
350                                            use_context, result, result_len)
351              : false;
352 }
353 
SetupDtls()354 bool DtlsTransport::SetupDtls() {
355   RTC_DCHECK(dtls_role_);
356   {
357     auto downward = std::make_unique<StreamInterfaceChannel>(ice_transport_);
358     StreamInterfaceChannel* downward_ptr = downward.get();
359 
360     dtls_ = rtc::SSLStreamAdapter::Create(std::move(downward));
361     if (!dtls_) {
362       RTC_LOG(LS_ERROR) << ToString() << ": Failed to create DTLS adapter.";
363       return false;
364     }
365     downward_ = downward_ptr;
366   }
367 
368   dtls_->SetIdentity(local_certificate_->identity()->Clone());
369   dtls_->SetMode(rtc::SSL_MODE_DTLS);
370   dtls_->SetMaxProtocolVersion(ssl_max_version_);
371   dtls_->SetServerRole(*dtls_role_);
372   dtls_->SignalEvent.connect(this, &DtlsTransport::OnDtlsEvent);
373   dtls_->SignalSSLHandshakeError.connect(this,
374                                          &DtlsTransport::OnDtlsHandshakeError);
375   if (remote_fingerprint_value_.size() &&
376       !dtls_->SetPeerCertificateDigest(
377           remote_fingerprint_algorithm_,
378           reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()),
379           remote_fingerprint_value_.size())) {
380     RTC_LOG(LS_ERROR) << ToString()
381                       << ": Couldn't set DTLS certificate digest.";
382     return false;
383   }
384 
385   // Set up DTLS-SRTP, if it's been enabled.
386   if (!srtp_ciphers_.empty()) {
387     if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) {
388       RTC_LOG(LS_ERROR) << ToString() << ": Couldn't set DTLS-SRTP ciphers.";
389       return false;
390     }
391   } else {
392     RTC_LOG(LS_INFO) << ToString() << ": Not using DTLS-SRTP.";
393   }
394 
395   RTC_LOG(LS_INFO) << ToString() << ": DTLS setup complete.";
396 
397   // If the underlying ice_transport is already writable at this point, we may
398   // be able to start DTLS right away.
399   MaybeStartDtls();
400   return true;
401 }
402 
GetSrtpCryptoSuite(int * cipher)403 bool DtlsTransport::GetSrtpCryptoSuite(int* cipher) {
404   if (dtls_state() != webrtc::DtlsTransportState::kConnected) {
405     return false;
406   }
407 
408   return dtls_->GetDtlsSrtpCryptoSuite(cipher);
409 }
410 
GetSslVersionBytes(int * version) const411 bool DtlsTransport::GetSslVersionBytes(int* version) const {
412   if (dtls_state() != webrtc::DtlsTransportState::kConnected) {
413     return false;
414   }
415 
416   return dtls_->GetSslVersionBytes(version);
417 }
418 
419 // Called from upper layers to send a media packet.
SendPacket(const char * data,size_t size,const rtc::PacketOptions & options,int flags)420 int DtlsTransport::SendPacket(const char* data,
421                               size_t size,
422                               const rtc::PacketOptions& options,
423                               int flags) {
424   if (!dtls_active_) {
425     // Not doing DTLS.
426     return ice_transport_->SendPacket(data, size, options);
427   }
428 
429   switch (dtls_state()) {
430     case webrtc::DtlsTransportState::kNew:
431       // Can't send data until the connection is active.
432       // TODO([email protected]): assert here if dtls_ is NULL?
433       return -1;
434     case webrtc::DtlsTransportState::kConnecting:
435       // Can't send data until the connection is active.
436       return -1;
437     case webrtc::DtlsTransportState::kConnected:
438       if (flags & PF_SRTP_BYPASS) {
439         RTC_DCHECK(!srtp_ciphers_.empty());
440         if (!IsRtpPacket(data, size)) {
441           return -1;
442         }
443 
444         return ice_transport_->SendPacket(data, size, options);
445       } else {
446         size_t written;
447         int error;
448         return (dtls_->WriteAll(
449                     rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data),
450                                        size),
451                     written, error) == rtc::SR_SUCCESS)
452                    ? static_cast<int>(size)
453                    : -1;
454       }
455     case webrtc::DtlsTransportState::kFailed:
456       // Can't send anything when we're failed.
457       RTC_LOG(LS_ERROR) << ToString()
458                         << ": Couldn't send packet due to "
459                            "webrtc::DtlsTransportState::kFailed.";
460       return -1;
461     case webrtc::DtlsTransportState::kClosed:
462       // Can't send anything when we're closed.
463       RTC_LOG(LS_ERROR) << ToString()
464                         << ": Couldn't send packet due to "
465                            "webrtc::DtlsTransportState::kClosed.";
466       return -1;
467     default:
468       RTC_DCHECK_NOTREACHED();
469       return -1;
470   }
471 }
472 
ice_transport()473 IceTransportInternal* DtlsTransport::ice_transport() {
474   return ice_transport_;
475 }
476 
IsDtlsConnected()477 bool DtlsTransport::IsDtlsConnected() {
478   return dtls_ && dtls_->IsTlsConnected();
479 }
480 
receiving() const481 bool DtlsTransport::receiving() const {
482   return receiving_;
483 }
484 
writable() const485 bool DtlsTransport::writable() const {
486   return writable_;
487 }
488 
GetError()489 int DtlsTransport::GetError() {
490   return ice_transport_->GetError();
491 }
492 
network_route() const493 absl::optional<rtc::NetworkRoute> DtlsTransport::network_route() const {
494   return ice_transport_->network_route();
495 }
496 
GetOption(rtc::Socket::Option opt,int * value)497 bool DtlsTransport::GetOption(rtc::Socket::Option opt, int* value) {
498   return ice_transport_->GetOption(opt, value);
499 }
500 
SetOption(rtc::Socket::Option opt,int value)501 int DtlsTransport::SetOption(rtc::Socket::Option opt, int value) {
502   return ice_transport_->SetOption(opt, value);
503 }
504 
ConnectToIceTransport()505 void DtlsTransport::ConnectToIceTransport() {
506   RTC_DCHECK(ice_transport_);
507   ice_transport_->SignalWritableState.connect(this,
508                                               &DtlsTransport::OnWritableState);
509   ice_transport_->SignalReadPacket.connect(this, &DtlsTransport::OnReadPacket);
510   ice_transport_->SignalSentPacket.connect(this, &DtlsTransport::OnSentPacket);
511   ice_transport_->SignalReadyToSend.connect(this,
512                                             &DtlsTransport::OnReadyToSend);
513   ice_transport_->SignalReceivingState.connect(
514       this, &DtlsTransport::OnReceivingState);
515   ice_transport_->SignalNetworkRouteChanged.connect(
516       this, &DtlsTransport::OnNetworkRouteChanged);
517 }
518 
519 // The state transition logic here is as follows:
520 // (1) If we're not doing DTLS-SRTP, then the state is just the
521 //     state of the underlying impl()
522 // (2) If we're doing DTLS-SRTP:
523 //     - Prior to the DTLS handshake, the state is neither receiving nor
524 //       writable
525 //     - When the impl goes writable for the first time we
526 //       start the DTLS handshake
527 //     - Once the DTLS handshake completes, the state is that of the
528 //       impl again
OnWritableState(rtc::PacketTransportInternal * transport)529 void DtlsTransport::OnWritableState(rtc::PacketTransportInternal* transport) {
530   RTC_DCHECK_RUN_ON(&thread_checker_);
531   RTC_DCHECK(transport == ice_transport_);
532   RTC_LOG(LS_VERBOSE) << ToString()
533                       << ": ice_transport writable state changed to "
534                       << ice_transport_->writable();
535 
536   if (!dtls_active_) {
537     // Not doing DTLS.
538     // Note: SignalWritableState fired by set_writable.
539     set_writable(ice_transport_->writable());
540     return;
541   }
542 
543   switch (dtls_state()) {
544     case webrtc::DtlsTransportState::kNew:
545       MaybeStartDtls();
546       break;
547     case webrtc::DtlsTransportState::kConnected:
548       // Note: SignalWritableState fired by set_writable.
549       set_writable(ice_transport_->writable());
550       break;
551     case webrtc::DtlsTransportState::kConnecting:
552       // Do nothing.
553       break;
554     case webrtc::DtlsTransportState::kFailed:
555       // Should not happen. Do nothing.
556       RTC_LOG(LS_ERROR) << ToString()
557                         << ": OnWritableState() called in state "
558                            "webrtc::DtlsTransportState::kFailed.";
559       break;
560     case webrtc::DtlsTransportState::kClosed:
561       // Should not happen. Do nothing.
562       RTC_LOG(LS_ERROR) << ToString()
563                         << ": OnWritableState() called in state "
564                            "webrtc::DtlsTransportState::kClosed.";
565       break;
566     case webrtc::DtlsTransportState::kNumValues:
567       RTC_DCHECK_NOTREACHED();
568       break;
569   }
570 }
571 
OnReceivingState(rtc::PacketTransportInternal * transport)572 void DtlsTransport::OnReceivingState(rtc::PacketTransportInternal* transport) {
573   RTC_DCHECK_RUN_ON(&thread_checker_);
574   RTC_DCHECK(transport == ice_transport_);
575   RTC_LOG(LS_VERBOSE) << ToString()
576                       << ": ice_transport "
577                          "receiving state changed to "
578                       << ice_transport_->receiving();
579   if (!dtls_active_ || dtls_state() == webrtc::DtlsTransportState::kConnected) {
580     // Note: SignalReceivingState fired by set_receiving.
581     set_receiving(ice_transport_->receiving());
582   }
583 }
584 
OnReadPacket(rtc::PacketTransportInternal * transport,const char * data,size_t size,const int64_t & packet_time_us,int flags)585 void DtlsTransport::OnReadPacket(rtc::PacketTransportInternal* transport,
586                                  const char* data,
587                                  size_t size,
588                                  const int64_t& packet_time_us,
589                                  int flags) {
590   RTC_DCHECK_RUN_ON(&thread_checker_);
591   RTC_DCHECK(transport == ice_transport_);
592   RTC_DCHECK(flags == 0);
593 
594   if (!dtls_active_) {
595     // Not doing DTLS.
596     SignalReadPacket(this, data, size, packet_time_us, 0);
597     return;
598   }
599 
600   switch (dtls_state()) {
601     case webrtc::DtlsTransportState::kNew:
602       if (dtls_) {
603         RTC_LOG(LS_INFO) << ToString()
604                          << ": Packet received before DTLS started.";
605       } else {
606         RTC_LOG(LS_WARNING) << ToString()
607                             << ": Packet received before we know if we are "
608                                "doing DTLS or not.";
609       }
610       // Cache a client hello packet received before DTLS has actually started.
611       if (IsDtlsClientHelloPacket(data, size)) {
612         RTC_LOG(LS_INFO) << ToString()
613                          << ": Caching DTLS ClientHello packet until DTLS is "
614                             "started.";
615         cached_client_hello_.SetData(data, size);
616         // If we haven't started setting up DTLS yet (because we don't have a
617         // remote fingerprint/role), we can use the client hello as a clue that
618         // the peer has chosen the client role, and proceed with the handshake.
619         // The fingerprint will be verified when it's set.
620         if (!dtls_ && local_certificate_) {
621           SetDtlsRole(rtc::SSL_SERVER);
622           SetupDtls();
623         }
624       } else {
625         RTC_LOG(LS_INFO) << ToString()
626                          << ": Not a DTLS ClientHello packet; dropping.";
627       }
628       break;
629 
630     case webrtc::DtlsTransportState::kConnecting:
631     case webrtc::DtlsTransportState::kConnected:
632       // We should only get DTLS or SRTP packets; STUN's already been demuxed.
633       // Is this potentially a DTLS packet?
634       if (IsDtlsPacket(data, size)) {
635         if (!HandleDtlsPacket(data, size)) {
636           RTC_LOG(LS_ERROR) << ToString() << ": Failed to handle DTLS packet.";
637           return;
638         }
639       } else {
640         // Not a DTLS packet; our handshake should be complete by now.
641         if (dtls_state() != webrtc::DtlsTransportState::kConnected) {
642           RTC_LOG(LS_ERROR) << ToString()
643                             << ": Received non-DTLS packet before DTLS "
644                                "complete.";
645           return;
646         }
647 
648         // And it had better be a SRTP packet.
649         if (!IsRtpPacket(data, size)) {
650           RTC_LOG(LS_ERROR)
651               << ToString() << ": Received unexpected non-DTLS packet.";
652           return;
653         }
654 
655         // Sanity check.
656         RTC_DCHECK(!srtp_ciphers_.empty());
657 
658         // Signal this upwards as a bypass packet.
659         SignalReadPacket(this, data, size, packet_time_us, PF_SRTP_BYPASS);
660       }
661       break;
662     case webrtc::DtlsTransportState::kFailed:
663     case webrtc::DtlsTransportState::kClosed:
664     case webrtc::DtlsTransportState::kNumValues:
665       // This shouldn't be happening. Drop the packet.
666       break;
667   }
668 }
669 
OnSentPacket(rtc::PacketTransportInternal * transport,const rtc::SentPacket & sent_packet)670 void DtlsTransport::OnSentPacket(rtc::PacketTransportInternal* transport,
671                                  const rtc::SentPacket& sent_packet) {
672   RTC_DCHECK_RUN_ON(&thread_checker_);
673   SignalSentPacket(this, sent_packet);
674 }
675 
OnReadyToSend(rtc::PacketTransportInternal * transport)676 void DtlsTransport::OnReadyToSend(rtc::PacketTransportInternal* transport) {
677   RTC_DCHECK_RUN_ON(&thread_checker_);
678   if (writable()) {
679     SignalReadyToSend(this);
680   }
681 }
682 
OnDtlsEvent(rtc::StreamInterface * dtls,int sig,int err)683 void DtlsTransport::OnDtlsEvent(rtc::StreamInterface* dtls, int sig, int err) {
684   RTC_DCHECK_RUN_ON(&thread_checker_);
685   RTC_DCHECK(dtls == dtls_.get());
686   if (sig & rtc::SE_OPEN) {
687     // This is the first time.
688     RTC_LOG(LS_INFO) << ToString() << ": DTLS handshake complete.";
689     if (dtls_->GetState() == rtc::SS_OPEN) {
690       // The check for OPEN shouldn't be necessary but let's make
691       // sure we don't accidentally frob the state if it's closed.
692       set_dtls_state(webrtc::DtlsTransportState::kConnected);
693       set_writable(true);
694     }
695   }
696   if (sig & rtc::SE_READ) {
697     uint8_t buf[kMaxDtlsPacketLen];
698     size_t read;
699     int read_error;
700     rtc::StreamResult ret;
701     // The underlying DTLS stream may have received multiple DTLS records in
702     // one packet, so read all of them.
703     do {
704       ret = dtls_->Read(buf, read, read_error);
705       if (ret == rtc::SR_SUCCESS) {
706         SignalReadPacket(this, reinterpret_cast<const char*>(buf), read,
707                          rtc::TimeMicros(), 0);
708       } else if (ret == rtc::SR_EOS) {
709         // Remote peer shut down the association with no error.
710         RTC_LOG(LS_INFO) << ToString() << ": DTLS transport closed by remote";
711         set_writable(false);
712         set_dtls_state(webrtc::DtlsTransportState::kClosed);
713         SignalClosed(this);
714       } else if (ret == rtc::SR_ERROR) {
715         // Remote peer shut down the association with an error.
716         RTC_LOG(LS_INFO)
717             << ToString()
718             << ": Closed by remote with DTLS transport error, code="
719             << read_error;
720         set_writable(false);
721         set_dtls_state(webrtc::DtlsTransportState::kFailed);
722         SignalClosed(this);
723       }
724     } while (ret == rtc::SR_SUCCESS);
725   }
726   if (sig & rtc::SE_CLOSE) {
727     RTC_DCHECK(sig == rtc::SE_CLOSE);  // SE_CLOSE should be by itself.
728     set_writable(false);
729     if (!err) {
730       RTC_LOG(LS_INFO) << ToString() << ": DTLS transport closed";
731       set_dtls_state(webrtc::DtlsTransportState::kClosed);
732     } else {
733       RTC_LOG(LS_INFO) << ToString() << ": DTLS transport error, code=" << err;
734       set_dtls_state(webrtc::DtlsTransportState::kFailed);
735     }
736   }
737 }
738 
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)739 void DtlsTransport::OnNetworkRouteChanged(
740     absl::optional<rtc::NetworkRoute> network_route) {
741   RTC_DCHECK_RUN_ON(&thread_checker_);
742   SignalNetworkRouteChanged(network_route);
743 }
744 
MaybeStartDtls()745 void DtlsTransport::MaybeStartDtls() {
746   if (dtls_ && ice_transport_->writable()) {
747     ConfigureHandshakeTimeout();
748 
749     if (dtls_->StartSSL()) {
750       // This should never fail:
751       // Because we are operating in a nonblocking mode and all
752       // incoming packets come in via OnReadPacket(), which rejects
753       // packets in this state, the incoming queue must be empty. We
754       // ignore write errors, thus any errors must be because of
755       // configuration and therefore are our fault.
756       RTC_DCHECK_NOTREACHED() << "StartSSL failed.";
757       RTC_LOG(LS_ERROR) << ToString() << ": Couldn't start DTLS handshake";
758       set_dtls_state(webrtc::DtlsTransportState::kFailed);
759       return;
760     }
761     RTC_LOG(LS_INFO) << ToString() << ": DtlsTransport: Started DTLS handshake";
762     set_dtls_state(webrtc::DtlsTransportState::kConnecting);
763     // Now that the handshake has started, we can process a cached ClientHello
764     // (if one exists).
765     if (cached_client_hello_.size()) {
766       if (*dtls_role_ == rtc::SSL_SERVER) {
767         RTC_LOG(LS_INFO) << ToString()
768                          << ": Handling cached DTLS ClientHello packet.";
769         if (!HandleDtlsPacket(cached_client_hello_.data<char>(),
770                               cached_client_hello_.size())) {
771           RTC_LOG(LS_ERROR) << ToString() << ": Failed to handle DTLS packet.";
772         }
773       } else {
774         RTC_LOG(LS_WARNING) << ToString()
775                             << ": Discarding cached DTLS ClientHello packet "
776                                "because we don't have the server role.";
777       }
778       cached_client_hello_.Clear();
779     }
780   }
781 }
782 
783 // Called from OnReadPacket when a DTLS packet is received.
HandleDtlsPacket(const char * data,size_t size)784 bool DtlsTransport::HandleDtlsPacket(const char* data, size_t size) {
785   // Sanity check we're not passing junk that
786   // just looks like DTLS.
787   const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data);
788   size_t tmp_size = size;
789   while (tmp_size > 0) {
790     if (tmp_size < kDtlsRecordHeaderLen)
791       return false;  // Too short for the header
792 
793     size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]);
794     if ((record_len + kDtlsRecordHeaderLen) > tmp_size)
795       return false;  // Body too short
796 
797     tmp_data += record_len + kDtlsRecordHeaderLen;
798     tmp_size -= record_len + kDtlsRecordHeaderLen;
799   }
800 
801   // Looks good. Pass to the SIC which ends up being passed to
802   // the DTLS stack.
803   return downward_->OnPacketReceived(data, size);
804 }
805 
set_receiving(bool receiving)806 void DtlsTransport::set_receiving(bool receiving) {
807   if (receiving_ == receiving) {
808     return;
809   }
810   receiving_ = receiving;
811   SignalReceivingState(this);
812 }
813 
set_writable(bool writable)814 void DtlsTransport::set_writable(bool writable) {
815   if (writable_ == writable) {
816     return;
817   }
818   if (event_log_) {
819     event_log_->Log(
820         std::make_unique<webrtc::RtcEventDtlsWritableState>(writable));
821   }
822   RTC_LOG(LS_VERBOSE) << ToString() << ": set_writable to: " << writable;
823   writable_ = writable;
824   if (writable_) {
825     SignalReadyToSend(this);
826   }
827   SignalWritableState(this);
828 }
829 
set_dtls_state(webrtc::DtlsTransportState state)830 void DtlsTransport::set_dtls_state(webrtc::DtlsTransportState state) {
831   if (dtls_state_ == state) {
832     return;
833   }
834   if (event_log_) {
835     event_log_->Log(
836         std::make_unique<webrtc::RtcEventDtlsTransportState>(state));
837   }
838   RTC_LOG(LS_VERBOSE) << ToString() << ": set_dtls_state from:"
839                       << static_cast<int>(dtls_state_) << " to "
840                       << static_cast<int>(state);
841   dtls_state_ = state;
842   SendDtlsState(this, state);
843 }
844 
OnDtlsHandshakeError(rtc::SSLHandshakeError error)845 void DtlsTransport::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
846   SendDtlsHandshakeError(error);
847 }
848 
ConfigureHandshakeTimeout()849 void DtlsTransport::ConfigureHandshakeTimeout() {
850   RTC_DCHECK(dtls_);
851   absl::optional<int> rtt = ice_transport_->GetRttEstimate();
852   if (rtt) {
853     // Limit the timeout to a reasonable range in case the ICE RTT takes
854     // extreme values.
855     int initial_timeout = std::max(kMinHandshakeTimeout,
856                                    std::min(kMaxHandshakeTimeout, 2 * (*rtt)));
857     RTC_LOG(LS_INFO) << ToString() << ": configuring DTLS handshake timeout "
858                      << initial_timeout << " based on ICE RTT " << *rtt;
859 
860     dtls_->SetInitialRetransmissionTimeout(initial_timeout);
861   } else {
862     RTC_LOG(LS_INFO)
863         << ToString()
864         << ": no RTT estimate - using default DTLS handshake timeout";
865   }
866 }
867 
868 }  // namespace cricket
869