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

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

Issue 1246913005: TransportController refactoring (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Merging again 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_FAKETRANSPORTCONTROLLER_H_
12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
13
14 #include <map>
15 #include <string>
16 #include <vector>
17
18 #include "webrtc/p2p/base/transport.h"
19 #include "webrtc/p2p/base/transportchannel.h"
20 #include "webrtc/p2p/base/transportcontroller.h"
21 #include "webrtc/p2p/base/transportchannelimpl.h"
22 #include "webrtc/base/bind.h"
23 #include "webrtc/base/buffer.h"
24 #include "webrtc/base/fakesslidentity.h"
25 #include "webrtc/base/messagequeue.h"
26 #include "webrtc/base/sigslot.h"
27 #include "webrtc/base/sslfingerprint.h"
28 #include "webrtc/base/thread.h"
29
30 namespace cricket {
31
32 class FakeTransport;
33
34 struct PacketMessageData : public rtc::MessageData {
35 PacketMessageData(const char* data, size_t len) : packet(data, len) {}
36 rtc::Buffer packet;
37 };
38
39 // Fake transport channel class, which can be passed to anything that needs a
40 // transport channel. Can be informed of another FakeTransportChannel via
41 // SetDestination.
42 // TODO(hbos): Move implementation to .cc file, this and other classes in file.
43 class FakeTransportChannel : public TransportChannelImpl,
44 public rtc::MessageHandler {
45 public:
46 explicit FakeTransportChannel(Transport* transport,
47 const std::string& name,
48 int component)
49 : TransportChannelImpl(name, component),
50 transport_(transport),
51 dtls_fingerprint_("", nullptr, 0) {}
52 ~FakeTransportChannel() { Reset(); }
53
54 uint64 IceTiebreaker() const { return tiebreaker_; }
55 IceMode remote_ice_mode() const { return remote_ice_mode_; }
56 const std::string& ice_ufrag() const { return ice_ufrag_; }
57 const std::string& ice_pwd() const { return ice_pwd_; }
58 const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
59 const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
60 const rtc::SSLFingerprint& dtls_fingerprint() const {
61 return dtls_fingerprint_;
62 }
63
64 // If async, will send packets by "Post"-ing to message queue instead of
65 // synchronously "Send"-ing.
66 void SetAsync(bool async) { async_ = async; }
67
68 Transport* GetTransport() override { return transport_; }
69
70 TransportChannelState GetState() const override {
71 if (connection_count_ == 0) {
72 return had_connection_ ? TransportChannelState::STATE_FAILED
73 : TransportChannelState::STATE_INIT;
74 }
75
76 if (connection_count_ == 1) {
77 return TransportChannelState::STATE_COMPLETED;
78 }
79
80 return TransportChannelState::STATE_CONNECTING;
81 }
82
83 void SetIceRole(IceRole role) override { role_ = role; }
84 IceRole GetIceRole() const override { return role_; }
85 void SetIceTiebreaker(uint64 tiebreaker) override {
86 tiebreaker_ = tiebreaker;
87 }
88 void SetIceCredentials(const std::string& ice_ufrag,
89 const std::string& ice_pwd) override {
90 ice_ufrag_ = ice_ufrag;
91 ice_pwd_ = ice_pwd;
92 }
93 void SetRemoteIceCredentials(const std::string& ice_ufrag,
94 const std::string& ice_pwd) override {
95 remote_ice_ufrag_ = ice_ufrag;
96 remote_ice_pwd_ = ice_pwd;
97 }
98
99 void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
100 bool SetRemoteFingerprint(const std::string& alg,
101 const uint8* digest,
102 size_t digest_len) override {
103 dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
104 return true;
105 }
106 bool SetSslRole(rtc::SSLRole role) override {
107 ssl_role_ = role;
108 return true;
109 }
110 bool GetSslRole(rtc::SSLRole* role) const override {
111 *role = ssl_role_;
112 return true;
113 }
114
115 void Connect() override {
116 if (state_ == STATE_INIT) {
117 state_ = STATE_CONNECTING;
118 // Connect is expected to start candidate gathering
119 if (gathering_state_ != kIceGatheringGathering) {
120 gathering_state_ = kIceGatheringGathering;
121 SignalGatheringState(this);
122 }
123 }
124 }
125
126 IceGatheringState gathering_state() const override {
127 return gathering_state_;
128 }
129
130 void Reset() {
131 if (state_ != STATE_INIT) {
132 state_ = STATE_INIT;
133 if (dest_) {
134 dest_->state_ = STATE_INIT;
135 dest_->dest_ = nullptr;
136 dest_ = nullptr;
137 }
138 }
139 }
140
141 void SetWritable(bool writable) { set_writable(writable); }
142
143 void SetDestination(FakeTransportChannel* dest) {
144 if (state_ == STATE_CONNECTING && dest) {
145 // This simulates the delivery of candidates.
146 dest_ = dest;
147 dest_->dest_ = this;
148 if (identity_ && dest_->identity_) {
149 do_dtls_ = true;
150 dest_->do_dtls_ = true;
151 NegotiateSrtpCiphers();
152 }
153 state_ = STATE_CONNECTED;
154 dest_->state_ = STATE_CONNECTED;
155 set_writable(true);
156 dest_->set_writable(true);
157 } else if (state_ == STATE_CONNECTED && !dest) {
158 // Simulates loss of connectivity, by asymmetrically forgetting dest_.
159 dest_ = nullptr;
160 state_ = STATE_CONNECTING;
161 set_writable(false);
162 }
163 }
164
165 void SetConnectionCount(size_t connection_count) {
166 size_t old_connection_count = connection_count_;
167 connection_count_ = connection_count;
168 if (connection_count)
169 had_connection_ = true;
170 if (connection_count_ < old_connection_count)
171 SignalConnectionRemoved(this);
172 }
173
174 void SetCandidatesGatheringComplete() {
175 if (gathering_state_ != kIceGatheringComplete) {
176 gathering_state_ = kIceGatheringComplete;
177 SignalGatheringState(this);
178 }
179 }
180
181 void SetReceiving(bool receiving) { set_receiving(receiving); }
182
183 void SetReceivingTimeout(int timeout) override {
184 receiving_timeout_ = timeout;
185 }
186
187 int receiving_timeout() const { return receiving_timeout_; }
188
189 int SendPacket(const char* data,
190 size_t len,
191 const rtc::PacketOptions& options,
192 int flags) override {
193 if (state_ != STATE_CONNECTED) {
194 return -1;
195 }
196
197 if (flags != PF_SRTP_BYPASS && flags != 0) {
198 return -1;
199 }
200
201 PacketMessageData* packet = new PacketMessageData(data, len);
202 if (async_) {
203 rtc::Thread::Current()->Post(this, 0, packet);
204 } else {
205 rtc::Thread::Current()->Send(this, 0, packet);
206 }
207 return static_cast<int>(len);
208 }
209 int SetOption(rtc::Socket::Option opt, int value) override { return true; }
210 bool GetOption(rtc::Socket::Option opt, int* value) override { return true; }
211 int GetError() override { return 0; }
212
213 void AddRemoteCandidate(const Candidate& candidate) override {
214 remote_candidates_.push_back(candidate);
215 }
216 const Candidates& remote_candidates() const { return remote_candidates_; }
217
218 void OnMessage(rtc::Message* msg) override {
219 PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata);
220 dest_->SignalReadPacket(dest_, data->packet.data<char>(),
221 data->packet.size(), rtc::CreatePacketTime(0), 0);
222 delete data;
223 }
224
225 bool SetLocalIdentity(rtc::SSLIdentity* identity) {
226 identity_ = identity;
227 return true;
228 }
229
230 void SetRemoteCertificate(rtc::FakeSSLCertificate* cert) {
231 remote_cert_ = cert;
232 }
233
234 bool IsDtlsActive() const override { return do_dtls_; }
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 { return false; }
250
251 bool GetLocalIdentity(rtc::SSLIdentity** identity) const override {
252 if (!identity_)
253 return false;
254
255 *identity = identity_->GetReference();
256 return true;
257 }
258
259 bool GetRemoteCertificate(rtc::SSLCertificate** cert) const override {
260 if (!remote_cert_)
261 return false;
262
263 *cert = remote_cert_->GetReference();
264 return true;
265 }
266
267 bool ExportKeyingMaterial(const std::string& label,
268 const uint8* context,
269 size_t context_len,
270 bool use_context,
271 uint8* result,
272 size_t result_len) override {
273 if (!chosen_srtp_cipher_.empty()) {
274 memset(result, 0xff, result_len);
275 return true;
276 }
277
278 return false;
279 }
280
281 void NegotiateSrtpCiphers() {
282 for (std::vector<std::string>::const_iterator it1 = srtp_ciphers_.begin();
283 it1 != srtp_ciphers_.end(); ++it1) {
284 for (std::vector<std::string>::const_iterator it2 =
285 dest_->srtp_ciphers_.begin();
286 it2 != dest_->srtp_ciphers_.end(); ++it2) {
287 if (*it1 == *it2) {
288 chosen_srtp_cipher_ = *it1;
289 dest_->chosen_srtp_cipher_ = *it2;
290 return;
291 }
292 }
293 }
294 }
295
296 bool GetStats(ConnectionInfos* infos) override {
297 ConnectionInfo info;
298 infos->clear();
299 infos->push_back(info);
300 return true;
301 }
302
303 void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
304 ssl_max_version_ = version;
305 }
306 rtc::SSLProtocolVersion ssl_max_protocol_version() const {
307 return ssl_max_version_;
308 }
309
310 private:
311 enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED };
312 Transport* transport_;
313 FakeTransportChannel* dest_ = nullptr;
314 State state_ = STATE_INIT;
315 bool async_ = false;
316 Candidates remote_candidates_;
317 rtc::SSLIdentity* identity_ = nullptr;
318 rtc::FakeSSLCertificate* remote_cert_ = nullptr;
319 bool do_dtls_ = false;
320 std::vector<std::string> srtp_ciphers_;
321 std::string chosen_srtp_cipher_;
322 int receiving_timeout_ = -1;
323 IceRole role_ = ICEROLE_UNKNOWN;
324 uint64 tiebreaker_ = 0;
325 std::string ice_ufrag_;
326 std::string ice_pwd_;
327 std::string remote_ice_ufrag_;
328 std::string remote_ice_pwd_;
329 IceMode remote_ice_mode_ = ICEMODE_FULL;
330 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_10;
331 rtc::SSLFingerprint dtls_fingerprint_;
332 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
333 size_t connection_count_ = 0;
334 IceGatheringState gathering_state_ = kIceGatheringNew;
335 bool had_connection_ = false;
336 };
337
338 // Fake transport class, which can be passed to anything that needs a Transport.
339 // Can be informed of another FakeTransport via SetDestination (low-tech way
340 // of doing candidates)
341 class FakeTransport : public Transport {
342 public:
343 typedef std::map<int, FakeTransportChannel*> ChannelMap;
344
345 explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {}
346
347 // Note that we only have a constructor with the allocator parameter so it can
348 // be wrapped by a DtlsTransport.
349 FakeTransport(const std::string& name, PortAllocator* allocator)
350 : Transport(name, nullptr) {}
351
352 ~FakeTransport() { DestroyAllChannels(); }
353
354 const ChannelMap& channels() const { return channels_; }
355
356 // If async, will send packets by "Post"-ing to message queue instead of
357 // synchronously "Send"-ing.
358 void SetAsync(bool async) { async_ = async; }
359 void SetDestination(FakeTransport* dest) {
360 dest_ = dest;
361 for (const auto& kv : channels_) {
362 // TODO(hbos): SetLocalCertificate
363 kv.second->SetLocalIdentity(certificate_ ? certificate_->identity()
364 : nullptr);
365 SetChannelDestination(kv.first, kv.second);
366 }
367 }
368
369 void SetWritable(bool writable) {
370 for (const auto& kv : channels_) {
371 kv.second->SetWritable(writable);
372 }
373 }
374
375 void SetLocalCertificate(
376 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
377 certificate_ = certificate;
378 }
379 bool GetLocalCertificate(
380 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
381 if (!certificate_)
382 return false;
383
384 *certificate = certificate_;
385 return true;
386 }
387
388 bool GetSslRole(rtc::SSLRole* role) const override {
389 if (channels_.empty()) {
390 return false;
391 }
392 return channels_.cbegin()->second->GetSslRole(role);
393 }
394
395 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override {
396 ssl_max_version_ = version;
397 for (const auto& kv : channels_) {
398 kv.second->set_ssl_max_protocol_version(ssl_max_version_);
399 }
400 return true;
401 }
402 rtc::SSLProtocolVersion ssl_max_protocol_version() const {
403 return ssl_max_version_;
404 }
405
406 using Transport::local_description;
407 using Transport::remote_description;
408
409 protected:
410 TransportChannelImpl* CreateTransportChannel(int component) override {
411 if (channels_.find(component) != channels_.end()) {
412 return nullptr;
413 }
414 FakeTransportChannel* channel =
415 new FakeTransportChannel(this, name(), component);
416 channel->set_ssl_max_protocol_version(ssl_max_version_);
417 channel->SetAsync(async_);
418 SetChannelDestination(component, channel);
419 channels_[component] = channel;
420 return channel;
421 }
422
423 void DestroyTransportChannel(TransportChannelImpl* channel) override {
424 channels_.erase(channel->component());
425 delete channel;
426 }
427
428 private:
429 FakeTransportChannel* GetFakeChannel(int component) {
430 auto it = channels_.find(component);
431 return (it != channels_.end()) ? it->second : nullptr;
432 }
433
434 void SetChannelDestination(int component, FakeTransportChannel* channel) {
435 FakeTransportChannel* dest_channel = nullptr;
436 if (dest_) {
437 dest_channel = dest_->GetFakeChannel(component);
438 if (dest_channel) {
439 // TODO(hbos): SetLocalCertificate
440 dest_channel->SetLocalIdentity(
441 dest_->certificate_ ? dest_->certificate_->identity() : nullptr);
442 }
443 }
444 channel->SetDestination(dest_channel);
445 }
446
447 // Note, this is distinct from the Channel map owned by Transport.
448 // This map just tracks the FakeTransportChannels created by this class.
449 // It's mainly needed so that we can access a FakeTransportChannel directly,
450 // even if wrapped by a DtlsTransportChannelWrapper.
451 ChannelMap channels_;
452 FakeTransport* dest_ = nullptr;
453 bool async_ = false;
454 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
455 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_10;
456 };
457
458 // Fake TransportController class, which can be passed into a BaseChannel object
459 // for test purposes. Can be connected to other FakeTransportControllers via
460 // Connect().
461 //
462 // This fake is unusual in that for the most part, it's implemented with the
463 // real TransportController code, but with fake TransportChannels underneath.
464 class FakeTransportController : public TransportController {
465 public:
466 FakeTransportController()
467 : TransportController(rtc::Thread::Current(),
468 rtc::Thread::Current(),
469 nullptr),
470 fail_create_channel_(false) {}
471
472 explicit FakeTransportController(IceRole role)
473 : TransportController(rtc::Thread::Current(),
474 rtc::Thread::Current(),
475 nullptr),
476 fail_create_channel_(false) {
477 SetIceRole(role);
478 }
479
480 explicit FakeTransportController(rtc::Thread* worker_thread)
481 : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
482 fail_create_channel_(false) {}
483
484 FakeTransportController(rtc::Thread* worker_thread, IceRole role)
485 : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
486 fail_create_channel_(false) {
487 SetIceRole(role);
488 }
489
490 FakeTransport* GetTransport_w(const std::string& transport_name) {
491 return static_cast<FakeTransport*>(
492 TransportController::GetTransport_w(transport_name));
493 }
494
495 void Connect(FakeTransportController* dest) {
496 worker_thread()->Invoke<void>(
497 rtc::Bind(&FakeTransportController::Connect_w, this, dest));
498 }
499
500 TransportChannel* CreateTransportChannel_w(const std::string& transport_name,
501 int component) override {
502 if (fail_create_channel_) {
503 return nullptr;
504 }
505 return TransportController::CreateTransportChannel_w(transport_name,
506 component);
507 }
508
509 void set_fail_channel_creation(bool fail_channel_creation) {
510 fail_create_channel_ = fail_channel_creation;
511 }
512
513 protected:
514 Transport* CreateTransport_w(const std::string& transport_name) override {
515 return new FakeTransport(transport_name);
516 }
517
518 void Connect_w(FakeTransportController* dest) {
519 // Simulate the exchange of candidates.
520 ConnectChannels_w();
521 dest->ConnectChannels_w();
522 for (auto& kv : transports()) {
523 FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
524 transport->SetDestination(dest->GetTransport_w(kv.first));
525 }
526 }
527
528 void ConnectChannels_w() {
529 for (auto& kv : transports()) {
530 FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
531 transport->ConnectChannels();
532 }
533 }
534
535 private:
536 bool fail_create_channel_;
537 };
538
539 } // namespace cricket
540
541 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698