10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2011, Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2011, RTFM, Inc. 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/dtlstransportchannel.h" 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/common.h" 322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/buffer.h" 332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/dscp.h" 342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/messagequeue.h" 352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/sslstreamadapter.h" 36cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/stream.h" 372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/thread.h" 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// We don't pull the RTP constants from rtputils.h, to avoid a layer violation. 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const size_t kDtlsRecordHeaderLen = 13; 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const size_t kMaxDtlsPacketLen = 2048; 4419f7dc99c2237edcf92563a6a099fb063edf5e8fjiayl@webrtc.orgstatic const size_t kMinRtpPacketLen = 12; 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool IsDtlsPacket(const char* data, size_t len) { 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* u = reinterpret_cast<const uint8*>(data); 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64)); 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5019f7dc99c2237edcf92563a6a099fb063edf5e8fjiayl@webrtc.orgstatic bool IsRtpPacket(const char* data, size_t len) { 5119f7dc99c2237edcf92563a6a099fb063edf5e8fjiayl@webrtc.org const uint8* u = reinterpret_cast<const uint8*>(data); 5219f7dc99c2237edcf92563a6a099fb063edf5e8fjiayl@webrtc.org return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80); 5319f7dc99c2237edcf92563a6a099fb063edf5e8fjiayl@webrtc.org} 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgrtc::StreamResult StreamInterfaceChannel::Read(void* buffer, 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t buffer_len, 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* read, 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int* error) { 592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (state_ == rtc::SS_CLOSED) 602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return rtc::SR_EOS; 612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (state_ == rtc::SS_OPENING) 622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return rtc::SR_BLOCK; 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return fifo_.Read(buffer, buffer_len, read, error); 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgrtc::StreamResult StreamInterfaceChannel::Write(const void* data, 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t data_len, 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* written, 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int* error) { 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Always succeeds, since this is an unreliable transport anyway. 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: Should this block if channel_'s temporarily unwritable? 732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::PacketOptions packet_options; 74f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org channel_->SendPacket(static_cast<const char*>(data), data_len, 75f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org packet_options); 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (written) { 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *written = data_len; 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 792a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return rtc::SR_SUCCESS; 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) { 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We force a read event here to ensure that we don't overflow our FIFO. 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Under high packet rate this can occur if we wait for the FIFO to post its 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // own SE_READ. 862a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org bool ret = (fifo_.WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS); 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org SignalEvent(this, rtc::SE_READ, 0); 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 932a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid StreamInterfaceChannel::OnEvent(rtc::StreamInterface* stream, 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int sig, int err) { 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalEvent(this, sig, err); 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgDtlsTransportChannelWrapper::DtlsTransportChannelWrapper( 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Transport* transport, 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel) 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : TransportChannelImpl(channel->content_name(), channel->component()), 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org transport_(transport), 1032a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org worker_thread_(rtc::Thread::Current()), 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_(channel), 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org downward_(NULL), 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_(STATE_NONE), 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org local_identity_(NULL), 1082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ssl_role_(rtc::SSL_CLIENT) { 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalReadableState.connect(this, 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnReadableState); 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalWritableState.connect(this, 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnWritableState); 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalReadPacket.connect(this, 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnReadPacket); 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalReadyToSend.connect(this, 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnReadyToSend); 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalRequestSignaling.connect(this, 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnRequestSignaling); 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalCandidateReady.connect(this, 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnCandidateReady); 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalCandidatesAllocationDone.connect(this, 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnCandidatesAllocationDone); 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalRoleConflict.connect(this, 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnRoleConflict); 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalRouteChange.connect(this, 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &DtlsTransportChannelWrapper::OnRouteChange); 127f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org channel_->SignalConnectionRemoved.connect(this, 128f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org &DtlsTransportChannelWrapper::OnConnectionRemoved); 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgDtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::Connect() { 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We should only get a single call to Connect. 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(dtls_state_ == STATE_NONE || 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ == STATE_OFFERED || 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ == STATE_ACCEPTED); 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->Connect(); 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::Reset() { 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->Reset(); 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_writable(false); 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_readable(false); 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Re-call SetupDtls() 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!SetupDtls()) { 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_ERROR, this) << "Error re-initializing DTLS"; 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_CLOSED; 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_ACCEPTED; 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 157e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.orgbool DtlsTransportChannelWrapper::SetLocalIdentity( 1582a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SSLIdentity* identity) { 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ != STATE_NONE) { 160f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org if (identity == local_identity_) { 161f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org // This may happen during renegotiation. 162f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity"; 163f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org return true; 164f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org } else { 165f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state"; 166f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org return false; 167f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org } 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (identity) { 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org local_identity_ = identity; 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_OFFERED; 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS"; 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgbool DtlsTransportChannelWrapper::GetLocalIdentity( 1812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SSLIdentity** identity) const { 18262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org if (!local_identity_) 18362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return false; 18462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 18562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org *identity = local_identity_->GetReference(); 18662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return true; 18762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org} 18862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 1892a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { 190a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org if (dtls_state_ == STATE_OPEN) { 191a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org if (ssl_role_ != role) { 192a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; 193a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return false; 194a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org } 195a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return true; 196a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org } 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 198a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org ssl_role_ = role; 199a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return true; 200a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org} 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const { 203a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org *role = ssl_role_; 204a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return true; 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 207e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.orgbool DtlsTransportChannelWrapper::SetRemoteFingerprint( 208e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org const std::string& digest_alg, 209e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org const uint8* digest, 210e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org size_t digest_len) { 211e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org 2122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer remote_fingerprint_value(digest, digest_len); 213e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org 214b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org if (dtls_state_ != STATE_NONE && 215b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org remote_fingerprint_value_ == remote_fingerprint_value && 216b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org !digest_alg.empty()) { 217b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org // This may happen during renegotiation. 218b9a6b71b8a8db9a3a8e8888448529f9b4624ab32jiayl@webrtc.org LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; 219e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org return true; 220e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org } 221e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Allow SetRemoteFingerprint with a NULL digest even if SetLocalIdentity 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // hasn't been called. 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ > STATE_OFFERED || 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (dtls_state_ == STATE_NONE && !digest_alg.empty())) { 226a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (digest_alg.empty()) { 231a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_NONE; 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // At this point we know we are doing DTLS 237e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org remote_fingerprint_value.TransferTo(&remote_fingerprint_value_); 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_fingerprint_algorithm_ = digest_alg; 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!SetupDtls()) { 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_CLOSED; 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_ACCEPTED; 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgbool DtlsTransportChannelWrapper::GetRemoteCertificate( 2502a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SSLCertificate** cert) const { 25162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org if (!dtls_) 25262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return false; 25362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 25462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return dtls_->GetPeerCertificate(cert); 25562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org} 25662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool DtlsTransportChannelWrapper::SetupDtls() { 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StreamInterfaceChannel* downward = 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org new StreamInterfaceChannel(worker_thread_, channel_); 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org dtls_.reset(rtc::SSLStreamAdapter::Create(downward)); 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!dtls_) { 263a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter."; 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete downward; 2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org downward_ = downward; 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_->SetIdentity(local_identity_->GetReference()); 2712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org dtls_->SetMode(rtc::SSL_MODE_DTLS); 272a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org dtls_->SetServerRole(ssl_role_); 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent); 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!dtls_->SetPeerCertificateDigest( 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_fingerprint_algorithm_, 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org reinterpret_cast<unsigned char *>(remote_fingerprint_value_.data()), 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_fingerprint_value_.length())) { 278a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set up DTLS-SRTP, if it's been enabled. 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!srtp_ciphers_.empty()) { 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { 285a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 289a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_INFO, this) << "Not using DTLS."; 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 292a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_INFO, this) << "DTLS setup complete."; 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2968841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.orgbool DtlsTransportChannelWrapper::SetSrtpCiphers( 2978841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org const std::vector<std::string>& ciphers) { 2988841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org if (srtp_ciphers_ == ciphers) 2998841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org return true; 3008841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org 30152e2af0918cd38cdde42d9d77b7c32685a3e1e50buildbot@webrtc.org if (dtls_state_ == STATE_STARTED) { 30252e2af0918cd38cdde42d9d77b7c32685a3e1e50buildbot@webrtc.org LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; 30352e2af0918cd38cdde42d9d77b7c32685a3e1e50buildbot@webrtc.org return true; 30452e2af0918cd38cdde42d9d77b7c32685a3e1e50buildbot@webrtc.org } 30552e2af0918cd38cdde42d9d77b7c32685a3e1e50buildbot@webrtc.org 3068841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org if (dtls_state_ == STATE_OPEN) { 3078841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org // We don't support DTLS renegotiation currently. If new set of srtp ciphers 3088841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org // are different than what's being used currently, we will not use it. 3098841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org // So for now, let's be happy (or sad) with a warning message. 3108841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org std::string current_srtp_cipher; 3118841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { 3128841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; 3138841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org return false; 3148841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org } 3158841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org const std::vector<std::string>::const_iterator iter = 3168841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); 3178841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org if (iter == ciphers.end()) { 3188841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org std::string requested_str; 3198841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org for (size_t i = 0; i < ciphers.size(); ++i) { 3208841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org requested_str.append(" "); 3218841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org requested_str.append(ciphers[i]); 3228841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org requested_str.append(" "); 3238841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org } 3248841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " 3258841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org << "renegotiation is not supported currently " 3268841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org << "current cipher = " << current_srtp_cipher << " and " 3278841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org << "requested = " << "[" << requested_str << "]"; 3288841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org } 3298841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org return true; 3308841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org } 3318841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ != STATE_NONE && 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ != STATE_OFFERED && 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ != STATE_ACCEPTED) { 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org srtp_ciphers_ = ciphers; 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) { 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ != STATE_OPEN) { 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return dtls_->GetDtlsSrtpCipher(cipher); 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Called from upper layers to send a media packet. 353f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.orgint DtlsTransportChannelWrapper::SendPacket( 354f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org const char* data, size_t size, 3552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options, int flags) { 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int result = -1; 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (dtls_state_) { 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OFFERED: 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We don't know if we are doing DTLS yet, so we can't send a packet. 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(ekr@rtfm.com): assert here? 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = -1; 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_STARTED: 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_ACCEPTED: 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Can't send data until the connection is active 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = -1; 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OPEN: 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (flags & PF_SRTP_BYPASS) { 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(!srtp_ciphers_.empty()); 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsRtpPacket(data, size)) { 375ac12b50104a35b42ff49d847bd4c01782d0434afjiayl@webrtc.org result = -1; 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 379f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org result = channel_->SendPacket(data, size, options); 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = (dtls_->WriteAll(data, size, NULL, NULL) == 3822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SR_SUCCESS) ? static_cast<int>(size) : -1; 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Not doing DTLS. 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_NONE: 387f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org result = channel_->SendPacket(data, size, options); 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_CLOSED: // Can't send anything when we're closed. 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return -1; 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return result; 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// The state transition logic here is as follows: 3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// (1) If we're not doing DTLS-SRTP, then the state is just the 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// state of the underlying impl() 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// (2) If we're doing DTLS-SRTP: 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// - Prior to the DTLS handshake, the state is neither readable or 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// writable 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// - When the impl goes writable for the first time we 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// start the DTLS handshake 4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// - Once the DTLS handshake completes, the state is that of the 4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// impl again 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnReadableState(TransportChannel* channel) { 4082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ASSERT(rtc::Thread::Current() == worker_thread_); 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_VERBOSE, this) 411a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org << "DTLSTransportChannelWrapper: channel readable state changed."; 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) { 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_readable(channel_->readable()); 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note: SignalReadableState fired by set_readable. 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) { 4202a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ASSERT(rtc::Thread::Current() == worker_thread_); 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_VERBOSE, this) 423a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org << "DTLSTransportChannelWrapper: channel writable state changed."; 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (dtls_state_) { 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_NONE: 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OPEN: 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_writable(channel_->writable()); 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note: SignalWritableState fired by set_writable. 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OFFERED: 4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Do nothing 4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_ACCEPTED: 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!MaybeStartDtls()) { 4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This should never happen: 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Because we are operating in a nonblocking mode and all 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // incoming packets come in via OnReadPacket(), which rejects 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // packets in this state, the incoming queue must be empty. We 4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ignore write errors, thus any errors must be because of 4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // configuration and therefore are our fault. 4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note that in non-debug configurations, failure in 4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // MaybeStartDtls() changes the state to STATE_CLOSED. 4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_STARTED: 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Do nothing 4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_CLOSED: 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Should not happen. Do nothing 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 460f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.orgvoid DtlsTransportChannelWrapper::OnReadPacket( 461f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org TransportChannel* channel, const char* data, size_t size, 4622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time, int flags) { 4632a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ASSERT(rtc::Thread::Current() == worker_thread_); 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(flags == 0); 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (dtls_state_) { 4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_NONE: 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We are not doing DTLS 470f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org SignalReadPacket(this, data, size, packet_time, 0); 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OFFERED: 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Currently drop the packet, but we might in future 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // decide to take this as evidence that the other 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // side is ready to do DTLS and start the handshake 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // on our end 478a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_WARNING, this) << "Received packet before we know if we are " 479a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org << "doing DTLS or not; dropping."; 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_ACCEPTED: 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Drop packets received before DTLS has actually started 484a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_STARTED: 4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_OPEN: 4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We should only get DTLS or SRTP packets; STUN's already been demuxed. 4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Is this potentially a DTLS packet? 4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsDtlsPacket(data, size)) { 4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!HandleDtlsPacket(data, size)) { 493a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Not a DTLS packet; our handshake should be complete by now. 4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_state_ != STATE_OPEN) { 499a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS " 500a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org << "complete."; 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // And it had better be a SRTP packet. 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsRtpPacket(data, size)) { 506a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet."; 5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sanity check. 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(!srtp_ciphers_.empty()); 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Signal this upwards as a bypass packet. 514f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS); 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case STATE_CLOSED: 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This shouldn't be happening. Drop the packet 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) { 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (writable()) { 5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalReadyToSend(this); 5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, 5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int sig, int err) { 5312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ASSERT(rtc::Thread::Current() == worker_thread_); 5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(dtls == dtls_.get()); 5332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (sig & rtc::SE_OPEN) { 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This is the first time. 535a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org LOG_J(LS_INFO, this) << "DTLS handshake complete."; 5362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (dtls_->GetState() == rtc::SS_OPEN) { 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The check for OPEN shouldn't be necessary but let's make 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // sure we don't accidentally frob the state if it's closed. 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_OPEN; 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_readable(true); 5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_writable(true); 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (sig & rtc::SE_READ) { 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org char buf[kMaxDtlsPacketLen]; 5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t read; 5482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { 5492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (sig & rtc::SE_CLOSE) { 5532a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!err) { 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, this) << "DTLS channel closed"; 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_readable(false); 5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org set_writable(false); 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_CLOSED; 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool DtlsTransportChannelWrapper::MaybeStartDtls() { 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel_->writable()) { 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dtls_->StartSSLWithPeer()) { 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_CLOSED; 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, this) 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "DtlsTransportChannelWrapper: Started DTLS handshake"; 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtls_state_ = STATE_STARTED; 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Called from OnReadPacket when a DTLS packet is received. 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t size) { 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sanity check we're not passing junk that 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // just looks like DTLS. 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const uint8* tmp_data = reinterpret_cast<const uint8* >(data); 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t tmp_size = size; 5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org while (tmp_size > 0) { 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tmp_size < kDtlsRecordHeaderLen) 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; // Too short for the header 5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]); 5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((record_len + kDtlsRecordHeaderLen) > tmp_size) 5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; // Body too short 5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tmp_data += record_len + kDtlsRecordHeaderLen; 5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tmp_size -= record_len + kDtlsRecordHeaderLen; 5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Looks good. Pass to the SIC which ends up being passed to 6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the DTLS stack. 6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return downward_->OnPacketReceived(data, size); 6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnRequestSignaling( 6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel) { 6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRequestSignaling(this); 6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnCandidateReady( 6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel, const Candidate& c) { 6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidateReady(this, c); 6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnCandidatesAllocationDone( 6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel) { 6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesAllocationDone(this); 6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnRoleConflict( 6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel) { 6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRoleConflict(this); 6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid DtlsTransportChannelWrapper::OnRouteChange( 6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannel* channel, const Candidate& candidate) { 6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRouteChange(this, candidate); 6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 635f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.orgvoid DtlsTransportChannelWrapper::OnConnectionRemoved( 636f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org TransportChannelImpl* channel) { 637f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org ASSERT(channel == channel_); 638f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org SignalConnectionRemoved(this); 639f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org} 640f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org 6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 642