OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2009 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 11 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
13 | 13 |
14 #include <map> | 14 #include <map> |
15 #include <memory> | 15 #include <memory> |
16 #include <string> | 16 #include <string> |
17 #include <vector> | 17 #include <vector> |
18 | 18 |
19 #include "webrtc/p2p/base/candidatepairinterface.h" | 19 #include "webrtc/p2p/base/candidatepairinterface.h" |
20 #include "webrtc/p2p/base/transport.h" | |
21 #include "webrtc/p2p/base/transportchannel.h" | 20 #include "webrtc/p2p/base/transportchannel.h" |
22 #include "webrtc/p2p/base/transportcontroller.h" | 21 #include "webrtc/p2p/base/transportcontroller.h" |
23 #include "webrtc/p2p/base/transportchannelimpl.h" | 22 #include "webrtc/p2p/base/transportchannelimpl.h" |
24 #include "webrtc/base/bind.h" | 23 #include "webrtc/base/bind.h" |
25 #include "webrtc/base/buffer.h" | 24 #include "webrtc/base/buffer.h" |
26 #include "webrtc/base/fakesslidentity.h" | 25 #include "webrtc/base/fakesslidentity.h" |
27 #include "webrtc/base/messagequeue.h" | 26 #include "webrtc/base/messagequeue.h" |
28 #include "webrtc/base/sigslot.h" | 27 #include "webrtc/base/sigslot.h" |
29 #include "webrtc/base/sslfingerprint.h" | 28 #include "webrtc/base/sslfingerprint.h" |
30 #include "webrtc/base/thread.h" | 29 #include "webrtc/base/thread.h" |
31 | 30 |
32 #ifdef HAVE_QUIC | 31 #ifdef HAVE_QUIC |
33 #include "webrtc/p2p/quic/quictransport.h" | 32 #include "webrtc/p2p/quic/quictransport.h" |
34 #endif | 33 #endif |
35 | 34 |
36 namespace cricket { | 35 namespace cricket { |
37 | 36 |
38 class FakeTransport; | |
39 | |
40 namespace { | 37 namespace { |
41 struct PacketMessageData : public rtc::MessageData { | 38 struct PacketMessageData : public rtc::MessageData { |
42 PacketMessageData(const char* data, size_t len) : packet(data, len) {} | 39 PacketMessageData(const char* data, size_t len) : packet(data, len) {} |
43 rtc::Buffer packet; | 40 rtc::Buffer packet; |
44 }; | 41 }; |
45 } // namespace | 42 } // namespace |
46 | 43 |
47 // Fake transport channel class, which can be passed to anything that needs a | 44 // Fake transport channel class, which can be passed to anything that needs a |
48 // transport channel. Can be informed of another FakeTransportChannel via | 45 // transport channel. Can be informed of another FakeTransportChannel via |
49 // SetDestination. | 46 // SetDestination. |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 std::string remote_ice_pwd_; | 333 std::string remote_ice_pwd_; |
337 IceMode remote_ice_mode_ = ICEMODE_FULL; | 334 IceMode remote_ice_mode_ = ICEMODE_FULL; |
338 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 335 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
339 rtc::SSLFingerprint dtls_fingerprint_; | 336 rtc::SSLFingerprint dtls_fingerprint_; |
340 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; | 337 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; |
341 size_t connection_count_ = 0; | 338 size_t connection_count_ = 0; |
342 IceGatheringState gathering_state_ = kIceGatheringNew; | 339 IceGatheringState gathering_state_ = kIceGatheringNew; |
343 bool had_connection_ = false; | 340 bool had_connection_ = false; |
344 }; | 341 }; |
345 | 342 |
346 // Fake transport class, which can be passed to anything that needs a Transport. | |
347 // Can be informed of another FakeTransport via SetDestination (low-tech way | |
348 // of doing candidates) | |
349 class FakeTransport : public Transport { | |
350 public: | |
351 typedef std::map<int, FakeTransportChannel*> ChannelMap; | |
352 | |
353 explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {} | |
354 | |
355 // Note that we only have a constructor with the allocator parameter so it can | |
356 // be wrapped by a DtlsTransport. | |
357 FakeTransport(const std::string& name, PortAllocator* allocator) | |
358 : Transport(name, nullptr) {} | |
359 | |
360 ~FakeTransport() { DestroyAllChannels(); } | |
361 | |
362 const ChannelMap& channels() const { return channels_; } | |
363 | |
364 // If async, will send packets by "Post"-ing to message queue instead of | |
365 // synchronously "Send"-ing. | |
366 void SetAsync(bool async) { async_ = async; } | |
367 void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; } | |
368 | |
369 // If |asymmetric| is true, only set the destination for this transport, and | |
370 // not |dest|. | |
371 void SetDestination(FakeTransport* dest, bool asymmetric = false) { | |
372 dest_ = dest; | |
373 for (const auto& kv : channels_) { | |
374 kv.second->SetLocalCertificate(certificate_); | |
375 SetChannelDestination(kv.first, kv.second, asymmetric); | |
376 } | |
377 } | |
378 | |
379 void SetWritable(bool writable) { | |
380 for (const auto& kv : channels_) { | |
381 kv.second->SetWritable(writable); | |
382 } | |
383 } | |
384 | |
385 void SetLocalCertificate( | |
386 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override { | |
387 certificate_ = certificate; | |
388 } | |
389 bool GetLocalCertificate( | |
390 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override { | |
391 if (!certificate_) | |
392 return false; | |
393 | |
394 *certificate = certificate_; | |
395 return true; | |
396 } | |
397 | |
398 bool GetSslRole(rtc::SSLRole* role) const override { | |
399 if (channels_.empty()) { | |
400 return false; | |
401 } | |
402 return channels_.begin()->second->GetSslRole(role); | |
403 } | |
404 | |
405 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { | |
406 ssl_max_version_ = version; | |
407 for (const auto& kv : channels_) { | |
408 kv.second->set_ssl_max_protocol_version(ssl_max_version_); | |
409 } | |
410 return true; | |
411 } | |
412 rtc::SSLProtocolVersion ssl_max_protocol_version() const { | |
413 return ssl_max_version_; | |
414 } | |
415 | |
416 using Transport::local_description; | |
417 using Transport::remote_description; | |
418 using Transport::VerifyCertificateFingerprint; | |
419 using Transport::NegotiateRole; | |
420 | |
421 protected: | |
422 TransportChannelImpl* CreateTransportChannel(int component) override { | |
423 if (channels_.find(component) != channels_.end()) { | |
424 return nullptr; | |
425 } | |
426 FakeTransportChannel* channel = new FakeTransportChannel(name(), component); | |
427 channel->set_ssl_max_protocol_version(ssl_max_version_); | |
428 channel->SetAsync(async_); | |
429 channel->SetAsyncDelay(async_delay_ms_); | |
430 SetChannelDestination(component, channel, false); | |
431 channels_[component] = channel; | |
432 return channel; | |
433 } | |
434 | |
435 void DestroyTransportChannel(TransportChannelImpl* channel) override { | |
436 channels_.erase(channel->component()); | |
437 delete channel; | |
438 } | |
439 | |
440 private: | |
441 FakeTransportChannel* GetFakeChannel(int component) { | |
442 auto it = channels_.find(component); | |
443 return (it != channels_.end()) ? it->second : nullptr; | |
444 } | |
445 | |
446 void SetChannelDestination(int component, | |
447 FakeTransportChannel* channel, | |
448 bool asymmetric) { | |
449 FakeTransportChannel* dest_channel = nullptr; | |
450 if (dest_) { | |
451 dest_channel = dest_->GetFakeChannel(component); | |
452 if (dest_channel && !asymmetric) { | |
453 dest_channel->SetLocalCertificate(dest_->certificate_); | |
454 } | |
455 } | |
456 channel->SetDestination(dest_channel, asymmetric); | |
457 } | |
458 | |
459 // Note, this is distinct from the Channel map owned by Transport. | |
460 // This map just tracks the FakeTransportChannels created by this class. | |
461 // It's mainly needed so that we can access a FakeTransportChannel directly, | |
462 // even if wrapped by a DtlsTransportChannelWrapper. | |
463 ChannelMap channels_; | |
464 FakeTransport* dest_ = nullptr; | |
465 bool async_ = false; | |
466 int async_delay_ms_ = 0; | |
467 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | |
468 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | |
469 }; | |
470 | |
471 #ifdef HAVE_QUIC | |
472 class FakeQuicTransport : public QuicTransport { | |
473 public: | |
474 FakeQuicTransport(const std::string& transport_name) | |
475 : QuicTransport(transport_name, nullptr, nullptr) {} | |
476 | |
477 protected: | |
478 QuicTransportChannel* CreateTransportChannel(int component) override { | |
479 FakeTransportChannel* fake_ice_transport_channel = | |
480 new FakeTransportChannel(name(), component); | |
481 return new QuicTransportChannel(fake_ice_transport_channel); | |
482 } | |
483 }; | |
484 #endif | |
485 | |
486 // Fake candidate pair class, which can be passed to BaseChannel for testing | 343 // Fake candidate pair class, which can be passed to BaseChannel for testing |
487 // purposes. | 344 // purposes. |
488 class FakeCandidatePair : public CandidatePairInterface { | 345 class FakeCandidatePair : public CandidatePairInterface { |
489 public: | 346 public: |
490 FakeCandidatePair(const Candidate& local_candidate, | 347 FakeCandidatePair(const Candidate& local_candidate, |
491 const Candidate& remote_candidate) | 348 const Candidate& remote_candidate) |
492 : local_candidate_(local_candidate), | 349 : local_candidate_(local_candidate), |
493 remote_candidate_(remote_candidate) {} | 350 remote_candidate_(remote_candidate) {} |
494 const Candidate& local_candidate() const override { return local_candidate_; } | 351 const Candidate& local_candidate() const override { return local_candidate_; } |
495 const Candidate& remote_candidate() const override { | 352 const Candidate& remote_candidate() const override { |
496 return remote_candidate_; | 353 return remote_candidate_; |
497 } | 354 } |
498 | 355 |
499 private: | 356 private: |
500 Candidate local_candidate_; | 357 Candidate local_candidate_; |
501 Candidate remote_candidate_; | 358 Candidate remote_candidate_; |
502 }; | 359 }; |
503 | 360 |
504 // Fake TransportController class, which can be passed into a BaseChannel object | 361 // Fake TransportController class, which can be passed into a BaseChannel object |
505 // for test purposes. Can be connected to other FakeTransportControllers via | 362 // for test purposes. Can be connected to other FakeTransportControllers via |
506 // Connect(). | 363 // Connect(). |
507 // | 364 // |
508 // This fake is unusual in that for the most part, it's implemented with the | 365 // This fake is unusual in that for the most part, it's implemented with the |
509 // real TransportController code, but with fake TransportChannels underneath. | 366 // real TransportController code, but with fake TransportChannels underneath. |
510 class FakeTransportController : public TransportController { | 367 class FakeTransportController : public TransportController { |
511 public: | 368 public: |
512 FakeTransportController() | 369 FakeTransportController() |
513 : TransportController(rtc::Thread::Current(), | 370 : TransportController(rtc::Thread::Current(), |
514 rtc::Thread::Current(), | 371 rtc::Thread::Current(), |
515 nullptr), | 372 nullptr) {} |
516 fail_create_channel_(false) {} | |
517 | 373 |
518 explicit FakeTransportController(bool redetermine_role_on_ice_restart) | 374 explicit FakeTransportController(bool redetermine_role_on_ice_restart) |
519 : TransportController(rtc::Thread::Current(), | 375 : TransportController(rtc::Thread::Current(), |
520 rtc::Thread::Current(), | 376 rtc::Thread::Current(), |
521 nullptr, | 377 nullptr, |
522 redetermine_role_on_ice_restart), | 378 redetermine_role_on_ice_restart) {} |
523 fail_create_channel_(false) {} | |
524 | 379 |
525 explicit FakeTransportController(IceRole role) | 380 explicit FakeTransportController(IceRole role) |
526 : TransportController(rtc::Thread::Current(), | 381 : TransportController(rtc::Thread::Current(), |
527 rtc::Thread::Current(), | 382 rtc::Thread::Current(), |
528 nullptr), | 383 nullptr) { |
529 fail_create_channel_(false) { | |
530 SetIceRole(role); | 384 SetIceRole(role); |
531 } | 385 } |
532 | 386 |
533 explicit FakeTransportController(rtc::Thread* network_thread) | 387 explicit FakeTransportController(rtc::Thread* network_thread) |
534 : TransportController(rtc::Thread::Current(), network_thread, nullptr), | 388 : TransportController(rtc::Thread::Current(), network_thread, nullptr) {} |
535 fail_create_channel_(false) {} | |
536 | 389 |
537 FakeTransportController(rtc::Thread* network_thread, IceRole role) | 390 FakeTransportController(rtc::Thread* network_thread, IceRole role) |
538 : TransportController(rtc::Thread::Current(), network_thread, nullptr), | 391 : TransportController(rtc::Thread::Current(), network_thread, nullptr) { |
539 fail_create_channel_(false) { | |
540 SetIceRole(role); | 392 SetIceRole(role); |
541 } | 393 } |
542 | 394 |
543 FakeTransport* GetTransport_n(const std::string& transport_name) { | 395 FakeTransportChannel* GetFakeTransportChannel_n( |
544 return static_cast<FakeTransport*>( | 396 const std::string& transport_name, |
545 TransportController::GetTransport_n(transport_name)); | 397 int component) { |
| 398 return static_cast<FakeTransportChannel*>( |
| 399 get_channel_for_testing(transport_name, component)); |
546 } | 400 } |
547 | 401 |
| 402 // Simulate the exchange of transport descriptions, and the gathering and |
| 403 // exchange of ICE candidates. |
548 void Connect(FakeTransportController* dest) { | 404 void Connect(FakeTransportController* dest) { |
| 405 for (const std::string& transport_name : transport_names_for_testing()) { |
| 406 TransportDescription local_desc( |
| 407 std::vector<std::string>(), |
| 408 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), |
| 409 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), |
| 410 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, nullptr); |
| 411 TransportDescription remote_desc( |
| 412 std::vector<std::string>(), |
| 413 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), |
| 414 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), |
| 415 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, nullptr); |
| 416 std::string err; |
| 417 SetLocalTransportDescription(transport_name, local_desc, |
| 418 cricket::CA_OFFER, &err); |
| 419 dest->SetRemoteTransportDescription(transport_name, local_desc, |
| 420 cricket::CA_OFFER, &err); |
| 421 dest->SetLocalTransportDescription(transport_name, remote_desc, |
| 422 cricket::CA_ANSWER, &err); |
| 423 SetRemoteTransportDescription(transport_name, remote_desc, |
| 424 cricket::CA_ANSWER, &err); |
| 425 } |
| 426 MaybeStartGathering(); |
| 427 dest->MaybeStartGathering(); |
549 network_thread()->Invoke<void>( | 428 network_thread()->Invoke<void>( |
550 RTC_FROM_HERE, | 429 RTC_FROM_HERE, |
551 rtc::Bind(&FakeTransportController::Connect_n, this, dest)); | 430 rtc::Bind(&FakeTransportController::SetChannelDestinations_n, this, |
552 } | 431 dest)); |
553 | |
554 TransportChannel* CreateTransportChannel_n(const std::string& transport_name, | |
555 int component) override { | |
556 if (fail_create_channel_) { | |
557 return nullptr; | |
558 } | |
559 return TransportController::CreateTransportChannel_n(transport_name, | |
560 component); | |
561 } | 432 } |
562 | 433 |
563 FakeCandidatePair* CreateFakeCandidatePair( | 434 FakeCandidatePair* CreateFakeCandidatePair( |
564 const rtc::SocketAddress& local_address, | 435 const rtc::SocketAddress& local_address, |
565 int16_t local_network_id, | 436 int16_t local_network_id, |
566 const rtc::SocketAddress& remote_address, | 437 const rtc::SocketAddress& remote_address, |
567 int16_t remote_network_id) { | 438 int16_t remote_network_id) { |
568 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, | 439 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, |
569 "foundation", local_network_id, 0); | 440 "foundation", local_network_id, 0); |
570 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, | 441 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, |
571 "foundation", remote_network_id, 0); | 442 "foundation", remote_network_id, 0); |
572 return new FakeCandidatePair(local_candidate, remote_candidate); | 443 return new FakeCandidatePair(local_candidate, remote_candidate); |
573 } | 444 } |
574 | 445 |
575 void set_fail_channel_creation(bool fail_channel_creation) { | 446 protected: |
576 fail_create_channel_ = fail_channel_creation; | 447 // The ICE channel is never actually used by TransportController directly, |
| 448 // since (currently) the DTLS channel pretends to be both ICE + DTLS. This |
| 449 // will change when we get rid of TransportChannelImpl. |
| 450 TransportChannelImpl* CreateIceTransportChannel_n( |
| 451 const std::string& transport_name, |
| 452 int component) override { |
| 453 return nullptr; |
577 } | 454 } |
578 | 455 |
579 protected: | 456 TransportChannelImpl* CreateDtlsTransportChannel_n( |
580 Transport* CreateTransport_n(const std::string& transport_name) override { | 457 const std::string& transport_name, |
581 #ifdef HAVE_QUIC | 458 int component, |
582 if (quic()) { | 459 TransportChannelImpl*) override { |
583 return new FakeQuicTransport(transport_name); | 460 return new FakeTransportChannel(transport_name, component); |
584 } | |
585 #endif | |
586 return new FakeTransport(transport_name); | |
587 } | |
588 | |
589 void Connect_n(FakeTransportController* dest) { | |
590 // Simulate the exchange of candidates. | |
591 ConnectChannels_n(); | |
592 dest->ConnectChannels_n(); | |
593 for (auto& kv : transports()) { | |
594 FakeTransport* transport = static_cast<FakeTransport*>(kv.second); | |
595 transport->SetDestination(dest->GetTransport_n(kv.first)); | |
596 } | |
597 } | |
598 | |
599 void ConnectChannels_n() { | |
600 TransportDescription faketransport_desc( | |
601 std::vector<std::string>(), | |
602 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), | |
603 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), cricket::ICEMODE_FULL, | |
604 cricket::CONNECTIONROLE_NONE, nullptr); | |
605 for (auto& kv : transports()) { | |
606 FakeTransport* transport = static_cast<FakeTransport*>(kv.second); | |
607 // Set local transport description for FakeTransport before connecting. | |
608 // Otherwise, the RTC_CHECK in Transport.ConnectChannel will fail. | |
609 if (!transport->local_description()) { | |
610 transport->SetLocalTransportDescription(faketransport_desc, | |
611 cricket::CA_OFFER, nullptr); | |
612 } | |
613 transport->MaybeStartGathering(); | |
614 } | |
615 } | 461 } |
616 | 462 |
617 private: | 463 private: |
618 bool fail_create_channel_; | 464 void SetChannelDestinations_n(FakeTransportController* dest) { |
| 465 for (TransportChannelImpl* tc : channels_for_testing()) { |
| 466 FakeTransportChannel* local = static_cast<FakeTransportChannel*>(tc); |
| 467 FakeTransportChannel* remote = dest->GetFakeTransportChannel_n( |
| 468 local->transport_name(), local->component()); |
| 469 if (remote) { |
| 470 bool asymmetric = false; |
| 471 local->SetDestination(remote, asymmetric); |
| 472 } |
| 473 } |
| 474 } |
619 }; | 475 }; |
620 | 476 |
621 } // namespace cricket | 477 } // namespace cricket |
622 | 478 |
623 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 479 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
OLD | NEW |