3 * Copyright 2011, Google Inc.
4 * Copyright 2011, RTFM, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
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.
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.
29 #include "webrtc/p2p/base/dtlstransportchannel.h"
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"
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;
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));
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);
55 rtc::StreamResult StreamInterfaceChannel::Read(void* buffer,
59 if (state_ == rtc::SS_CLOSED)
61 if (state_ == rtc::SS_OPENING)
64 return fifo_.Read(buffer, buffer_len, read, error);
67 rtc::StreamResult StreamInterfaceChannel::Write(const void* data,
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,
79 return rtc::SR_SUCCESS;
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
86 bool ret = (fifo_.WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS);
88 SignalEvent(this, rtc::SE_READ, 0);
93 void StreamInterfaceChannel::OnEvent(rtc::StreamInterface* stream,
95 SignalEvent(this, sig, err);
98 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
100 TransportChannelImpl* channel)
101 : TransportChannelImpl(channel->content_name(), channel->component()),
102 transport_(transport),
103 worker_thread_(rtc::Thread::Current()),
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);
131 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
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);
142 void DtlsTransportChannelWrapper::Reset() {
147 // Re-call SetupDtls()
149 LOG_J(LS_ERROR, this) << "Error re-initializing DTLS";
150 dtls_state_ = STATE_CLOSED;
154 dtls_state_ = STATE_ACCEPTED;
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";
165 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state";
171 local_identity_ = identity;
172 dtls_state_ = STATE_OFFERED;
174 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS";
180 bool DtlsTransportChannelWrapper::GetLocalIdentity(
181 rtc::SSLIdentity** identity) const {
182 if (!local_identity_)
185 *identity = local_identity_->GetReference();
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.";
202 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
207 bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
208 const std::string& digest_alg,
212 rtc::Buffer remote_fingerprint_value(digest, digest_len);
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";
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.";
230 if (digest_alg.empty()) {
231 LOG_J(LS_INFO, this) << "Other side didn't support DTLS.";
232 dtls_state_ = STATE_NONE;
236 // At this point we know we are doing DTLS
237 remote_fingerprint_value.TransferTo(&remote_fingerprint_value_);
238 remote_fingerprint_algorithm_ = digest_alg;
241 dtls_state_ = STATE_CLOSED;
245 dtls_state_ = STATE_ACCEPTED;
249 bool DtlsTransportChannelWrapper::GetRemoteCertificate(
250 rtc::SSLCertificate** cert) const {
254 return dtls_->GetPeerCertificate(cert);
257 bool DtlsTransportChannelWrapper::SetupDtls() {
258 StreamInterfaceChannel* downward =
259 new StreamInterfaceChannel(worker_thread_, channel_);
261 dtls_.reset(rtc::SSLStreamAdapter::Create(downward));
263 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter.";
268 downward_ = downward;
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.";
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.";
289 LOG_J(LS_INFO, this) << "Not using DTLS.";
292 LOG_J(LS_INFO, this) << "DTLS setup complete.";
296 bool DtlsTransportChannelWrapper::SetSrtpCiphers(
297 const std::vector<std::string>& ciphers) {
298 if (srtp_ciphers_ == ciphers)
301 if (dtls_state_ == STATE_STARTED) {
302 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating";
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(¤t_srtp_cipher)) {
312 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
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(" ");
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 << "]";
332 if (dtls_state_ != STATE_NONE &&
333 dtls_state_ != STATE_OFFERED &&
334 dtls_state_ != STATE_ACCEPTED) {
339 srtp_ciphers_ = ciphers;
343 bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
344 if (dtls_state_ != STATE_OPEN) {
348 return dtls_->GetDtlsSrtpCipher(cipher);
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) {
358 switch (dtls_state_) {
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?
367 // Can't send data until the connection is active
372 if (flags & PF_SRTP_BYPASS) {
373 ASSERT(!srtp_ciphers_.empty());
374 if (!IsRtpPacket(data, size)) {
379 result = channel_->SendPacket(data, size, options);
381 result = (dtls_->WriteAll(data, size, NULL, NULL) ==
382 rtc::SR_SUCCESS) ? static_cast<int>(size) : -1;
387 result = channel_->SendPacket(data, size, options);
390 case STATE_CLOSED: // Can't send anything when we're closed.
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
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
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.";
413 if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) {
414 set_readable(channel_->readable());
415 // Note: SignalReadableState fired by set_readable.
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.";
425 switch (dtls_state_) {
428 set_writable(channel_->writable());
429 // Note: SignalWritableState fired by set_writable.
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.
455 // Should not happen. Do nothing
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_);
467 switch (dtls_state_) {
469 // We are not doing DTLS
470 SignalReadPacket(this, data, size, packet_time, 0);
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
478 LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
479 << "doing DTLS or not; dropping.";
483 // Drop packets received before DTLS has actually started
484 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
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.";
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 "
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.";
511 ASSERT(!srtp_ciphers_.empty());
513 // Signal this upwards as a bypass packet.
514 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
518 // This shouldn't be happening. Drop the packet
523 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
525 SignalReadyToSend(this);
529 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
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;
545 if (sig & rtc::SE_READ) {
546 char buf[kMaxDtlsPacketLen];
548 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) {
549 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
552 if (sig & rtc::SE_CLOSE) {
553 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself.
555 LOG_J(LS_INFO, this) << "DTLS channel closed";
557 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
562 dtls_state_ = STATE_CLOSED;
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;
574 << "DtlsTransportChannelWrapper: Started DTLS handshake";
576 dtls_state_ = STATE_STARTED;
581 // Called from OnReadPacket when a DTLS packet is received.
582 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
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
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
596 tmp_data += record_len + kDtlsRecordHeaderLen;
597 tmp_size -= record_len + kDtlsRecordHeaderLen;
600 // Looks good. Pass to the SIC which ends up being passed to
602 return downward_->OnPacketReceived(data, size);
605 void DtlsTransportChannelWrapper::OnRequestSignaling(
606 TransportChannelImpl* channel) {
607 ASSERT(channel == channel_);
608 SignalRequestSignaling(this);
611 void DtlsTransportChannelWrapper::OnCandidateReady(
612 TransportChannelImpl* channel, const Candidate& c) {
613 ASSERT(channel == channel_);
614 SignalCandidateReady(this, c);
617 void DtlsTransportChannelWrapper::OnCandidatesAllocationDone(
618 TransportChannelImpl* channel) {
619 ASSERT(channel == channel_);
620 SignalCandidatesAllocationDone(this);
623 void DtlsTransportChannelWrapper::OnRoleConflict(
624 TransportChannelImpl* channel) {
625 ASSERT(channel == channel_);
626 SignalRoleConflict(this);
629 void DtlsTransportChannelWrapper::OnRouteChange(
630 TransportChannel* channel, const Candidate& candidate) {
631 ASSERT(channel == channel_);
632 SignalRouteChange(this, candidate);
635 void DtlsTransportChannelWrapper::OnConnectionRemoved(
636 TransportChannelImpl* channel) {
637 ASSERT(channel == channel_);
638 SignalConnectionRemoved(this);
641 } // namespace cricket