Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / dtlstransportchannel.cc
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 "webrtc/p2p/base/dtlstransportchannel.h"
30
31 #include "webrtc/p2p/base/common.h"
32 #include "webrtc/base/buffer.h"
33 #include "webrtc/base/dscp.h"
34 #include "webrtc/base/messagequeue.h"
35 #include "webrtc/base/sslstreamadapter.h"
36 #include "webrtc/base/stream.h"
37 #include "webrtc/base/thread.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
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 }
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
55 rtc::StreamResult StreamInterfaceChannel::Read(void* buffer,
56                                                      size_t buffer_len,
57                                                      size_t* read,
58                                                      int* error) {
59   if (state_ == rtc::SS_CLOSED)
60     return rtc::SR_EOS;
61   if (state_ == rtc::SS_OPENING)
62     return rtc::SR_BLOCK;
63
64   return fifo_.Read(buffer, buffer_len, read, error);
65 }
66
67 rtc::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   rtc::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 rtc::SR_SUCCESS;
80 }
81
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) == rtc::SR_SUCCESS);
87   if (ret) {
88     SignalEvent(this, rtc::SE_READ, 0);
89   }
90   return ret;
91 }
92
93 void StreamInterfaceChannel::OnEvent(rtc::StreamInterface* stream,
94                                      int sig, int err) {
95   SignalEvent(this, sig, err);
96 }
97
98 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
99                                            Transport* transport,
100                                            TransportChannelImpl* channel)
101     : TransportChannelImpl(channel->content_name(), channel->component()),
102       transport_(transport),
103       worker_thread_(rtc::Thread::Current()),
104       channel_(channel),
105       downward_(NULL),
106       dtls_state_(STATE_NONE),
107       local_identity_(NULL),
108       ssl_role_(rtc::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
131 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
132 }
133
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
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
157 bool DtlsTransportChannelWrapper::SetLocalIdentity(
158     rtc::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
180 bool DtlsTransportChannelWrapper::GetLocalIdentity(
181     rtc::SSLIdentity** identity) const {
182   if (!local_identity_)
183     return false;
184
185   *identity = local_identity_->GetReference();
186   return true;
187 }
188
189 bool DtlsTransportChannelWrapper::SetSslRole(rtc::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
202 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
203   *role = ssl_role_;
204   return true;
205 }
206
207 bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
208     const std::string& digest_alg,
209     const uint8* digest,
210     size_t digest_len) {
211
212   rtc::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
249 bool DtlsTransportChannelWrapper::GetRemoteCertificate(
250     rtc::SSLCertificate** cert) const {
251   if (!dtls_)
252     return false;
253
254   return dtls_->GetPeerCertificate(cert);
255 }
256
257 bool DtlsTransportChannelWrapper::SetupDtls() {
258   StreamInterfaceChannel* downward =
259       new StreamInterfaceChannel(worker_thread_, channel_);
260
261   dtls_.reset(rtc::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(rtc::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
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_STARTED) {
302     LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating";
303     return true;
304   }
305
306   if (dtls_state_ == STATE_OPEN) {
307     // We don't support DTLS renegotiation currently. If new set of srtp ciphers
308     // are different than what's being used currently, we will not use it.
309     // So for now, let's be happy (or sad) with a warning message.
310     std::string current_srtp_cipher;
311     if (!dtls_->GetDtlsSrtpCipher(&current_srtp_cipher)) {
312       LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
313       return false;
314     }
315     const std::vector<std::string>::const_iterator iter =
316         std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher);
317     if (iter == ciphers.end()) {
318       std::string requested_str;
319       for (size_t i = 0; i < ciphers.size(); ++i) {
320         requested_str.append(" ");
321         requested_str.append(ciphers[i]);
322         requested_str.append(" ");
323       }
324       LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS "
325                       << "renegotiation is not supported currently "
326                       << "current cipher = " << current_srtp_cipher << " and "
327                       << "requested = " << "[" << requested_str << "]";
328     }
329     return true;
330   }
331
332   if (dtls_state_ != STATE_NONE &&
333       dtls_state_ != STATE_OFFERED &&
334       dtls_state_ != STATE_ACCEPTED) {
335     ASSERT(false);
336     return false;
337   }
338
339   srtp_ciphers_ = ciphers;
340   return true;
341 }
342
343 bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
344   if (dtls_state_ != STATE_OPEN) {
345     return false;
346   }
347
348   return dtls_->GetDtlsSrtpCipher(cipher);
349 }
350
351
352 // Called from upper layers to send a media packet.
353 int DtlsTransportChannelWrapper::SendPacket(
354     const char* data, size_t size,
355     const rtc::PacketOptions& options, int flags) {
356   int result = -1;
357
358   switch (dtls_state_) {
359     case STATE_OFFERED:
360       // We don't know if we are doing DTLS yet, so we can't send a packet.
361       // TODO(ekr@rtfm.com): assert here?
362       result = -1;
363       break;
364
365     case STATE_STARTED:
366     case STATE_ACCEPTED:
367       // Can't send data until the connection is active
368       result = -1;
369       break;
370
371     case STATE_OPEN:
372       if (flags & PF_SRTP_BYPASS) {
373         ASSERT(!srtp_ciphers_.empty());
374         if (!IsRtpPacket(data, size)) {
375           result = -1;
376           break;
377         }
378
379         result = channel_->SendPacket(data, size, options);
380       } else {
381         result = (dtls_->WriteAll(data, size, NULL, NULL) ==
382           rtc::SR_SUCCESS) ? static_cast<int>(size) : -1;
383       }
384       break;
385       // Not doing DTLS.
386     case STATE_NONE:
387       result = channel_->SendPacket(data, size, options);
388       break;
389
390     case STATE_CLOSED:  // Can't send anything when we're closed.
391       return -1;
392   }
393
394   return result;
395 }
396
397 // The state transition logic here is as follows:
398 // (1) If we're not doing DTLS-SRTP, then the state is just the
399 //     state of the underlying impl()
400 // (2) If we're doing DTLS-SRTP:
401 //     - Prior to the DTLS handshake, the state is neither readable or
402 //       writable
403 //     - When the impl goes writable for the first time we
404 //       start the DTLS handshake
405 //     - Once the DTLS handshake completes, the state is that of the
406 //       impl again
407 void DtlsTransportChannelWrapper::OnReadableState(TransportChannel* channel) {
408   ASSERT(rtc::Thread::Current() == worker_thread_);
409   ASSERT(channel == channel_);
410   LOG_J(LS_VERBOSE, this)
411       << "DTLSTransportChannelWrapper: channel readable state changed.";
412
413   if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) {
414     set_readable(channel_->readable());
415     // Note: SignalReadableState fired by set_readable.
416   }
417 }
418
419 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) {
420   ASSERT(rtc::Thread::Current() == worker_thread_);
421   ASSERT(channel == channel_);
422   LOG_J(LS_VERBOSE, this)
423       << "DTLSTransportChannelWrapper: channel writable state changed.";
424
425   switch (dtls_state_) {
426     case STATE_NONE:
427     case STATE_OPEN:
428       set_writable(channel_->writable());
429       // Note: SignalWritableState fired by set_writable.
430       break;
431
432     case STATE_OFFERED:
433       // Do nothing
434       break;
435
436     case STATE_ACCEPTED:
437       if (!MaybeStartDtls()) {
438         // This should never happen:
439         // Because we are operating in a nonblocking mode and all
440         // incoming packets come in via OnReadPacket(), which rejects
441         // packets in this state, the incoming queue must be empty. We
442         // ignore write errors, thus any errors must be because of
443         // configuration and therefore are our fault.
444         // Note that in non-debug configurations, failure in
445         // MaybeStartDtls() changes the state to STATE_CLOSED.
446         ASSERT(false);
447       }
448       break;
449
450     case STATE_STARTED:
451       // Do nothing
452       break;
453
454     case STATE_CLOSED:
455       // Should not happen. Do nothing
456       break;
457   }
458 }
459
460 void DtlsTransportChannelWrapper::OnReadPacket(
461     TransportChannel* channel, const char* data, size_t size,
462     const rtc::PacketTime& packet_time, int flags) {
463   ASSERT(rtc::Thread::Current() == worker_thread_);
464   ASSERT(channel == channel_);
465   ASSERT(flags == 0);
466
467   switch (dtls_state_) {
468     case STATE_NONE:
469       // We are not doing DTLS
470       SignalReadPacket(this, data, size, packet_time, 0);
471       break;
472
473     case STATE_OFFERED:
474       // Currently drop the packet, but we might in future
475       // decide to take this as evidence that the other
476       // side is ready to do DTLS and start the handshake
477       // on our end
478       LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
479                               << "doing DTLS or not; dropping.";
480       break;
481
482     case STATE_ACCEPTED:
483       // Drop packets received before DTLS has actually started
484       LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
485       break;
486
487     case STATE_STARTED:
488     case STATE_OPEN:
489       // We should only get DTLS or SRTP packets; STUN's already been demuxed.
490       // Is this potentially a DTLS packet?
491       if (IsDtlsPacket(data, size)) {
492         if (!HandleDtlsPacket(data, size)) {
493           LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet.";
494           return;
495         }
496       } else {
497         // Not a DTLS packet; our handshake should be complete by now.
498         if (dtls_state_ != STATE_OPEN) {
499           LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS "
500                                 << "complete.";
501           return;
502         }
503
504         // And it had better be a SRTP packet.
505         if (!IsRtpPacket(data, size)) {
506           LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet.";
507           return;
508         }
509
510         // Sanity check.
511         ASSERT(!srtp_ciphers_.empty());
512
513         // Signal this upwards as a bypass packet.
514         SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
515       }
516       break;
517     case STATE_CLOSED:
518       // This shouldn't be happening. Drop the packet
519       break;
520   }
521 }
522
523 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
524   if (writable()) {
525     SignalReadyToSend(this);
526   }
527 }
528
529 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
530                                               int sig, int err) {
531   ASSERT(rtc::Thread::Current() == worker_thread_);
532   ASSERT(dtls == dtls_.get());
533   if (sig & rtc::SE_OPEN) {
534     // This is the first time.
535     LOG_J(LS_INFO, this) << "DTLS handshake complete.";
536     if (dtls_->GetState() == rtc::SS_OPEN) {
537       // The check for OPEN shouldn't be necessary but let's make
538       // sure we don't accidentally frob the state if it's closed.
539       dtls_state_ = STATE_OPEN;
540
541       set_readable(true);
542       set_writable(true);
543     }
544   }
545   if (sig & rtc::SE_READ) {
546     char buf[kMaxDtlsPacketLen];
547     size_t read;
548     if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) {
549       SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
550     }
551   }
552   if (sig & rtc::SE_CLOSE) {
553     ASSERT(sig == rtc::SE_CLOSE);  // SE_CLOSE should be by itself.
554     if (!err) {
555       LOG_J(LS_INFO, this) << "DTLS channel closed";
556     } else {
557       LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
558     }
559
560     set_readable(false);
561     set_writable(false);
562     dtls_state_ = STATE_CLOSED;
563   }
564 }
565
566 bool DtlsTransportChannelWrapper::MaybeStartDtls() {
567   if (channel_->writable()) {
568     if (dtls_->StartSSLWithPeer()) {
569       LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake";
570       dtls_state_ = STATE_CLOSED;
571       return false;
572     }
573     LOG_J(LS_INFO, this)
574       << "DtlsTransportChannelWrapper: Started DTLS handshake";
575
576     dtls_state_ = STATE_STARTED;
577   }
578   return true;
579 }
580
581 // Called from OnReadPacket when a DTLS packet is received.
582 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
583                                                    size_t size) {
584   // Sanity check we're not passing junk that
585   // just looks like DTLS.
586   const uint8* tmp_data = reinterpret_cast<const uint8* >(data);
587   size_t tmp_size = size;
588   while (tmp_size > 0) {
589     if (tmp_size < kDtlsRecordHeaderLen)
590       return false;  // Too short for the header
591
592     size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]);
593     if ((record_len + kDtlsRecordHeaderLen) > tmp_size)
594       return false;  // Body too short
595
596     tmp_data += record_len + kDtlsRecordHeaderLen;
597     tmp_size -= record_len + kDtlsRecordHeaderLen;
598   }
599
600   // Looks good. Pass to the SIC which ends up being passed to
601   // the DTLS stack.
602   return downward_->OnPacketReceived(data, size);
603 }
604
605 void DtlsTransportChannelWrapper::OnRequestSignaling(
606     TransportChannelImpl* channel) {
607   ASSERT(channel == channel_);
608   SignalRequestSignaling(this);
609 }
610
611 void DtlsTransportChannelWrapper::OnCandidateReady(
612     TransportChannelImpl* channel, const Candidate& c) {
613   ASSERT(channel == channel_);
614   SignalCandidateReady(this, c);
615 }
616
617 void DtlsTransportChannelWrapper::OnCandidatesAllocationDone(
618     TransportChannelImpl* channel) {
619   ASSERT(channel == channel_);
620   SignalCandidatesAllocationDone(this);
621 }
622
623 void DtlsTransportChannelWrapper::OnRoleConflict(
624     TransportChannelImpl* channel) {
625   ASSERT(channel == channel_);
626   SignalRoleConflict(this);
627 }
628
629 void DtlsTransportChannelWrapper::OnRouteChange(
630     TransportChannel* channel, const Candidate& candidate) {
631   ASSERT(channel == channel_);
632   SignalRouteChange(this, candidate);
633 }
634
635 void DtlsTransportChannelWrapper::OnConnectionRemoved(
636     TransportChannelImpl* channel) {
637   ASSERT(channel == channel_);
638   SignalConnectionRemoved(this);
639 }
640
641 }  // namespace cricket