blob: 508158f678679fe42c7a5133ed56214ee5a69935 [file] [log] [blame]
deadbeeff5346592017-01-25 05:51:211/*
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3 *
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.
9 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#ifndef P2P_BASE_FAKEDTLSTRANSPORT_H_
12#define P2P_BASE_FAKEDTLSTRANSPORT_H_
deadbeeff5346592017-01-25 05:51:2113
14#include <memory>
15#include <string>
16#include <vector>
17
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "p2p/base/dtlstransportinternal.h"
19#include "p2p/base/fakeicetransport.h"
20#include "rtc_base/fakesslidentity.h"
deadbeeff5346592017-01-25 05:51:2121
22namespace cricket {
23
24// Fake DTLS transport which is implemented by wrapping a fake ICE transport.
25// Doesn't interact directly with fake ICE transport for anything other than
26// sending packets.
27class FakeDtlsTransport : public DtlsTransportInternal {
28 public:
29 explicit FakeDtlsTransport(FakeIceTransport* ice_transport)
30 : ice_transport_(ice_transport),
31 transport_name_(ice_transport->transport_name()),
32 component_(ice_transport->component()),
33 dtls_fingerprint_("", nullptr, 0) {
Zhi Huang942bc2e2017-11-13 21:26:0734 RTC_DCHECK(ice_transport_);
deadbeeff5346592017-01-25 05:51:2135 ice_transport_->SignalReadPacket.connect(
36 this, &FakeDtlsTransport::OnIceTransportReadPacket);
Zhi Huang942bc2e2017-11-13 21:26:0737 ice_transport_->SignalNetworkRouteChanged.connect(
38 this, &FakeDtlsTransport::OnNetworkRouteChanged);
deadbeeff5346592017-01-25 05:51:2139 }
40
41 // If this constructor is called, a new fake ICE transport will be created,
42 // and this FakeDtlsTransport will take the ownership.
43 explicit FakeDtlsTransport(const std::string& name, int component)
44 : owned_ice_transport_(new FakeIceTransport(name, component)),
45 transport_name_(owned_ice_transport_->transport_name()),
46 component_(owned_ice_transport_->component()),
47 dtls_fingerprint_("", nullptr, 0) {
48 ice_transport_ = owned_ice_transport_.get();
49 ice_transport_->SignalReadPacket.connect(
50 this, &FakeDtlsTransport::OnIceTransportReadPacket);
Zhi Huang942bc2e2017-11-13 21:26:0751 ice_transport_->SignalNetworkRouteChanged.connect(
52 this, &FakeDtlsTransport::OnNetworkRouteChanged);
deadbeeff5346592017-01-25 05:51:2153 }
54
55 ~FakeDtlsTransport() override {
56 if (dest_ && dest_->dest_ == this) {
57 dest_->dest_ = nullptr;
58 }
59 }
60
61 // Get inner fake ICE transport.
62 FakeIceTransport* fake_ice_transport() { return ice_transport_; }
63
64 // If async, will send packets by "Post"-ing to message queue instead of
65 // synchronously "Send"-ing.
66 void SetAsync(bool async) { ice_transport_->SetAsync(async); }
67 void SetAsyncDelay(int delay_ms) { ice_transport_->SetAsyncDelay(delay_ms); }
68
69 // SetWritable, SetReceiving and SetDestination are the main methods that can
70 // be used for testing, to simulate connectivity or lack thereof.
71 void SetWritable(bool writable) {
72 ice_transport_->SetWritable(writable);
73 set_writable(writable);
74 }
75 void SetReceiving(bool receiving) {
76 ice_transport_->SetReceiving(receiving);
77 set_receiving(receiving);
78 }
79
80 // Simulates the two DTLS transports connecting to each other.
81 // If |asymmetric| is true this method only affects this FakeDtlsTransport.
82 // If false, it affects |dest| as well.
83 void SetDestination(FakeDtlsTransport* dest, bool asymmetric = false) {
84 if (dest == dest_) {
85 return;
86 }
87 RTC_DCHECK(!dest || !dest_)
88 << "Changing fake destination from one to another is not supported.";
89 if (dest && !dest_) {
90 // This simulates the DTLS handshake.
91 dest_ = dest;
92 if (local_cert_ && dest_->local_cert_) {
93 do_dtls_ = true;
deadbeeff5346592017-01-25 05:51:2194 }
95 SetWritable(true);
96 if (!asymmetric) {
97 dest->SetDestination(this, true);
98 }
jbauch5869f502017-06-29 19:31:3699 dtls_state_ = DTLS_TRANSPORT_CONNECTED;
deadbeeff5346592017-01-25 05:51:21100 ice_transport_->SetDestination(
101 static_cast<FakeIceTransport*>(dest->ice_transport()), asymmetric);
102 } else {
103 // Simulates loss of connectivity, by asymmetrically forgetting dest_.
104 dest_ = nullptr;
105 SetWritable(false);
106 ice_transport_->SetDestination(nullptr, asymmetric);
107 }
108 }
109
110 // Fake DtlsTransportInternal implementation.
111 DtlsTransportState dtls_state() const override { return dtls_state_; }
112 const std::string& transport_name() const override { return transport_name_; }
113 int component() const override { return component_; }
114 const rtc::SSLFingerprint& dtls_fingerprint() const {
115 return dtls_fingerprint_;
116 }
117 bool SetRemoteFingerprint(const std::string& alg,
118 const uint8_t* digest,
119 size_t digest_len) override {
120 dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
121 return true;
122 }
123 bool SetSslRole(rtc::SSLRole role) override {
124 ssl_role_ = role;
125 return true;
126 }
127 bool GetSslRole(rtc::SSLRole* role) const override {
128 *role = ssl_role_;
129 return true;
130 }
jbauch5869f502017-06-29 19:31:36131 const rtc::CryptoOptions& crypto_options() const override {
132 return crypto_options_;
133 }
134 void SetCryptoOptions(const rtc::CryptoOptions& crypto_options) {
135 crypto_options_ = crypto_options;
136 }
deadbeeff5346592017-01-25 05:51:21137 bool SetLocalCertificate(
138 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
139 local_cert_ = certificate;
140 return true;
141 }
142 void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
143 remote_cert_ = cert;
144 }
145 bool IsDtlsActive() const override { return do_dtls_; }
deadbeeff5346592017-01-25 05:51:21146 bool GetSrtpCryptoSuite(int* crypto_suite) override {
deadbeef7914b8c2017-04-21 10:23:33147 if (!do_dtls_) {
148 return false;
deadbeeff5346592017-01-25 05:51:21149 }
jbauch5869f502017-06-29 19:31:36150 *crypto_suite = crypto_suite_;
deadbeef7914b8c2017-04-21 10:23:33151 return true;
deadbeeff5346592017-01-25 05:51:21152 }
jbauch5869f502017-06-29 19:31:36153 void SetSrtpCryptoSuite(int crypto_suite) {
154 crypto_suite_ = crypto_suite;
155 }
deadbeeff5346592017-01-25 05:51:21156 bool GetSslCipherSuite(int* cipher_suite) override { return false; }
157 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
158 return local_cert_;
159 }
160 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
161 const override {
162 return remote_cert_ ? std::unique_ptr<rtc::SSLCertificate>(
163 remote_cert_->GetReference())
164 : nullptr;
165 }
166 bool ExportKeyingMaterial(const std::string& label,
167 const uint8_t* context,
168 size_t context_len,
169 bool use_context,
170 uint8_t* result,
171 size_t result_len) override {
deadbeef7914b8c2017-04-21 10:23:33172 if (!do_dtls_) {
173 return false;
deadbeeff5346592017-01-25 05:51:21174 }
deadbeef7914b8c2017-04-21 10:23:33175 memset(result, 0xff, result_len);
176 return true;
deadbeeff5346592017-01-25 05:51:21177 }
178 void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
179 ssl_max_version_ = version;
180 }
181 rtc::SSLProtocolVersion ssl_max_protocol_version() const {
182 return ssl_max_version_;
183 }
deadbeeff5346592017-01-25 05:51:21184
185 IceTransportInternal* ice_transport() override { return ice_transport_; }
186
deadbeef5bd5ca32017-02-10 19:31:50187 // PacketTransportInternal implementation, which passes through to fake ICE
deadbeeff5346592017-01-25 05:51:21188 // transport for sending actual packets.
189 bool writable() const override { return writable_; }
190 bool receiving() const override { return receiving_; }
191 int SendPacket(const char* data,
192 size_t len,
193 const rtc::PacketOptions& options,
194 int flags) override {
195 // We expect only SRTP packets to be sent through this interface.
196 if (flags != PF_SRTP_BYPASS && flags != 0) {
197 return -1;
198 }
199 return ice_transport_->SendPacket(data, len, options, flags);
200 }
201 int SetOption(rtc::Socket::Option opt, int value) override {
202 return ice_transport_->SetOption(opt, value);
203 }
204 bool GetOption(rtc::Socket::Option opt, int* value) override {
205 return ice_transport_->GetOption(opt, value);
206 }
207 int GetError() override { return ice_transport_->GetError(); }
208
Zhi Huang942bc2e2017-11-13 21:26:07209 rtc::Optional<rtc::NetworkRoute> network_route() const override {
210 return ice_transport_->network_route();
211 }
212
deadbeeff5346592017-01-25 05:51:21213 private:
deadbeef5bd5ca32017-02-10 19:31:50214 void OnIceTransportReadPacket(PacketTransportInternal* ice_,
deadbeeff5346592017-01-25 05:51:21215 const char* data,
216 size_t len,
217 const rtc::PacketTime& time,
218 int flags) {
219 SignalReadPacket(this, data, len, time, flags);
220 }
221
deadbeeff5346592017-01-25 05:51:21222 void set_receiving(bool receiving) {
223 if (receiving_ == receiving) {
224 return;
225 }
226 receiving_ = receiving;
227 SignalReceivingState(this);
228 }
229
230 void set_writable(bool writable) {
231 if (writable_ == writable) {
232 return;
233 }
234 writable_ = writable;
235 if (writable_) {
236 SignalReadyToSend(this);
237 }
238 SignalWritableState(this);
239 }
240
Zhi Huang942bc2e2017-11-13 21:26:07241 void OnNetworkRouteChanged(rtc::Optional<rtc::NetworkRoute> network_route) {
242 SignalNetworkRouteChanged(network_route);
243 }
244
deadbeeff5346592017-01-25 05:51:21245 FakeIceTransport* ice_transport_;
246 std::unique_ptr<FakeIceTransport> owned_ice_transport_;
247 std::string transport_name_;
248 int component_;
249 FakeDtlsTransport* dest_ = nullptr;
250 rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
251 rtc::FakeSSLCertificate* remote_cert_ = nullptr;
252 bool do_dtls_ = false;
deadbeeff5346592017-01-25 05:51:21253 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
254 rtc::SSLFingerprint dtls_fingerprint_;
255 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
jbauch5869f502017-06-29 19:31:36256 int crypto_suite_ = rtc::SRTP_AES128_CM_SHA1_80;
257 rtc::CryptoOptions crypto_options_;
deadbeeff5346592017-01-25 05:51:21258
259 DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW;
260
261 bool receiving_ = false;
262 bool writable_ = false;
263};
264
265} // namespace cricket
266
Mirko Bonadei92ea95e2017-09-15 04:47:31267#endif // P2P_BASE_FAKEDTLSTRANSPORT_H_