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

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

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

Powered by Google App Engine
This is Rietveld 408576698