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