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 <utility>
12
13 #include "webrtc/p2p/base/dtlstransportchannel.h"
14
15 #include "webrtc/p2p/base/common.h"
16 #include "webrtc/base/buffer.h"
17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/dscp.h"
19 #include "webrtc/base/messagequeue.h"
20 #include "webrtc/base/sslstreamadapter.h"
21 #include "webrtc/base/stream.h"
22 #include "webrtc/base/thread.h"
23
24 namespace cricket {
25
26 // We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
27 static const size_t kDtlsRecordHeaderLen = 13;
28 static const size_t kMaxDtlsPacketLen = 2048;
29 static const size_t kMinRtpPacketLen = 12;
30
31 // Maximum number of pending packets in the queue. Packets are read immediately
32 // after they have been written, so a capacity of "1" is sufficient.
33 static const size_t kMaxPendingPackets = 1;
34
IsDtlsPacket(const char * data,size_t len)35 static bool IsDtlsPacket(const char* data, size_t len) {
36 const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
37 return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
38 }
IsRtpPacket(const char * data,size_t len)39 static bool IsRtpPacket(const char* data, size_t len) {
40 const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
41 return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
42 }
43
StreamInterfaceChannel(TransportChannel * channel)44 StreamInterfaceChannel::StreamInterfaceChannel(TransportChannel* channel)
45 : channel_(channel),
46 state_(rtc::SS_OPEN),
47 packets_(kMaxPendingPackets, kMaxDtlsPacketLen) {
48 }
49
Read(void * buffer,size_t buffer_len,size_t * read,int * error)50 rtc::StreamResult StreamInterfaceChannel::Read(void* buffer,
51 size_t buffer_len,
52 size_t* read,
53 int* error) {
54 if (state_ == rtc::SS_CLOSED)
55 return rtc::SR_EOS;
56 if (state_ == rtc::SS_OPENING)
57 return rtc::SR_BLOCK;
58
59 if (!packets_.ReadFront(buffer, buffer_len, read)) {
60 return rtc::SR_BLOCK;
61 }
62
63 return rtc::SR_SUCCESS;
64 }
65
Write(const void * data,size_t data_len,size_t * written,int * error)66 rtc::StreamResult StreamInterfaceChannel::Write(const void* data,
67 size_t data_len,
68 size_t* written,
69 int* error) {
70 // Always succeeds, since this is an unreliable transport anyway.
71 // TODO: Should this block if channel_'s temporarily unwritable?
72 rtc::PacketOptions packet_options;
73 channel_->SendPacket(static_cast<const char*>(data), data_len,
74 packet_options);
75 if (written) {
76 *written = data_len;
77 }
78 return rtc::SR_SUCCESS;
79 }
80
OnPacketReceived(const char * data,size_t size)81 bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) {
82 // We force a read event here to ensure that we don't overflow our queue.
83 bool ret = packets_.WriteBack(data, size, NULL);
84 RTC_CHECK(ret) << "Failed to write packet to queue.";
85 if (ret) {
86 SignalEvent(this, rtc::SE_READ, 0);
87 }
88 return ret;
89 }
90
DtlsTransportChannelWrapper(Transport * transport,TransportChannelImpl * channel)91 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
92 Transport* transport,
93 TransportChannelImpl* channel)
94 : TransportChannelImpl(channel->transport_name(), channel->component()),
95 transport_(transport),
96 worker_thread_(rtc::Thread::Current()),
97 channel_(channel),
98 downward_(NULL),
99 ssl_role_(rtc::SSL_CLIENT),
100 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12) {
101 channel_->SignalWritableState.connect(this,
102 &DtlsTransportChannelWrapper::OnWritableState);
103 channel_->SignalReadPacket.connect(this,
104 &DtlsTransportChannelWrapper::OnReadPacket);
105 channel_->SignalSentPacket.connect(
106 this, &DtlsTransportChannelWrapper::OnSentPacket);
107 channel_->SignalReadyToSend.connect(this,
108 &DtlsTransportChannelWrapper::OnReadyToSend);
109 channel_->SignalGatheringState.connect(
110 this, &DtlsTransportChannelWrapper::OnGatheringState);
111 channel_->SignalCandidateGathered.connect(
112 this, &DtlsTransportChannelWrapper::OnCandidateGathered);
113 channel_->SignalRoleConflict.connect(this,
114 &DtlsTransportChannelWrapper::OnRoleConflict);
115 channel_->SignalRouteChange.connect(this,
116 &DtlsTransportChannelWrapper::OnRouteChange);
117 channel_->SignalConnectionRemoved.connect(this,
118 &DtlsTransportChannelWrapper::OnConnectionRemoved);
119 channel_->SignalReceivingState.connect(this,
120 &DtlsTransportChannelWrapper::OnReceivingState);
121 }
122
~DtlsTransportChannelWrapper()123 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
124 }
125
Connect()126 void DtlsTransportChannelWrapper::Connect() {
127 // We should only get a single call to Connect.
128 ASSERT(dtls_state() == DTLS_TRANSPORT_NEW);
129 channel_->Connect();
130 }
131
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)132 bool DtlsTransportChannelWrapper::SetLocalCertificate(
133 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
134 if (dtls_active_) {
135 if (certificate == local_certificate_) {
136 // This may happen during renegotiation.
137 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity";
138 return true;
139 } else {
140 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state";
141 return false;
142 }
143 }
144
145 if (certificate) {
146 local_certificate_ = certificate;
147 dtls_active_ = true;
148 } else {
149 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS";
150 }
151
152 return true;
153 }
154
155 rtc::scoped_refptr<rtc::RTCCertificate>
GetLocalCertificate() const156 DtlsTransportChannelWrapper::GetLocalCertificate() const {
157 return local_certificate_;
158 }
159
SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version)160 bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion(
161 rtc::SSLProtocolVersion version) {
162 if (dtls_active_) {
163 LOG(LS_ERROR) << "Not changing max. protocol version "
164 << "while DTLS is negotiating";
165 return false;
166 }
167
168 ssl_max_version_ = version;
169 return true;
170 }
171
SetSslRole(rtc::SSLRole role)172 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) {
173 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) {
174 if (ssl_role_ != role) {
175 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup.";
176 return false;
177 }
178 return true;
179 }
180
181 ssl_role_ = role;
182 return true;
183 }
184
GetSslRole(rtc::SSLRole * role) const185 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
186 *role = ssl_role_;
187 return true;
188 }
189
GetSslCipherSuite(int * cipher)190 bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) {
191 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) {
192 return false;
193 }
194
195 return dtls_->GetSslCipherSuite(cipher);
196 }
197
SetRemoteFingerprint(const std::string & digest_alg,const uint8_t * digest,size_t digest_len)198 bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
199 const std::string& digest_alg,
200 const uint8_t* digest,
201 size_t digest_len) {
202 rtc::Buffer remote_fingerprint_value(digest, digest_len);
203
204 // Once we have the local certificate, the same remote fingerprint can be set
205 // multiple times.
206 if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value &&
207 !digest_alg.empty()) {
208 // This may happen during renegotiation.
209 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint";
210 return true;
211 }
212
213 // If the other side doesn't support DTLS, turn off |dtls_active_|.
214 if (digest_alg.empty()) {
215 RTC_DCHECK(!digest_len);
216 LOG_J(LS_INFO, this) << "Other side didn't support DTLS.";
217 dtls_active_ = false;
218 return true;
219 }
220
221 // Otherwise, we must have a local certificate before setting remote
222 // fingerprint.
223 if (!dtls_active_) {
224 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state.";
225 return false;
226 }
227
228 // At this point we know we are doing DTLS
229 remote_fingerprint_value_ = std::move(remote_fingerprint_value);
230 remote_fingerprint_algorithm_ = digest_alg;
231
232 bool reconnect = dtls_;
233
234 if (!SetupDtls()) {
235 set_dtls_state(DTLS_TRANSPORT_FAILED);
236 return false;
237 }
238
239 if (reconnect) {
240 Reconnect();
241 }
242
243 return true;
244 }
245
GetRemoteSSLCertificate(rtc::SSLCertificate ** cert) const246 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate(
247 rtc::SSLCertificate** cert) const {
248 if (!dtls_) {
249 return false;
250 }
251
252 return dtls_->GetPeerCertificate(cert);
253 }
254
SetupDtls()255 bool DtlsTransportChannelWrapper::SetupDtls() {
256 StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_);
257
258 dtls_.reset(rtc::SSLStreamAdapter::Create(downward));
259 if (!dtls_) {
260 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter.";
261 delete downward;
262 return false;
263 }
264
265 downward_ = downward;
266
267 dtls_->SetIdentity(local_certificate_->identity()->GetReference());
268 dtls_->SetMode(rtc::SSL_MODE_DTLS);
269 dtls_->SetMaxProtocolVersion(ssl_max_version_);
270 dtls_->SetServerRole(ssl_role_);
271 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
272 if (!dtls_->SetPeerCertificateDigest(
273 remote_fingerprint_algorithm_,
274 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()),
275 remote_fingerprint_value_.size())) {
276 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest.";
277 return false;
278 }
279
280 // Set up DTLS-SRTP, if it's been enabled.
281 if (!srtp_ciphers_.empty()) {
282 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) {
283 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers.";
284 return false;
285 }
286 } else {
287 LOG_J(LS_INFO, this) << "Not using DTLS-SRTP.";
288 }
289
290 LOG_J(LS_INFO, this) << "DTLS setup complete.";
291 return true;
292 }
293
SetSrtpCryptoSuites(const std::vector<int> & ciphers)294 bool DtlsTransportChannelWrapper::SetSrtpCryptoSuites(
295 const std::vector<int>& ciphers) {
296 if (srtp_ciphers_ == ciphers)
297 return true;
298
299 if (dtls_state() == DTLS_TRANSPORT_CONNECTING) {
300 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating";
301 return true;
302 }
303
304 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) {
305 // We don't support DTLS renegotiation currently. If new set of srtp ciphers
306 // are different than what's being used currently, we will not use it.
307 // So for now, let's be happy (or sad) with a warning message.
308 int current_srtp_cipher;
309 if (!dtls_->GetDtlsSrtpCryptoSuite(¤t_srtp_cipher)) {
310 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
311 return false;
312 }
313 const std::vector<int>::const_iterator iter =
314 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher);
315 if (iter == ciphers.end()) {
316 std::string requested_str;
317 for (size_t i = 0; i < ciphers.size(); ++i) {
318 requested_str.append(" ");
319 requested_str.append(rtc::SrtpCryptoSuiteToName(ciphers[i]));
320 requested_str.append(" ");
321 }
322 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS "
323 << "renegotiation is not supported currently "
324 << "current cipher = " << current_srtp_cipher << " and "
325 << "requested = " << "[" << requested_str << "]";
326 }
327 return true;
328 }
329
330 if (!VERIFY(dtls_state() == DTLS_TRANSPORT_NEW)) {
331 return false;
332 }
333
334 srtp_ciphers_ = ciphers;
335 return true;
336 }
337
GetSrtpCryptoSuite(int * cipher)338 bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(int* cipher) {
339 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) {
340 return false;
341 }
342
343 return dtls_->GetDtlsSrtpCryptoSuite(cipher);
344 }
345
346
347 // Called from upper layers to send a media packet.
SendPacket(const char * data,size_t size,const rtc::PacketOptions & options,int flags)348 int DtlsTransportChannelWrapper::SendPacket(
349 const char* data, size_t size,
350 const rtc::PacketOptions& options, int flags) {
351 if (!dtls_active_) {
352 // Not doing DTLS.
353 return channel_->SendPacket(data, size, options);
354 }
355
356 switch (dtls_state()) {
357 case DTLS_TRANSPORT_NEW:
358 // Can't send data until the connection is active.
359 // TODO(ekr@rtfm.com): assert here if dtls_ is NULL?
360 return -1;
361 case DTLS_TRANSPORT_CONNECTING:
362 // Can't send data until the connection is active.
363 return -1;
364 case DTLS_TRANSPORT_CONNECTED:
365 if (flags & PF_SRTP_BYPASS) {
366 ASSERT(!srtp_ciphers_.empty());
367 if (!IsRtpPacket(data, size)) {
368 return -1;
369 }
370
371 return channel_->SendPacket(data, size, options);
372 } else {
373 return (dtls_->WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS)
374 ? static_cast<int>(size)
375 : -1;
376 }
377 case DTLS_TRANSPORT_FAILED:
378 case DTLS_TRANSPORT_CLOSED:
379 // Can't send anything when we're closed.
380 return -1;
381 default:
382 ASSERT(false);
383 return -1;
384 }
385 }
386
387 // The state transition logic here is as follows:
388 // (1) If we're not doing DTLS-SRTP, then the state is just the
389 // state of the underlying impl()
390 // (2) If we're doing DTLS-SRTP:
391 // - Prior to the DTLS handshake, the state is neither receiving nor
392 // writable
393 // - When the impl goes writable for the first time we
394 // start the DTLS handshake
395 // - Once the DTLS handshake completes, the state is that of the
396 // impl again
OnWritableState(TransportChannel * channel)397 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) {
398 ASSERT(rtc::Thread::Current() == worker_thread_);
399 ASSERT(channel == channel_);
400 LOG_J(LS_VERBOSE, this)
401 << "DTLSTransportChannelWrapper: channel writable state changed to "
402 << channel_->writable();
403
404 if (!dtls_active_) {
405 // Not doing DTLS.
406 // Note: SignalWritableState fired by set_writable.
407 set_writable(channel_->writable());
408 return;
409 }
410
411 switch (dtls_state()) {
412 case DTLS_TRANSPORT_NEW:
413 // This should never fail:
414 // Because we are operating in a nonblocking mode and all
415 // incoming packets come in via OnReadPacket(), which rejects
416 // packets in this state, the incoming queue must be empty. We
417 // ignore write errors, thus any errors must be because of
418 // configuration and therefore are our fault.
419 // Note that in non-debug configurations, failure in
420 // MaybeStartDtls() changes the state to DTLS_TRANSPORT_FAILED.
421 VERIFY(MaybeStartDtls());
422 break;
423 case DTLS_TRANSPORT_CONNECTED:
424 // Note: SignalWritableState fired by set_writable.
425 set_writable(channel_->writable());
426 break;
427 case DTLS_TRANSPORT_CONNECTING:
428 // Do nothing.
429 break;
430 case DTLS_TRANSPORT_FAILED:
431 case DTLS_TRANSPORT_CLOSED:
432 // Should not happen. Do nothing.
433 break;
434 }
435 }
436
OnReceivingState(TransportChannel * channel)437 void DtlsTransportChannelWrapper::OnReceivingState(TransportChannel* channel) {
438 ASSERT(rtc::Thread::Current() == worker_thread_);
439 ASSERT(channel == channel_);
440 LOG_J(LS_VERBOSE, this)
441 << "DTLSTransportChannelWrapper: channel receiving state changed to "
442 << channel_->receiving();
443 if (!dtls_active_ || dtls_state() == DTLS_TRANSPORT_CONNECTED) {
444 // Note: SignalReceivingState fired by set_receiving.
445 set_receiving(channel_->receiving());
446 }
447 }
448
OnReadPacket(TransportChannel * channel,const char * data,size_t size,const rtc::PacketTime & packet_time,int flags)449 void DtlsTransportChannelWrapper::OnReadPacket(
450 TransportChannel* channel, const char* data, size_t size,
451 const rtc::PacketTime& packet_time, int flags) {
452 ASSERT(rtc::Thread::Current() == worker_thread_);
453 ASSERT(channel == channel_);
454 ASSERT(flags == 0);
455
456 if (!dtls_active_) {
457 // Not doing DTLS.
458 SignalReadPacket(this, data, size, packet_time, 0);
459 return;
460 }
461
462 switch (dtls_state()) {
463 case DTLS_TRANSPORT_NEW:
464 if (dtls_) {
465 // Drop packets received before DTLS has actually started.
466 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
467 } else {
468 // Currently drop the packet, but we might in future
469 // decide to take this as evidence that the other
470 // side is ready to do DTLS and start the handshake
471 // on our end.
472 LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
473 << "doing DTLS or not; dropping.";
474 }
475 break;
476
477 case DTLS_TRANSPORT_CONNECTING:
478 case DTLS_TRANSPORT_CONNECTED:
479 // We should only get DTLS or SRTP packets; STUN's already been demuxed.
480 // Is this potentially a DTLS packet?
481 if (IsDtlsPacket(data, size)) {
482 if (!HandleDtlsPacket(data, size)) {
483 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet.";
484 return;
485 }
486 } else {
487 // Not a DTLS packet; our handshake should be complete by now.
488 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) {
489 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS "
490 << "complete.";
491 return;
492 }
493
494 // And it had better be a SRTP packet.
495 if (!IsRtpPacket(data, size)) {
496 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet.";
497 return;
498 }
499
500 // Sanity check.
501 ASSERT(!srtp_ciphers_.empty());
502
503 // Signal this upwards as a bypass packet.
504 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
505 }
506 break;
507 case DTLS_TRANSPORT_FAILED:
508 case DTLS_TRANSPORT_CLOSED:
509 // This shouldn't be happening. Drop the packet.
510 break;
511 }
512 }
513
OnSentPacket(TransportChannel * channel,const rtc::SentPacket & sent_packet)514 void DtlsTransportChannelWrapper::OnSentPacket(
515 TransportChannel* channel,
516 const rtc::SentPacket& sent_packet) {
517 ASSERT(rtc::Thread::Current() == worker_thread_);
518
519 SignalSentPacket(this, sent_packet);
520 }
521
OnReadyToSend(TransportChannel * channel)522 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
523 if (writable()) {
524 SignalReadyToSend(this);
525 }
526 }
527
OnDtlsEvent(rtc::StreamInterface * dtls,int sig,int err)528 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
529 int sig, int err) {
530 ASSERT(rtc::Thread::Current() == worker_thread_);
531 ASSERT(dtls == dtls_.get());
532 if (sig & rtc::SE_OPEN) {
533 // This is the first time.
534 LOG_J(LS_INFO, this) << "DTLS handshake complete.";
535 if (dtls_->GetState() == rtc::SS_OPEN) {
536 // The check for OPEN shouldn't be necessary but let's make
537 // sure we don't accidentally frob the state if it's closed.
538 set_dtls_state(DTLS_TRANSPORT_CONNECTED);
539 set_writable(true);
540 }
541 }
542 if (sig & rtc::SE_READ) {
543 char buf[kMaxDtlsPacketLen];
544 size_t read;
545 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) {
546 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
547 }
548 }
549 if (sig & rtc::SE_CLOSE) {
550 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself.
551 set_writable(false);
552 if (!err) {
553 LOG_J(LS_INFO, this) << "DTLS channel closed";
554 set_dtls_state(DTLS_TRANSPORT_CLOSED);
555 } else {
556 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
557 set_dtls_state(DTLS_TRANSPORT_FAILED);
558 }
559 }
560 }
561
MaybeStartDtls()562 bool DtlsTransportChannelWrapper::MaybeStartDtls() {
563 if (dtls_ && channel_->writable()) {
564 if (dtls_->StartSSLWithPeer()) {
565 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake";
566 set_dtls_state(DTLS_TRANSPORT_FAILED);
567 return false;
568 }
569 LOG_J(LS_INFO, this)
570 << "DtlsTransportChannelWrapper: Started DTLS handshake";
571 set_dtls_state(DTLS_TRANSPORT_CONNECTING);
572 }
573 return true;
574 }
575
576 // Called from OnReadPacket when a DTLS packet is received.
HandleDtlsPacket(const char * data,size_t size)577 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
578 size_t size) {
579 // Sanity check we're not passing junk that
580 // just looks like DTLS.
581 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data);
582 size_t tmp_size = size;
583 while (tmp_size > 0) {
584 if (tmp_size < kDtlsRecordHeaderLen)
585 return false; // Too short for the header
586
587 size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]);
588 if ((record_len + kDtlsRecordHeaderLen) > tmp_size)
589 return false; // Body too short
590
591 tmp_data += record_len + kDtlsRecordHeaderLen;
592 tmp_size -= record_len + kDtlsRecordHeaderLen;
593 }
594
595 // Looks good. Pass to the SIC which ends up being passed to
596 // the DTLS stack.
597 return downward_->OnPacketReceived(data, size);
598 }
599
OnGatheringState(TransportChannelImpl * channel)600 void DtlsTransportChannelWrapper::OnGatheringState(
601 TransportChannelImpl* channel) {
602 ASSERT(channel == channel_);
603 SignalGatheringState(this);
604 }
605
OnCandidateGathered(TransportChannelImpl * channel,const Candidate & c)606 void DtlsTransportChannelWrapper::OnCandidateGathered(
607 TransportChannelImpl* channel,
608 const Candidate& c) {
609 ASSERT(channel == channel_);
610 SignalCandidateGathered(this, c);
611 }
612
OnRoleConflict(TransportChannelImpl * channel)613 void DtlsTransportChannelWrapper::OnRoleConflict(
614 TransportChannelImpl* channel) {
615 ASSERT(channel == channel_);
616 SignalRoleConflict(this);
617 }
618
OnRouteChange(TransportChannel * channel,const Candidate & candidate)619 void DtlsTransportChannelWrapper::OnRouteChange(
620 TransportChannel* channel, const Candidate& candidate) {
621 ASSERT(channel == channel_);
622 SignalRouteChange(this, candidate);
623 }
624
OnConnectionRemoved(TransportChannelImpl * channel)625 void DtlsTransportChannelWrapper::OnConnectionRemoved(
626 TransportChannelImpl* channel) {
627 ASSERT(channel == channel_);
628 SignalConnectionRemoved(this);
629 }
630
Reconnect()631 void DtlsTransportChannelWrapper::Reconnect() {
632 set_dtls_state(DTLS_TRANSPORT_NEW);
633 set_writable(false);
634 if (channel_->writable()) {
635 OnWritableState(channel_);
636 }
637 }
638
639 } // namespace cricket
640