• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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