• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2011, Google Inc.
4  * Copyright 2011, RTFM, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright notice,
12  *     this list of conditions and the following disclaimer in the documentation
13  *     and/or other materials provided with the distribution.
14  *  3. The name of the author may not be used to endorse or promote products
15  *     derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "talk/p2p/base/dtlstransportchannel.h"
30 
31 #include "talk/base/buffer.h"
32 #include "talk/base/dscp.h"
33 #include "talk/base/messagequeue.h"
34 #include "talk/base/stream.h"
35 #include "talk/base/sslstreamadapter.h"
36 #include "talk/base/thread.h"
37 #include "talk/p2p/base/common.h"
38 
39 namespace cricket {
40 
41 // We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
42 static const size_t kDtlsRecordHeaderLen = 13;
43 static const size_t kMaxDtlsPacketLen = 2048;
44 static const size_t kMinRtpPacketLen = 12;
45 
IsDtlsPacket(const char * data,size_t len)46 static bool IsDtlsPacket(const char* data, size_t len) {
47   const uint8* u = reinterpret_cast<const uint8*>(data);
48   return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
49 }
IsRtpPacket(const char * data,size_t len)50 static bool IsRtpPacket(const char* data, size_t len) {
51   const uint8* u = reinterpret_cast<const uint8*>(data);
52   return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
53 }
54 
Read(void * buffer,size_t buffer_len,size_t * read,int * error)55 talk_base::StreamResult StreamInterfaceChannel::Read(void* buffer,
56                                                      size_t buffer_len,
57                                                      size_t* read,
58                                                      int* error) {
59   if (state_ == talk_base::SS_CLOSED)
60     return talk_base::SR_EOS;
61   if (state_ == talk_base::SS_OPENING)
62     return talk_base::SR_BLOCK;
63 
64   return fifo_.Read(buffer, buffer_len, read, error);
65 }
66 
Write(const void * data,size_t data_len,size_t * written,int * error)67 talk_base::StreamResult StreamInterfaceChannel::Write(const void* data,
68                                                       size_t data_len,
69                                                       size_t* written,
70                                                       int* error) {
71   // Always succeeds, since this is an unreliable transport anyway.
72   // TODO: Should this block if channel_'s temporarily unwritable?
73   talk_base::PacketOptions packet_options;
74   channel_->SendPacket(static_cast<const char*>(data), data_len,
75                        packet_options);
76   if (written) {
77     *written = data_len;
78   }
79   return talk_base::SR_SUCCESS;
80 }
81 
OnPacketReceived(const char * data,size_t size)82 bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) {
83   // We force a read event here to ensure that we don't overflow our FIFO.
84   // Under high packet rate this can occur if we wait for the FIFO to post its
85   // own SE_READ.
86   bool ret = (fifo_.WriteAll(data, size, NULL, NULL) == talk_base::SR_SUCCESS);
87   if (ret) {
88     SignalEvent(this, talk_base::SE_READ, 0);
89   }
90   return ret;
91 }
92 
OnEvent(talk_base::StreamInterface * stream,int sig,int err)93 void StreamInterfaceChannel::OnEvent(talk_base::StreamInterface* stream,
94                                      int sig, int err) {
95   SignalEvent(this, sig, err);
96 }
97 
DtlsTransportChannelWrapper(Transport * transport,TransportChannelImpl * channel)98 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
99                                            Transport* transport,
100                                            TransportChannelImpl* channel)
101     : TransportChannelImpl(channel->content_name(), channel->component()),
102       transport_(transport),
103       worker_thread_(talk_base::Thread::Current()),
104       channel_(channel),
105       downward_(NULL),
106       dtls_state_(STATE_NONE),
107       local_identity_(NULL),
108       ssl_role_(talk_base::SSL_CLIENT) {
109   channel_->SignalReadableState.connect(this,
110       &DtlsTransportChannelWrapper::OnReadableState);
111   channel_->SignalWritableState.connect(this,
112       &DtlsTransportChannelWrapper::OnWritableState);
113   channel_->SignalReadPacket.connect(this,
114       &DtlsTransportChannelWrapper::OnReadPacket);
115   channel_->SignalReadyToSend.connect(this,
116       &DtlsTransportChannelWrapper::OnReadyToSend);
117   channel_->SignalRequestSignaling.connect(this,
118       &DtlsTransportChannelWrapper::OnRequestSignaling);
119   channel_->SignalCandidateReady.connect(this,
120       &DtlsTransportChannelWrapper::OnCandidateReady);
121   channel_->SignalCandidatesAllocationDone.connect(this,
122       &DtlsTransportChannelWrapper::OnCandidatesAllocationDone);
123   channel_->SignalRoleConflict.connect(this,
124       &DtlsTransportChannelWrapper::OnRoleConflict);
125   channel_->SignalRouteChange.connect(this,
126       &DtlsTransportChannelWrapper::OnRouteChange);
127   channel_->SignalConnectionRemoved.connect(this,
128       &DtlsTransportChannelWrapper::OnConnectionRemoved);
129 }
130 
~DtlsTransportChannelWrapper()131 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
132 }
133 
Connect()134 void DtlsTransportChannelWrapper::Connect() {
135   // We should only get a single call to Connect.
136   ASSERT(dtls_state_ == STATE_NONE ||
137          dtls_state_ == STATE_OFFERED ||
138          dtls_state_ == STATE_ACCEPTED);
139   channel_->Connect();
140 }
141 
Reset()142 void DtlsTransportChannelWrapper::Reset() {
143   channel_->Reset();
144   set_writable(false);
145   set_readable(false);
146 
147   // Re-call SetupDtls()
148   if (!SetupDtls()) {
149     LOG_J(LS_ERROR, this) << "Error re-initializing DTLS";
150     dtls_state_ = STATE_CLOSED;
151     return;
152   }
153 
154   dtls_state_ = STATE_ACCEPTED;
155 }
156 
SetLocalIdentity(talk_base::SSLIdentity * identity)157 bool DtlsTransportChannelWrapper::SetLocalIdentity(
158     talk_base::SSLIdentity* identity) {
159   if (dtls_state_ != STATE_NONE) {
160     if (identity == local_identity_) {
161       // This may happen during renegotiation.
162       LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity";
163       return true;
164     } else {
165       LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state";
166       return false;
167     }
168   }
169 
170   if (identity) {
171     local_identity_ = identity;
172     dtls_state_ = STATE_OFFERED;
173   } else {
174     LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS";
175   }
176 
177   return true;
178 }
179 
GetLocalIdentity(talk_base::SSLIdentity ** identity) const180 bool DtlsTransportChannelWrapper::GetLocalIdentity(
181     talk_base::SSLIdentity** identity) const {
182   if (!local_identity_)
183     return false;
184 
185   *identity = local_identity_->GetReference();
186   return true;
187 }
188 
SetSslRole(talk_base::SSLRole role)189 bool DtlsTransportChannelWrapper::SetSslRole(talk_base::SSLRole role) {
190   if (dtls_state_ == STATE_OPEN) {
191     if (ssl_role_ != role) {
192       LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup.";
193       return false;
194     }
195     return true;
196   }
197 
198   ssl_role_ = role;
199   return true;
200 }
201 
GetSslRole(talk_base::SSLRole * role) const202 bool DtlsTransportChannelWrapper::GetSslRole(talk_base::SSLRole* role) const {
203   *role = ssl_role_;
204   return true;
205 }
206 
SetRemoteFingerprint(const std::string & digest_alg,const uint8 * digest,size_t digest_len)207 bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
208     const std::string& digest_alg,
209     const uint8* digest,
210     size_t digest_len) {
211 
212   talk_base::Buffer remote_fingerprint_value(digest, digest_len);
213 
214   if (dtls_state_ != STATE_NONE &&
215       remote_fingerprint_value_ == remote_fingerprint_value &&
216       !digest_alg.empty()) {
217     // This may happen during renegotiation.
218     LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint";
219     return true;
220   }
221 
222   // Allow SetRemoteFingerprint with a NULL digest even if SetLocalIdentity
223   // hasn't been called.
224   if (dtls_state_ > STATE_OFFERED ||
225       (dtls_state_ == STATE_NONE && !digest_alg.empty())) {
226     LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state.";
227     return false;
228   }
229 
230   if (digest_alg.empty()) {
231     LOG_J(LS_INFO, this) << "Other side didn't support DTLS.";
232     dtls_state_ = STATE_NONE;
233     return true;
234   }
235 
236   // At this point we know we are doing DTLS
237   remote_fingerprint_value.TransferTo(&remote_fingerprint_value_);
238   remote_fingerprint_algorithm_ = digest_alg;
239 
240   if (!SetupDtls()) {
241     dtls_state_ = STATE_CLOSED;
242     return false;
243   }
244 
245   dtls_state_ = STATE_ACCEPTED;
246   return true;
247 }
248 
GetRemoteCertificate(talk_base::SSLCertificate ** cert) const249 bool DtlsTransportChannelWrapper::GetRemoteCertificate(
250     talk_base::SSLCertificate** cert) const {
251   if (!dtls_)
252     return false;
253 
254   return dtls_->GetPeerCertificate(cert);
255 }
256 
SetupDtls()257 bool DtlsTransportChannelWrapper::SetupDtls() {
258   StreamInterfaceChannel* downward =
259       new StreamInterfaceChannel(worker_thread_, channel_);
260 
261   dtls_.reset(talk_base::SSLStreamAdapter::Create(downward));
262   if (!dtls_) {
263     LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter.";
264     delete downward;
265     return false;
266   }
267 
268   downward_ = downward;
269 
270   dtls_->SetIdentity(local_identity_->GetReference());
271   dtls_->SetMode(talk_base::SSL_MODE_DTLS);
272   dtls_->SetServerRole(ssl_role_);
273   dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
274   if (!dtls_->SetPeerCertificateDigest(
275           remote_fingerprint_algorithm_,
276           reinterpret_cast<unsigned char *>(remote_fingerprint_value_.data()),
277           remote_fingerprint_value_.length())) {
278     LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest.";
279     return false;
280   }
281 
282   // Set up DTLS-SRTP, if it's been enabled.
283   if (!srtp_ciphers_.empty()) {
284     if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) {
285       LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers.";
286       return false;
287     }
288   } else {
289     LOG_J(LS_INFO, this) << "Not using DTLS.";
290   }
291 
292   LOG_J(LS_INFO, this) << "DTLS setup complete.";
293   return true;
294 }
295 
SetSrtpCiphers(const std::vector<std::string> & ciphers)296 bool DtlsTransportChannelWrapper::SetSrtpCiphers(
297     const std::vector<std::string>& ciphers) {
298   if (srtp_ciphers_ == ciphers)
299     return true;
300 
301   if (dtls_state_ == STATE_OPEN) {
302     // We don't support DTLS renegotiation currently. If new set of srtp ciphers
303     // are different than what's being used currently, we will not use it.
304     // So for now, let's be happy (or sad) with a warning message.
305     std::string current_srtp_cipher;
306     if (!dtls_->GetDtlsSrtpCipher(&current_srtp_cipher)) {
307       LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
308       return false;
309     }
310     const std::vector<std::string>::const_iterator iter =
311         std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher);
312     if (iter == ciphers.end()) {
313       std::string requested_str;
314       for (size_t i = 0; i < ciphers.size(); ++i) {
315         requested_str.append(" ");
316         requested_str.append(ciphers[i]);
317         requested_str.append(" ");
318       }
319       LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS "
320                       << "renegotiation is not supported currently "
321                       << "current cipher = " << current_srtp_cipher << " and "
322                       << "requested = " << "[" << requested_str << "]";
323     }
324     return true;
325   }
326 
327   if (dtls_state_ != STATE_NONE &&
328       dtls_state_ != STATE_OFFERED &&
329       dtls_state_ != STATE_ACCEPTED) {
330     ASSERT(false);
331     return false;
332   }
333 
334   srtp_ciphers_ = ciphers;
335   return true;
336 }
337 
GetSrtpCipher(std::string * cipher)338 bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
339   if (dtls_state_ != STATE_OPEN) {
340     return false;
341   }
342 
343   return dtls_->GetDtlsSrtpCipher(cipher);
344 }
345 
346 
347 // Called from upper layers to send a media packet.
SendPacket(const char * data,size_t size,const talk_base::PacketOptions & options,int flags)348 int DtlsTransportChannelWrapper::SendPacket(
349     const char* data, size_t size,
350     const talk_base::PacketOptions& options, int flags) {
351   int result = -1;
352 
353   switch (dtls_state_) {
354     case STATE_OFFERED:
355       // We don't know if we are doing DTLS yet, so we can't send a packet.
356       // TODO(ekr@rtfm.com): assert here?
357       result = -1;
358       break;
359 
360     case STATE_STARTED:
361     case STATE_ACCEPTED:
362       // Can't send data until the connection is active
363       result = -1;
364       break;
365 
366     case STATE_OPEN:
367       if (flags & PF_SRTP_BYPASS) {
368         ASSERT(!srtp_ciphers_.empty());
369         if (!IsRtpPacket(data, size)) {
370           result = -1;
371           break;
372         }
373 
374         result = channel_->SendPacket(data, size, options);
375       } else {
376         result = (dtls_->WriteAll(data, size, NULL, NULL) ==
377           talk_base::SR_SUCCESS) ? static_cast<int>(size) : -1;
378       }
379       break;
380       // Not doing DTLS.
381     case STATE_NONE:
382       result = channel_->SendPacket(data, size, options);
383       break;
384 
385     case STATE_CLOSED:  // Can't send anything when we're closed.
386       return -1;
387   }
388 
389   return result;
390 }
391 
392 // The state transition logic here is as follows:
393 // (1) If we're not doing DTLS-SRTP, then the state is just the
394 //     state of the underlying impl()
395 // (2) If we're doing DTLS-SRTP:
396 //     - Prior to the DTLS handshake, the state is neither readable or
397 //       writable
398 //     - When the impl goes writable for the first time we
399 //       start the DTLS handshake
400 //     - Once the DTLS handshake completes, the state is that of the
401 //       impl again
OnReadableState(TransportChannel * channel)402 void DtlsTransportChannelWrapper::OnReadableState(TransportChannel* channel) {
403   ASSERT(talk_base::Thread::Current() == worker_thread_);
404   ASSERT(channel == channel_);
405   LOG_J(LS_VERBOSE, this)
406       << "DTLSTransportChannelWrapper: channel readable state changed.";
407 
408   if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) {
409     set_readable(channel_->readable());
410     // Note: SignalReadableState fired by set_readable.
411   }
412 }
413 
OnWritableState(TransportChannel * channel)414 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) {
415   ASSERT(talk_base::Thread::Current() == worker_thread_);
416   ASSERT(channel == channel_);
417   LOG_J(LS_VERBOSE, this)
418       << "DTLSTransportChannelWrapper: channel writable state changed.";
419 
420   switch (dtls_state_) {
421     case STATE_NONE:
422     case STATE_OPEN:
423       set_writable(channel_->writable());
424       // Note: SignalWritableState fired by set_writable.
425       break;
426 
427     case STATE_OFFERED:
428       // Do nothing
429       break;
430 
431     case STATE_ACCEPTED:
432       if (!MaybeStartDtls()) {
433         // This should never happen:
434         // Because we are operating in a nonblocking mode and all
435         // incoming packets come in via OnReadPacket(), which rejects
436         // packets in this state, the incoming queue must be empty. We
437         // ignore write errors, thus any errors must be because of
438         // configuration and therefore are our fault.
439         // Note that in non-debug configurations, failure in
440         // MaybeStartDtls() changes the state to STATE_CLOSED.
441         ASSERT(false);
442       }
443       break;
444 
445     case STATE_STARTED:
446       // Do nothing
447       break;
448 
449     case STATE_CLOSED:
450       // Should not happen. Do nothing
451       break;
452   }
453 }
454 
OnReadPacket(TransportChannel * channel,const char * data,size_t size,const talk_base::PacketTime & packet_time,int flags)455 void DtlsTransportChannelWrapper::OnReadPacket(
456     TransportChannel* channel, const char* data, size_t size,
457     const talk_base::PacketTime& packet_time, int flags) {
458   ASSERT(talk_base::Thread::Current() == worker_thread_);
459   ASSERT(channel == channel_);
460   ASSERT(flags == 0);
461 
462   switch (dtls_state_) {
463     case STATE_NONE:
464       // We are not doing DTLS
465       SignalReadPacket(this, data, size, packet_time, 0);
466       break;
467 
468     case STATE_OFFERED:
469       // Currently drop the packet, but we might in future
470       // decide to take this as evidence that the other
471       // side is ready to do DTLS and start the handshake
472       // on our end
473       LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
474                               << "doing DTLS or not; dropping.";
475       break;
476 
477     case STATE_ACCEPTED:
478       // Drop packets received before DTLS has actually started
479       LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
480       break;
481 
482     case STATE_STARTED:
483     case STATE_OPEN:
484       // We should only get DTLS or SRTP packets; STUN's already been demuxed.
485       // Is this potentially a DTLS packet?
486       if (IsDtlsPacket(data, size)) {
487         if (!HandleDtlsPacket(data, size)) {
488           LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet.";
489           return;
490         }
491       } else {
492         // Not a DTLS packet; our handshake should be complete by now.
493         if (dtls_state_ != STATE_OPEN) {
494           LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS "
495                                 << "complete.";
496           return;
497         }
498 
499         // And it had better be a SRTP packet.
500         if (!IsRtpPacket(data, size)) {
501           LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet.";
502           return;
503         }
504 
505         // Sanity check.
506         ASSERT(!srtp_ciphers_.empty());
507 
508         // Signal this upwards as a bypass packet.
509         SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
510       }
511       break;
512     case STATE_CLOSED:
513       // This shouldn't be happening. Drop the packet
514       break;
515   }
516 }
517 
OnReadyToSend(TransportChannel * channel)518 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
519   if (writable()) {
520     SignalReadyToSend(this);
521   }
522 }
523 
OnDtlsEvent(talk_base::StreamInterface * dtls,int sig,int err)524 void DtlsTransportChannelWrapper::OnDtlsEvent(talk_base::StreamInterface* dtls,
525                                               int sig, int err) {
526   ASSERT(talk_base::Thread::Current() == worker_thread_);
527   ASSERT(dtls == dtls_.get());
528   if (sig & talk_base::SE_OPEN) {
529     // This is the first time.
530     LOG_J(LS_INFO, this) << "DTLS handshake complete.";
531     if (dtls_->GetState() == talk_base::SS_OPEN) {
532       // The check for OPEN shouldn't be necessary but let's make
533       // sure we don't accidentally frob the state if it's closed.
534       dtls_state_ = STATE_OPEN;
535 
536       set_readable(true);
537       set_writable(true);
538     }
539   }
540   if (sig & talk_base::SE_READ) {
541     char buf[kMaxDtlsPacketLen];
542     size_t read;
543     if (dtls_->Read(buf, sizeof(buf), &read, NULL) == talk_base::SR_SUCCESS) {
544       SignalReadPacket(this, buf, read, talk_base::CreatePacketTime(0), 0);
545     }
546   }
547   if (sig & talk_base::SE_CLOSE) {
548     ASSERT(sig == talk_base::SE_CLOSE);  // SE_CLOSE should be by itself.
549     if (!err) {
550       LOG_J(LS_INFO, this) << "DTLS channel closed";
551     } else {
552       LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
553     }
554 
555     set_readable(false);
556     set_writable(false);
557     dtls_state_ = STATE_CLOSED;
558   }
559 }
560 
MaybeStartDtls()561 bool DtlsTransportChannelWrapper::MaybeStartDtls() {
562   if (channel_->writable()) {
563     if (dtls_->StartSSLWithPeer()) {
564       LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake";
565       dtls_state_ = STATE_CLOSED;
566       return false;
567     }
568     LOG_J(LS_INFO, this)
569       << "DtlsTransportChannelWrapper: Started DTLS handshake";
570 
571     dtls_state_ = STATE_STARTED;
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* tmp_data = reinterpret_cast<const uint8* >(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 
OnRequestSignaling(TransportChannelImpl * channel)600 void DtlsTransportChannelWrapper::OnRequestSignaling(
601     TransportChannelImpl* channel) {
602   ASSERT(channel == channel_);
603   SignalRequestSignaling(this);
604 }
605 
OnCandidateReady(TransportChannelImpl * channel,const Candidate & c)606 void DtlsTransportChannelWrapper::OnCandidateReady(
607     TransportChannelImpl* channel, const Candidate& c) {
608   ASSERT(channel == channel_);
609   SignalCandidateReady(this, c);
610 }
611 
OnCandidatesAllocationDone(TransportChannelImpl * channel)612 void DtlsTransportChannelWrapper::OnCandidatesAllocationDone(
613     TransportChannelImpl* channel) {
614   ASSERT(channel == channel_);
615   SignalCandidatesAllocationDone(this);
616 }
617 
OnRoleConflict(TransportChannelImpl * channel)618 void DtlsTransportChannelWrapper::OnRoleConflict(
619     TransportChannelImpl* channel) {
620   ASSERT(channel == channel_);
621   SignalRoleConflict(this);
622 }
623 
OnRouteChange(TransportChannel * channel,const Candidate & candidate)624 void DtlsTransportChannelWrapper::OnRouteChange(
625     TransportChannel* channel, const Candidate& candidate) {
626   ASSERT(channel == channel_);
627   SignalRouteChange(this, candidate);
628 }
629 
OnConnectionRemoved(TransportChannelImpl * channel)630 void DtlsTransportChannelWrapper::OnConnectionRemoved(
631     TransportChannelImpl* channel) {
632   ASSERT(channel == channel_);
633   SignalConnectionRemoved(this);
634 }
635 
636 }  // namespace cricket
637