2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "webrtc/p2p/base/dtlstransportchannel.h"
13 #include "webrtc/p2p/base/common.h"
14 #include "webrtc/base/buffer.h"
15 #include "webrtc/base/dscp.h"
16 #include "webrtc/base/messagequeue.h"
17 #include "webrtc/base/sslstreamadapter.h"
18 #include "webrtc/base/stream.h"
19 #include "webrtc/base/thread.h"
23 // We don't pull the RTP constants from rtputils.h, to avoid a layer violation.
24 static const size_t kDtlsRecordHeaderLen = 13;
25 static const size_t kMaxDtlsPacketLen = 2048;
26 static const size_t kMinRtpPacketLen = 12;
28 static bool IsDtlsPacket(const char* data, size_t len) {
29 const uint8* u = reinterpret_cast<const uint8*>(data);
30 return (len >= kDtlsRecordHeaderLen && (u[0] > 19 && u[0] < 64));
32 static bool IsRtpPacket(const char* data, size_t len) {
33 const uint8* u = reinterpret_cast<const uint8*>(data);
34 return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
37 rtc::StreamResult StreamInterfaceChannel::Read(void* buffer,
41 if (state_ == rtc::SS_CLOSED)
43 if (state_ == rtc::SS_OPENING)
46 return fifo_.Read(buffer, buffer_len, read, error);
49 rtc::StreamResult StreamInterfaceChannel::Write(const void* data,
53 // Always succeeds, since this is an unreliable transport anyway.
54 // TODO: Should this block if channel_'s temporarily unwritable?
55 rtc::PacketOptions packet_options;
56 channel_->SendPacket(static_cast<const char*>(data), data_len,
61 return rtc::SR_SUCCESS;
64 bool StreamInterfaceChannel::OnPacketReceived(const char* data, size_t size) {
65 // We force a read event here to ensure that we don't overflow our FIFO.
66 // Under high packet rate this can occur if we wait for the FIFO to post its
68 bool ret = (fifo_.WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS);
70 SignalEvent(this, rtc::SE_READ, 0);
75 void StreamInterfaceChannel::OnEvent(rtc::StreamInterface* stream,
77 SignalEvent(this, sig, err);
80 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
82 TransportChannelImpl* channel)
83 : TransportChannelImpl(channel->content_name(), channel->component()),
84 transport_(transport),
85 worker_thread_(rtc::Thread::Current()),
88 dtls_state_(STATE_NONE),
89 local_identity_(NULL),
90 ssl_role_(rtc::SSL_CLIENT) {
91 channel_->SignalReadableState.connect(this,
92 &DtlsTransportChannelWrapper::OnReadableState);
93 channel_->SignalWritableState.connect(this,
94 &DtlsTransportChannelWrapper::OnWritableState);
95 channel_->SignalReadPacket.connect(this,
96 &DtlsTransportChannelWrapper::OnReadPacket);
97 channel_->SignalReadyToSend.connect(this,
98 &DtlsTransportChannelWrapper::OnReadyToSend);
99 channel_->SignalRequestSignaling.connect(this,
100 &DtlsTransportChannelWrapper::OnRequestSignaling);
101 channel_->SignalCandidateReady.connect(this,
102 &DtlsTransportChannelWrapper::OnCandidateReady);
103 channel_->SignalCandidatesAllocationDone.connect(this,
104 &DtlsTransportChannelWrapper::OnCandidatesAllocationDone);
105 channel_->SignalRoleConflict.connect(this,
106 &DtlsTransportChannelWrapper::OnRoleConflict);
107 channel_->SignalRouteChange.connect(this,
108 &DtlsTransportChannelWrapper::OnRouteChange);
109 channel_->SignalConnectionRemoved.connect(this,
110 &DtlsTransportChannelWrapper::OnConnectionRemoved);
113 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
116 void DtlsTransportChannelWrapper::Connect() {
117 // We should only get a single call to Connect.
118 ASSERT(dtls_state_ == STATE_NONE ||
119 dtls_state_ == STATE_OFFERED ||
120 dtls_state_ == STATE_ACCEPTED);
124 void DtlsTransportChannelWrapper::Reset() {
129 // Re-call SetupDtls()
131 LOG_J(LS_ERROR, this) << "Error re-initializing DTLS";
132 dtls_state_ = STATE_CLOSED;
136 dtls_state_ = STATE_ACCEPTED;
139 bool DtlsTransportChannelWrapper::SetLocalIdentity(
140 rtc::SSLIdentity* identity) {
141 if (dtls_state_ != STATE_NONE) {
142 if (identity == local_identity_) {
143 // This may happen during renegotiation.
144 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity";
147 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state";
153 local_identity_ = identity;
154 dtls_state_ = STATE_OFFERED;
156 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS";
162 bool DtlsTransportChannelWrapper::GetLocalIdentity(
163 rtc::SSLIdentity** identity) const {
164 if (!local_identity_)
167 *identity = local_identity_->GetReference();
171 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) {
172 if (dtls_state_ == STATE_OPEN) {
173 if (ssl_role_ != role) {
174 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup.";
184 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
189 bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
190 const std::string& digest_alg,
194 rtc::Buffer remote_fingerprint_value(digest, digest_len);
196 if (dtls_state_ != STATE_NONE &&
197 remote_fingerprint_value_ == remote_fingerprint_value &&
198 !digest_alg.empty()) {
199 // This may happen during renegotiation.
200 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint";
204 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalIdentity
205 // hasn't been called.
206 if (dtls_state_ > STATE_OFFERED ||
207 (dtls_state_ == STATE_NONE && !digest_alg.empty())) {
208 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state.";
212 if (digest_alg.empty()) {
213 LOG_J(LS_INFO, this) << "Other side didn't support DTLS.";
214 dtls_state_ = STATE_NONE;
218 // At this point we know we are doing DTLS
219 remote_fingerprint_value.TransferTo(&remote_fingerprint_value_);
220 remote_fingerprint_algorithm_ = digest_alg;
223 dtls_state_ = STATE_CLOSED;
227 dtls_state_ = STATE_ACCEPTED;
231 bool DtlsTransportChannelWrapper::GetRemoteCertificate(
232 rtc::SSLCertificate** cert) const {
236 return dtls_->GetPeerCertificate(cert);
239 bool DtlsTransportChannelWrapper::SetupDtls() {
240 StreamInterfaceChannel* downward =
241 new StreamInterfaceChannel(worker_thread_, channel_);
243 dtls_.reset(rtc::SSLStreamAdapter::Create(downward));
245 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter.";
250 downward_ = downward;
252 dtls_->SetIdentity(local_identity_->GetReference());
253 dtls_->SetMode(rtc::SSL_MODE_DTLS);
254 dtls_->SetServerRole(ssl_role_);
255 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
256 if (!dtls_->SetPeerCertificateDigest(
257 remote_fingerprint_algorithm_,
258 reinterpret_cast<unsigned char *>(remote_fingerprint_value_.data()),
259 remote_fingerprint_value_.length())) {
260 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest.";
264 // Set up DTLS-SRTP, if it's been enabled.
265 if (!srtp_ciphers_.empty()) {
266 if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) {
267 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers.";
271 LOG_J(LS_INFO, this) << "Not using DTLS.";
274 LOG_J(LS_INFO, this) << "DTLS setup complete.";
278 bool DtlsTransportChannelWrapper::SetSrtpCiphers(
279 const std::vector<std::string>& ciphers) {
280 if (srtp_ciphers_ == ciphers)
283 if (dtls_state_ == STATE_STARTED) {
284 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating";
288 if (dtls_state_ == STATE_OPEN) {
289 // We don't support DTLS renegotiation currently. If new set of srtp ciphers
290 // are different than what's being used currently, we will not use it.
291 // So for now, let's be happy (or sad) with a warning message.
292 std::string current_srtp_cipher;
293 if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) {
294 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
297 const std::vector<std::string>::const_iterator iter =
298 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher);
299 if (iter == ciphers.end()) {
300 std::string requested_str;
301 for (size_t i = 0; i < ciphers.size(); ++i) {
302 requested_str.append(" ");
303 requested_str.append(ciphers[i]);
304 requested_str.append(" ");
306 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS "
307 << "renegotiation is not supported currently "
308 << "current cipher = " << current_srtp_cipher << " and "
309 << "requested = " << "[" << requested_str << "]";
314 if (dtls_state_ != STATE_NONE &&
315 dtls_state_ != STATE_OFFERED &&
316 dtls_state_ != STATE_ACCEPTED) {
321 srtp_ciphers_ = ciphers;
325 bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) {
326 if (dtls_state_ != STATE_OPEN) {
330 return dtls_->GetDtlsSrtpCipher(cipher);
334 // Called from upper layers to send a media packet.
335 int DtlsTransportChannelWrapper::SendPacket(
336 const char* data, size_t size,
337 const rtc::PacketOptions& options, int flags) {
340 switch (dtls_state_) {
342 // We don't know if we are doing DTLS yet, so we can't send a packet.
343 // TODO(ekr@rtfm.com): assert here?
349 // Can't send data until the connection is active
354 if (flags & PF_SRTP_BYPASS) {
355 ASSERT(!srtp_ciphers_.empty());
356 if (!IsRtpPacket(data, size)) {
361 result = channel_->SendPacket(data, size, options);
363 result = (dtls_->WriteAll(data, size, NULL, NULL) ==
364 rtc::SR_SUCCESS) ? static_cast<int>(size) : -1;
369 result = channel_->SendPacket(data, size, options);
372 case STATE_CLOSED: // Can't send anything when we're closed.
379 // The state transition logic here is as follows:
380 // (1) If we're not doing DTLS-SRTP, then the state is just the
381 // state of the underlying impl()
382 // (2) If we're doing DTLS-SRTP:
383 // - Prior to the DTLS handshake, the state is neither readable or
385 // - When the impl goes writable for the first time we
386 // start the DTLS handshake
387 // - Once the DTLS handshake completes, the state is that of the
389 void DtlsTransportChannelWrapper::OnReadableState(TransportChannel* channel) {
390 ASSERT(rtc::Thread::Current() == worker_thread_);
391 ASSERT(channel == channel_);
392 LOG_J(LS_VERBOSE, this)
393 << "DTLSTransportChannelWrapper: channel readable state changed.";
395 if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) {
396 set_readable(channel_->readable());
397 // Note: SignalReadableState fired by set_readable.
401 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) {
402 ASSERT(rtc::Thread::Current() == worker_thread_);
403 ASSERT(channel == channel_);
404 LOG_J(LS_VERBOSE, this)
405 << "DTLSTransportChannelWrapper: channel writable state changed.";
407 switch (dtls_state_) {
410 set_writable(channel_->writable());
411 // Note: SignalWritableState fired by set_writable.
419 if (!MaybeStartDtls()) {
420 // This should never happen:
421 // Because we are operating in a nonblocking mode and all
422 // incoming packets come in via OnReadPacket(), which rejects
423 // packets in this state, the incoming queue must be empty. We
424 // ignore write errors, thus any errors must be because of
425 // configuration and therefore are our fault.
426 // Note that in non-debug configurations, failure in
427 // MaybeStartDtls() changes the state to STATE_CLOSED.
437 // Should not happen. Do nothing
442 void DtlsTransportChannelWrapper::OnReadPacket(
443 TransportChannel* channel, const char* data, size_t size,
444 const rtc::PacketTime& packet_time, int flags) {
445 ASSERT(rtc::Thread::Current() == worker_thread_);
446 ASSERT(channel == channel_);
449 switch (dtls_state_) {
451 // We are not doing DTLS
452 SignalReadPacket(this, data, size, packet_time, 0);
456 // Currently drop the packet, but we might in future
457 // decide to take this as evidence that the other
458 // side is ready to do DTLS and start the handshake
460 LOG_J(LS_WARNING, this) << "Received packet before we know if we are "
461 << "doing DTLS or not; dropping.";
465 // Drop packets received before DTLS has actually started
466 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started.";
471 // We should only get DTLS or SRTP packets; STUN's already been demuxed.
472 // Is this potentially a DTLS packet?
473 if (IsDtlsPacket(data, size)) {
474 if (!HandleDtlsPacket(data, size)) {
475 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet.";
479 // Not a DTLS packet; our handshake should be complete by now.
480 if (dtls_state_ != STATE_OPEN) {
481 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS "
486 // And it had better be a SRTP packet.
487 if (!IsRtpPacket(data, size)) {
488 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet.";
493 ASSERT(!srtp_ciphers_.empty());
495 // Signal this upwards as a bypass packet.
496 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS);
500 // This shouldn't be happening. Drop the packet
505 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) {
507 SignalReadyToSend(this);
511 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
513 ASSERT(rtc::Thread::Current() == worker_thread_);
514 ASSERT(dtls == dtls_.get());
515 if (sig & rtc::SE_OPEN) {
516 // This is the first time.
517 LOG_J(LS_INFO, this) << "DTLS handshake complete.";
518 if (dtls_->GetState() == rtc::SS_OPEN) {
519 // The check for OPEN shouldn't be necessary but let's make
520 // sure we don't accidentally frob the state if it's closed.
521 dtls_state_ = STATE_OPEN;
527 if (sig & rtc::SE_READ) {
528 char buf[kMaxDtlsPacketLen];
530 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) {
531 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
534 if (sig & rtc::SE_CLOSE) {
535 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself.
537 LOG_J(LS_INFO, this) << "DTLS channel closed";
539 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
544 dtls_state_ = STATE_CLOSED;
548 bool DtlsTransportChannelWrapper::MaybeStartDtls() {
549 if (channel_->writable()) {
550 if (dtls_->StartSSLWithPeer()) {
551 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake";
552 dtls_state_ = STATE_CLOSED;
556 << "DtlsTransportChannelWrapper: Started DTLS handshake";
558 dtls_state_ = STATE_STARTED;
563 // Called from OnReadPacket when a DTLS packet is received.
564 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
566 // Sanity check we're not passing junk that
567 // just looks like DTLS.
568 const uint8* tmp_data = reinterpret_cast<const uint8* >(data);
569 size_t tmp_size = size;
570 while (tmp_size > 0) {
571 if (tmp_size < kDtlsRecordHeaderLen)
572 return false; // Too short for the header
574 size_t record_len = (tmp_data[11] << 8) | (tmp_data[12]);
575 if ((record_len + kDtlsRecordHeaderLen) > tmp_size)
576 return false; // Body too short
578 tmp_data += record_len + kDtlsRecordHeaderLen;
579 tmp_size -= record_len + kDtlsRecordHeaderLen;
582 // Looks good. Pass to the SIC which ends up being passed to
584 return downward_->OnPacketReceived(data, size);
587 void DtlsTransportChannelWrapper::OnRequestSignaling(
588 TransportChannelImpl* channel) {
589 ASSERT(channel == channel_);
590 SignalRequestSignaling(this);
593 void DtlsTransportChannelWrapper::OnCandidateReady(
594 TransportChannelImpl* channel, const Candidate& c) {
595 ASSERT(channel == channel_);
596 SignalCandidateReady(this, c);
599 void DtlsTransportChannelWrapper::OnCandidatesAllocationDone(
600 TransportChannelImpl* channel) {
601 ASSERT(channel == channel_);
602 SignalCandidatesAllocationDone(this);
605 void DtlsTransportChannelWrapper::OnRoleConflict(
606 TransportChannelImpl* channel) {
607 ASSERT(channel == channel_);
608 SignalRoleConflict(this);
611 void DtlsTransportChannelWrapper::OnRouteChange(
612 TransportChannel* channel, const Candidate& candidate) {
613 ASSERT(channel == channel_);
614 SignalRouteChange(this, candidate);
617 void DtlsTransportChannelWrapper::OnConnectionRemoved(
618 TransportChannelImpl* channel) {
619 ASSERT(channel == channel_);
620 SignalConnectionRemoved(this);
623 } // namespace cricket