Chromium Code Reviews| Index: webrtc/p2p/base/fakedtlstransport.h |
| diff --git a/webrtc/p2p/base/fakedtlstransport.h b/webrtc/p2p/base/fakedtlstransport.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1fe66ec1b28d2119016d06765327fa6a57ef0d7d |
| --- /dev/null |
| +++ b/webrtc/p2p/base/fakedtlstransport.h |
| @@ -0,0 +1,270 @@ |
| +/* |
| + * Copyright 2017 The WebRTC Project Authors. All rights reserved. |
| + * |
| + * Use of this source code is governed by a BSD-style license |
| + * that can be found in the LICENSE file in the root of the source |
| + * tree. An additional intellectual property rights grant can be found |
| + * in the file PATENTS. All contributing project authors may |
| + * be found in the AUTHORS file in the root of the source tree. |
| + */ |
| + |
| +#ifndef WEBRTC_P2P_BASE_FAKEDTLSTRANSPORT_H_ |
| +#define WEBRTC_P2P_BASE_FAKEDTLSTRANSPORT_H_ |
| + |
| +#include <memory> |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "webrtc/base/fakesslidentity.h" |
| +#include "webrtc/p2p/base/dtlstransportinternal.h" |
| +#include "webrtc/p2p/base/fakeicetransport.h" |
| + |
| +namespace cricket { |
| + |
| +// Fake DTLS transport which is implemented by wrapping a fake ICE transport. |
| +// Doesn't interact directly with fake ICE transport for anything other than |
| +// sending packets. |
| +class FakeDtlsTransport : public DtlsTransportInternal { |
| + public: |
| + explicit FakeDtlsTransport(FakeIceTransport* ice_transport) |
| + : ice_transport_(ice_transport), |
| + transport_name_(ice_transport->transport_name()), |
| + component_(ice_transport->component()), |
| + dtls_fingerprint_("", nullptr, 0) { |
| + ice_transport_->SignalReadPacket.connect( |
| + this, &FakeDtlsTransport::OnIceTransportReadPacket); |
| + } |
| + |
| + // If this constructor is called, a new fake ICE transport will be created, |
| + // and this FakeDtlsTransport will take the ownership. |
| + explicit FakeDtlsTransport(const std::string& name, int component) |
| + : owned_ice_transport_(new FakeIceTransport(name, component)), |
| + transport_name_(owned_ice_transport_->transport_name()), |
| + component_(owned_ice_transport_->component()), |
| + dtls_fingerprint_("", nullptr, 0) { |
| + ice_transport_ = owned_ice_transport_.get(); |
| + ice_transport_->SignalReadPacket.connect( |
| + this, &FakeDtlsTransport::OnIceTransportReadPacket); |
| + } |
| + |
| + ~FakeDtlsTransport() override { |
| + if (dest_ && dest_->dest_ == this) { |
| + dest_->dest_ = nullptr; |
| + } |
| + } |
| + |
| + // Get inner fake ICE transport. |
| + FakeIceTransport* fake_ice_transport() { return ice_transport_; } |
| + |
| + // If async, will send packets by "Post"-ing to message queue instead of |
| + // synchronously "Send"-ing. |
| + void SetAsync(bool async) { ice_transport_->SetAsync(async); } |
| + void SetAsyncDelay(int delay_ms) { ice_transport_->SetAsyncDelay(delay_ms); } |
| + |
| + // SetWritable, SetReceiving and SetDestination are the main methods that can |
| + // be used for testing, to simulate connectivity or lack thereof. |
| + void SetWritable(bool writable) { |
| + ice_transport_->SetWritable(writable); |
| + set_writable(writable); |
| + } |
| + void SetReceiving(bool receiving) { |
| + ice_transport_->SetReceiving(receiving); |
| + set_receiving(receiving); |
| + } |
| + |
| + // Simulates the two DTLS transports connecting to each other. |
| + // If |asymmetric| is true this method only affects this FakeDtlsTransport. |
| + // If false, it affects |dest| as well. |
| + void SetDestination(FakeDtlsTransport* dest, bool asymmetric = false) { |
| + if (dest == dest_) { |
| + return; |
| + } |
| + RTC_DCHECK(!dest || !dest_) |
| + << "Changing fake destination from one to another is not supported."; |
| + if (dest && !dest_) { |
| + // This simulates the DTLS handshake. |
| + dest_ = dest; |
| + if (local_cert_ && dest_->local_cert_) { |
| + do_dtls_ = true; |
| + NegotiateSrtpCiphers(); |
| + } |
| + SetWritable(true); |
| + if (!asymmetric) { |
| + dest->SetDestination(this, true); |
| + } |
| + ice_transport_->SetDestination( |
| + static_cast<FakeIceTransport*>(dest->ice_transport()), asymmetric); |
| + } else { |
| + // Simulates loss of connectivity, by asymmetrically forgetting dest_. |
| + dest_ = nullptr; |
| + SetWritable(false); |
| + ice_transport_->SetDestination(nullptr, asymmetric); |
| + } |
| + } |
| + |
| + // Fake DtlsTransportInternal implementation. |
| + DtlsTransportState dtls_state() const override { return dtls_state_; } |
| + const std::string& transport_name() const override { return transport_name_; } |
| + int component() const override { return component_; } |
| + const rtc::SSLFingerprint& dtls_fingerprint() const { |
| + return dtls_fingerprint_; |
| + } |
| + bool SetRemoteFingerprint(const std::string& alg, |
| + const uint8_t* digest, |
| + size_t digest_len) override { |
| + dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len); |
| + return true; |
| + } |
| + bool SetSslRole(rtc::SSLRole role) override { |
| + ssl_role_ = role; |
| + return true; |
| + } |
| + bool GetSslRole(rtc::SSLRole* role) const override { |
| + *role = ssl_role_; |
| + return true; |
| + } |
| + bool SetLocalCertificate( |
| + const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override { |
| + local_cert_ = certificate; |
| + return true; |
| + } |
| + void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) { |
| + remote_cert_ = cert; |
| + } |
| + bool IsDtlsActive() const override { return do_dtls_; } |
| + bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override { |
| + srtp_ciphers_ = ciphers; |
| + return true; |
| + } |
| + bool GetSrtpCryptoSuite(int* crypto_suite) override { |
| + if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) { |
| + *crypto_suite = chosen_crypto_suite_; |
| + return true; |
| + } |
| + return false; |
| + } |
| + bool GetSslCipherSuite(int* cipher_suite) override { return false; } |
| + rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override { |
| + return local_cert_; |
| + } |
| + std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() |
| + const override { |
| + return remote_cert_ ? std::unique_ptr<rtc::SSLCertificate>( |
| + remote_cert_->GetReference()) |
| + : nullptr; |
| + } |
| + bool ExportKeyingMaterial(const std::string& label, |
| + const uint8_t* context, |
| + size_t context_len, |
| + bool use_context, |
| + uint8_t* result, |
| + size_t result_len) override { |
| + if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) { |
| + memset(result, 0xff, result_len); |
| + return true; |
| + } |
| + |
| + return false; |
| + } |
| + void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) { |
| + ssl_max_version_ = version; |
| + } |
| + rtc::SSLProtocolVersion ssl_max_protocol_version() const { |
| + return ssl_max_version_; |
| + } |
| + bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override { |
| + std::vector<int> crypto_suites; |
| + for (const auto cipher : ciphers) { |
| + crypto_suites.push_back(rtc::SrtpCryptoSuiteFromName(cipher)); |
| + } |
| + return SetSrtpCryptoSuites(crypto_suites); |
| + } |
| + |
| + IceTransportInternal* ice_transport() override { return ice_transport_; } |
| + |
| + // PacketTransportInterface implementation, which passes through to fake ICE |
| + // transport for sending actual packets. |
| + bool writable() const override { return writable_; } |
| + bool receiving() const override { return receiving_; } |
| + int SendPacket(const char* data, |
| + size_t len, |
| + const rtc::PacketOptions& options, |
| + int flags) override { |
| + // We expect only SRTP packets to be sent through this interface. |
| + if (flags != PF_SRTP_BYPASS && flags != 0) { |
| + return -1; |
| + } |
| + return ice_transport_->SendPacket(data, len, options, flags); |
| + } |
| + int SetOption(rtc::Socket::Option opt, int value) override { |
| + return ice_transport_->SetOption(opt, value); |
| + } |
| + bool GetOption(rtc::Socket::Option opt, int* value) override { |
| + return ice_transport_->GetOption(opt, value); |
| + } |
| + int GetError() override { return ice_transport_->GetError(); } |
| + |
| + private: |
| + void OnIceTransportReadPacket(PacketTransportInterface* ice_, |
| + const char* data, |
| + size_t len, |
| + const rtc::PacketTime& time, |
| + int flags) { |
| + SignalReadPacket(this, data, len, time, flags); |
| + } |
| + |
| + void NegotiateSrtpCiphers() { |
| + for (std::vector<int>::const_iterator it1 = srtp_ciphers_.begin(); |
| + it1 != srtp_ciphers_.end(); ++it1) { |
| + for (std::vector<int>::const_iterator it2 = dest_->srtp_ciphers_.begin(); |
| + it2 != dest_->srtp_ciphers_.end(); ++it2) { |
| + if (*it1 == *it2) { |
| + chosen_crypto_suite_ = *it1; |
| + return; |
| + } |
| + } |
| + } |
| + } |
| + |
| + void set_receiving(bool receiving) { |
| + if (receiving_ == receiving) { |
| + return; |
| + } |
| + receiving_ = receiving; |
| + SignalReceivingState(this); |
| + } |
| + |
| + void set_writable(bool writable) { |
| + if (writable_ == writable) { |
| + return; |
| + } |
| + writable_ = writable; |
| + if (writable_) { |
| + SignalReadyToSend(this); |
| + } |
| + SignalWritableState(this); |
| + } |
| + |
| + FakeIceTransport* ice_transport_; |
| + std::unique_ptr<FakeIceTransport> owned_ice_transport_; |
| + std::string transport_name_; |
| + int component_; |
| + FakeDtlsTransport* dest_ = nullptr; |
| + rtc::scoped_refptr<rtc::RTCCertificate> local_cert_; |
| + rtc::FakeSSLCertificate* remote_cert_ = nullptr; |
| + bool do_dtls_ = false; |
| + std::vector<int> srtp_ciphers_; |
| + int chosen_crypto_suite_ = rtc::SRTP_INVALID_CRYPTO_SUITE; |
| + rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
| + rtc::SSLFingerprint dtls_fingerprint_; |
| + rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; |
| + |
| + DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW; |
| + |
| + bool receiving_ = false; |
| + bool writable_ = false; |
| +}; |
| + |
| +} // namespace cricket |
| + |
| +#endif // WEBRTC_P2P_BASE_FAKEDTLSTRANSPORT_H_ |
|
Taylor Brandstetter
2017/01/24 02:00:05
Moved from faketransportcontroller.h, removed ICE
|