Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(576)

Side by Side Diff: webrtc/p2p/base/fakesession.h

Issue 1350523003: TransportController refactoring. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing Mac test. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2009 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
11 #ifndef WEBRTC_P2P_BASE_FAKESESSION_H_
12 #define WEBRTC_P2P_BASE_FAKESESSION_H_
13
14 #include <map>
15 #include <string>
16 #include <vector>
17
18 #include "webrtc/p2p/base/session.h"
19 #include "webrtc/p2p/base/transport.h"
20 #include "webrtc/p2p/base/transportchannel.h"
21 #include "webrtc/p2p/base/transportchannelimpl.h"
22 #include "webrtc/base/buffer.h"
23 #include "webrtc/base/fakesslidentity.h"
24 #include "webrtc/base/messagequeue.h"
25 #include "webrtc/base/sigslot.h"
26 #include "webrtc/base/sslfingerprint.h"
27
28 namespace cricket {
29
30 class FakeTransport;
31
32 struct PacketMessageData : public rtc::MessageData {
33 PacketMessageData(const char* data, size_t len) : packet(data, len) {
34 }
35 rtc::Buffer packet;
36 };
37
38 // Fake transport channel class, which can be passed to anything that needs a
39 // transport channel. Can be informed of another FakeTransportChannel via
40 // SetDestination.
41 // TODO(hbos): Move implementation to .cc file, this and other classes in file.
42 class FakeTransportChannel : public TransportChannelImpl,
43 public rtc::MessageHandler {
44 public:
45 explicit FakeTransportChannel(Transport* transport,
46 const std::string& content_name,
47 int component)
48 : TransportChannelImpl(content_name, component),
49 transport_(transport),
50 dest_(nullptr),
51 state_(STATE_INIT),
52 async_(false),
53 do_dtls_(false),
54 role_(ICEROLE_UNKNOWN),
55 tiebreaker_(0),
56 remote_ice_mode_(ICEMODE_FULL),
57 dtls_fingerprint_("", nullptr, 0),
58 ssl_role_(rtc::SSL_CLIENT),
59 connection_count_(0) {
60 }
61 ~FakeTransportChannel() {
62 Reset();
63 }
64
65 uint64 IceTiebreaker() const { return tiebreaker_; }
66 IceMode remote_ice_mode() const { return remote_ice_mode_; }
67 const std::string& ice_ufrag() const { return ice_ufrag_; }
68 const std::string& ice_pwd() const { return ice_pwd_; }
69 const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
70 const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
71 const rtc::SSLFingerprint& dtls_fingerprint() const {
72 return dtls_fingerprint_;
73 }
74
75 void SetAsync(bool async) {
76 async_ = async;
77 }
78
79 Transport* GetTransport() override {
80 return transport_;
81 }
82
83 TransportChannelState GetState() const override {
84 if (connection_count_ == 0) {
85 return TransportChannelState::STATE_FAILED;
86 }
87
88 if (connection_count_ == 1) {
89 return TransportChannelState::STATE_COMPLETED;
90 }
91
92 return TransportChannelState::STATE_FAILED;
93 }
94
95 void SetIceRole(IceRole role) override { role_ = role; }
96 IceRole GetIceRole() const override { return role_; }
97 void SetIceTiebreaker(uint64 tiebreaker) override {
98 tiebreaker_ = tiebreaker;
99 }
100 void SetIceCredentials(const std::string& ice_ufrag,
101 const std::string& ice_pwd) override {
102 ice_ufrag_ = ice_ufrag;
103 ice_pwd_ = ice_pwd;
104 }
105 void SetRemoteIceCredentials(const std::string& ice_ufrag,
106 const std::string& ice_pwd) override {
107 remote_ice_ufrag_ = ice_ufrag;
108 remote_ice_pwd_ = ice_pwd;
109 }
110
111 void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
112 bool SetRemoteFingerprint(const std::string& alg, const uint8* digest,
113 size_t digest_len) override {
114 dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
115 return true;
116 }
117 bool SetSslRole(rtc::SSLRole role) override {
118 ssl_role_ = role;
119 return true;
120 }
121 bool GetSslRole(rtc::SSLRole* role) const override {
122 *role = ssl_role_;
123 return true;
124 }
125
126 void Connect() override {
127 if (state_ == STATE_INIT) {
128 state_ = STATE_CONNECTING;
129 }
130 }
131 virtual void Reset() {
132 if (state_ != STATE_INIT) {
133 state_ = STATE_INIT;
134 if (dest_) {
135 dest_->state_ = STATE_INIT;
136 dest_->dest_ = NULL;
137 dest_ = NULL;
138 }
139 }
140 }
141
142 void SetWritable(bool writable) {
143 set_writable(writable);
144 }
145
146 void SetDestination(FakeTransportChannel* dest) {
147 if (state_ == STATE_CONNECTING && dest) {
148 // This simulates the delivery of candidates.
149 dest_ = dest;
150 dest_->dest_ = this;
151 if (certificate_ && dest_->certificate_) {
152 do_dtls_ = true;
153 dest_->do_dtls_ = true;
154 NegotiateSrtpCiphers();
155 }
156 state_ = STATE_CONNECTED;
157 dest_->state_ = STATE_CONNECTED;
158 set_writable(true);
159 dest_->set_writable(true);
160 } else if (state_ == STATE_CONNECTED && !dest) {
161 // Simulates loss of connectivity, by asymmetrically forgetting dest_.
162 dest_ = NULL;
163 state_ = STATE_CONNECTING;
164 set_writable(false);
165 }
166 }
167
168 void SetConnectionCount(size_t connection_count) {
169 size_t old_connection_count = connection_count_;
170 connection_count_ = connection_count;
171 if (connection_count_ < old_connection_count)
172 SignalConnectionRemoved(this);
173 }
174
175 void SetReceiving(bool receiving) {
176 set_receiving(receiving);
177 }
178
179 void SetReceivingTimeout(int timeout) override {}
180
181 int SendPacket(const char* data, size_t len,
182 const rtc::PacketOptions& options, int flags) override {
183 if (state_ != STATE_CONNECTED) {
184 return -1;
185 }
186
187 if (flags != PF_SRTP_BYPASS && flags != 0) {
188 return -1;
189 }
190
191 PacketMessageData* packet = new PacketMessageData(data, len);
192 if (async_) {
193 rtc::Thread::Current()->Post(this, 0, packet);
194 } else {
195 rtc::Thread::Current()->Send(this, 0, packet);
196 }
197 return static_cast<int>(len);
198 }
199 int SetOption(rtc::Socket::Option opt, int value) override {
200 return true;
201 }
202 bool GetOption(rtc::Socket::Option opt, int* value) override {
203 return true;
204 }
205 int GetError() override {
206 return 0;
207 }
208
209 void OnSignalingReady() override {
210 }
211 void OnCandidate(const Candidate& candidate) override {
212 }
213
214 void OnMessage(rtc::Message* msg) override {
215 PacketMessageData* data = static_cast<PacketMessageData*>(
216 msg->pdata);
217 dest_->SignalReadPacket(dest_, data->packet.data<char>(),
218 data->packet.size(), rtc::CreatePacketTime(0), 0);
219 delete data;
220 }
221
222 bool SetLocalCertificate(
223 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
224 certificate_ = certificate;
225 return true;
226 }
227
228 void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
229 remote_cert_ = cert;
230 }
231
232 bool IsDtlsActive() const override {
233 return do_dtls_;
234 }
235
236 bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override {
237 srtp_ciphers_ = ciphers;
238 return true;
239 }
240
241 bool GetSrtpCipher(std::string* cipher) override {
242 if (!chosen_srtp_cipher_.empty()) {
243 *cipher = chosen_srtp_cipher_;
244 return true;
245 }
246 return false;
247 }
248
249 bool GetSslCipher(std::string* cipher) override {
250 return false;
251 }
252
253 rtc::scoped_refptr<rtc::RTCCertificate>
254 GetLocalCertificate() const override {
255 return certificate_;
256 }
257
258 bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override {
259 if (!remote_cert_)
260 return false;
261
262 *cert = remote_cert_->GetReference();
263 return true;
264 }
265
266 bool ExportKeyingMaterial(const std::string& label,
267 const uint8* context,
268 size_t context_len,
269 bool use_context,
270 uint8* result,
271 size_t result_len) override {
272 if (!chosen_srtp_cipher_.empty()) {
273 memset(result, 0xff, result_len);
274 return true;
275 }
276
277 return false;
278 }
279
280 virtual void NegotiateSrtpCiphers() {
281 for (std::vector<std::string>::const_iterator it1 = srtp_ciphers_.begin();
282 it1 != srtp_ciphers_.end(); ++it1) {
283 for (std::vector<std::string>::const_iterator it2 =
284 dest_->srtp_ciphers_.begin();
285 it2 != dest_->srtp_ciphers_.end(); ++it2) {
286 if (*it1 == *it2) {
287 chosen_srtp_cipher_ = *it1;
288 dest_->chosen_srtp_cipher_ = *it2;
289 return;
290 }
291 }
292 }
293 }
294
295 bool GetStats(ConnectionInfos* infos) override {
296 ConnectionInfo info;
297 infos->clear();
298 infos->push_back(info);
299 return true;
300 }
301
302 private:
303 enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED };
304 Transport* transport_;
305 FakeTransportChannel* dest_;
306 State state_;
307 bool async_;
308 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
309 rtc::FakeSSLCertificate* remote_cert_;
310 bool do_dtls_;
311 std::vector<std::string> srtp_ciphers_;
312 std::string chosen_srtp_cipher_;
313 IceRole role_;
314 uint64 tiebreaker_;
315 std::string ice_ufrag_;
316 std::string ice_pwd_;
317 std::string remote_ice_ufrag_;
318 std::string remote_ice_pwd_;
319 IceMode remote_ice_mode_;
320 rtc::SSLFingerprint dtls_fingerprint_;
321 rtc::SSLRole ssl_role_;
322 size_t connection_count_;
323 };
324
325 // Fake transport class, which can be passed to anything that needs a Transport.
326 // Can be informed of another FakeTransport via SetDestination (low-tech way
327 // of doing candidates)
328 class FakeTransport : public Transport {
329 public:
330 typedef std::map<int, FakeTransportChannel*> ChannelMap;
331 FakeTransport(rtc::Thread* signaling_thread,
332 rtc::Thread* worker_thread,
333 const std::string& content_name,
334 PortAllocator* alllocator = nullptr)
335 : Transport(signaling_thread, worker_thread,
336 content_name, nullptr),
337 dest_(nullptr),
338 async_(false) {
339 }
340 ~FakeTransport() {
341 DestroyAllChannels();
342 }
343
344 const ChannelMap& channels() const { return channels_; }
345
346 void SetAsync(bool async) { async_ = async; }
347 void SetDestination(FakeTransport* dest) {
348 dest_ = dest;
349 for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
350 ++it) {
351 it->second->SetLocalCertificate(certificate_);
352 SetChannelDestination(it->first, it->second);
353 }
354 }
355
356 void SetWritable(bool writable) {
357 for (ChannelMap::iterator it = channels_.begin(); it != channels_.end();
358 ++it) {
359 it->second->SetWritable(writable);
360 }
361 }
362
363 void set_certificate(
364 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
365 certificate_ = certificate;
366 }
367
368 using Transport::local_description;
369 using Transport::remote_description;
370
371 protected:
372 TransportChannelImpl* CreateTransportChannel(int component) override {
373 if (channels_.find(component) != channels_.end()) {
374 return NULL;
375 }
376 FakeTransportChannel* channel =
377 new FakeTransportChannel(this, content_name(), component);
378 channel->SetAsync(async_);
379 SetChannelDestination(component, channel);
380 channels_[component] = channel;
381 return channel;
382 }
383 void DestroyTransportChannel(TransportChannelImpl* channel) override {
384 channels_.erase(channel->component());
385 delete channel;
386 }
387 void SetCertificate_w(
388 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
389 certificate_ = certificate;
390 }
391 bool GetCertificate_w(
392 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
393 if (!certificate_)
394 return false;
395
396 *certificate = certificate_;
397 return true;
398 }
399
400 private:
401 FakeTransportChannel* GetFakeChannel(int component) {
402 ChannelMap::iterator it = channels_.find(component);
403 return (it != channels_.end()) ? it->second : NULL;
404 }
405 void SetChannelDestination(int component,
406 FakeTransportChannel* channel) {
407 FakeTransportChannel* dest_channel = NULL;
408 if (dest_) {
409 dest_channel = dest_->GetFakeChannel(component);
410 if (dest_channel)
411 dest_channel->SetLocalCertificate(dest_->certificate_);
412 }
413 channel->SetDestination(dest_channel);
414 }
415
416 // Note, this is distinct from the Channel map owned by Transport.
417 // This map just tracks the FakeTransportChannels created by this class.
418 ChannelMap channels_;
419 FakeTransport* dest_;
420 bool async_;
421 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
422 };
423
424 // Fake session class, which can be passed into a BaseChannel object for
425 // test purposes. Can be connected to other FakeSessions via Connect().
426 class FakeSession : public BaseSession {
427 public:
428 explicit FakeSession()
429 : BaseSession(rtc::Thread::Current(),
430 rtc::Thread::Current(),
431 NULL, "", "", true),
432 fail_create_channel_(false) {
433 }
434 explicit FakeSession(bool initiator)
435 : BaseSession(rtc::Thread::Current(),
436 rtc::Thread::Current(),
437 NULL, "", "", initiator),
438 fail_create_channel_(false) {
439 }
440 FakeSession(rtc::Thread* worker_thread, bool initiator)
441 : BaseSession(rtc::Thread::Current(),
442 worker_thread,
443 NULL, "", "", initiator),
444 fail_create_channel_(false) {
445 }
446
447 FakeTransport* GetTransport(const std::string& content_name) {
448 return static_cast<FakeTransport*>(
449 BaseSession::GetTransport(content_name));
450 }
451
452 void Connect(FakeSession* dest) {
453 // Simulate the exchange of candidates.
454 CompleteNegotiation();
455 dest->CompleteNegotiation();
456 for (TransportMap::const_iterator it = transport_proxies().begin();
457 it != transport_proxies().end(); ++it) {
458 static_cast<FakeTransport*>(it->second->impl())->SetDestination(
459 dest->GetTransport(it->first));
460 }
461 }
462
463 TransportChannel* CreateChannel(const std::string& content_name,
464 int component) override {
465 if (fail_create_channel_) {
466 return NULL;
467 }
468 return BaseSession::CreateChannel(content_name, component);
469 }
470
471 void set_fail_channel_creation(bool fail_channel_creation) {
472 fail_create_channel_ = fail_channel_creation;
473 }
474
475 // TODO: Hoist this into Session when we re-work the Session code.
476 void set_ssl_rtccertificate(
477 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
478 for (TransportMap::const_iterator it = transport_proxies().begin();
479 it != transport_proxies().end(); ++it) {
480 // We know that we have a FakeTransport*
481
482 static_cast<FakeTransport*>(it->second->impl())->set_certificate
483 (certificate);
484 }
485 }
486
487 protected:
488 Transport* CreateTransport(const std::string& content_name) override {
489 return new FakeTransport(signaling_thread(), worker_thread(), content_name);
490 }
491
492 void CompleteNegotiation() {
493 for (TransportMap::const_iterator it = transport_proxies().begin();
494 it != transport_proxies().end(); ++it) {
495 it->second->CompleteNegotiation();
496 it->second->ConnectChannels();
497 }
498 }
499
500 private:
501 bool fail_create_channel_;
502 };
503
504 } // namespace cricket
505
506 #endif // WEBRTC_P2P_BASE_FAKESESSION_H_
OLDNEW
« no previous file with comments | « webrtc/p2p/base/dtlstransportchannel_unittest.cc ('k') | webrtc/p2p/base/faketransportcontroller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698