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" |
20 #include "webrtc/p2p/base/transportchannel.h" | 21 #include "webrtc/p2p/base/transportchannel.h" |
21 #include "webrtc/p2p/base/transportcontroller.h" | 22 #include "webrtc/p2p/base/transportcontroller.h" |
22 #include "webrtc/p2p/base/transportchannelimpl.h" | 23 #include "webrtc/p2p/base/transportchannelimpl.h" |
23 #include "webrtc/base/bind.h" | 24 #include "webrtc/base/bind.h" |
24 #include "webrtc/base/buffer.h" | 25 #include "webrtc/base/buffer.h" |
25 #include "webrtc/base/fakesslidentity.h" | 26 #include "webrtc/base/fakesslidentity.h" |
26 #include "webrtc/base/messagequeue.h" | 27 #include "webrtc/base/messagequeue.h" |
27 #include "webrtc/base/sigslot.h" | 28 #include "webrtc/base/sigslot.h" |
28 #include "webrtc/base/sslfingerprint.h" | 29 #include "webrtc/base/sslfingerprint.h" |
29 #include "webrtc/base/thread.h" | 30 #include "webrtc/base/thread.h" |
30 | 31 |
31 #ifdef HAVE_QUIC | 32 #ifdef HAVE_QUIC |
32 #include "webrtc/p2p/quic/quictransport.h" | 33 #include "webrtc/p2p/quic/quictransport.h" |
33 #endif | 34 #endif |
34 | 35 |
35 namespace cricket { | 36 namespace cricket { |
36 | 37 |
| 38 class FakeTransport; |
| 39 |
37 namespace { | 40 namespace { |
38 struct PacketMessageData : public rtc::MessageData { | 41 struct PacketMessageData : public rtc::MessageData { |
39 PacketMessageData(const char* data, size_t len) : packet(data, len) {} | 42 PacketMessageData(const char* data, size_t len) : packet(data, len) {} |
40 rtc::Buffer packet; | 43 rtc::Buffer packet; |
41 }; | 44 }; |
42 } // namespace | 45 } // namespace |
43 | 46 |
44 // Fake transport channel class, which can be passed to anything that needs a | 47 // Fake transport channel class, which can be passed to anything that needs a |
45 // transport channel. Can be informed of another FakeTransportChannel via | 48 // transport channel. Can be informed of another FakeTransportChannel via |
46 // SetDestination. | 49 // SetDestination. |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 std::string remote_ice_pwd_; | 336 std::string remote_ice_pwd_; |
334 IceMode remote_ice_mode_ = ICEMODE_FULL; | 337 IceMode remote_ice_mode_ = ICEMODE_FULL; |
335 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 338 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
336 rtc::SSLFingerprint dtls_fingerprint_; | 339 rtc::SSLFingerprint dtls_fingerprint_; |
337 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; | 340 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; |
338 size_t connection_count_ = 0; | 341 size_t connection_count_ = 0; |
339 IceGatheringState gathering_state_ = kIceGatheringNew; | 342 IceGatheringState gathering_state_ = kIceGatheringNew; |
340 bool had_connection_ = false; | 343 bool had_connection_ = false; |
341 }; | 344 }; |
342 | 345 |
| 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 |
343 // Fake candidate pair class, which can be passed to BaseChannel for testing | 486 // Fake candidate pair class, which can be passed to BaseChannel for testing |
344 // purposes. | 487 // purposes. |
345 class FakeCandidatePair : public CandidatePairInterface { | 488 class FakeCandidatePair : public CandidatePairInterface { |
346 public: | 489 public: |
347 FakeCandidatePair(const Candidate& local_candidate, | 490 FakeCandidatePair(const Candidate& local_candidate, |
348 const Candidate& remote_candidate) | 491 const Candidate& remote_candidate) |
349 : local_candidate_(local_candidate), | 492 : local_candidate_(local_candidate), |
350 remote_candidate_(remote_candidate) {} | 493 remote_candidate_(remote_candidate) {} |
351 const Candidate& local_candidate() const override { return local_candidate_; } | 494 const Candidate& local_candidate() const override { return local_candidate_; } |
352 const Candidate& remote_candidate() const override { | 495 const Candidate& remote_candidate() const override { |
353 return remote_candidate_; | 496 return remote_candidate_; |
354 } | 497 } |
355 | 498 |
356 private: | 499 private: |
357 Candidate local_candidate_; | 500 Candidate local_candidate_; |
358 Candidate remote_candidate_; | 501 Candidate remote_candidate_; |
359 }; | 502 }; |
360 | 503 |
361 // Fake TransportController class, which can be passed into a BaseChannel object | 504 // Fake TransportController class, which can be passed into a BaseChannel object |
362 // for test purposes. Can be connected to other FakeTransportControllers via | 505 // for test purposes. Can be connected to other FakeTransportControllers via |
363 // Connect(). | 506 // Connect(). |
364 // | 507 // |
365 // This fake is unusual in that for the most part, it's implemented with the | 508 // This fake is unusual in that for the most part, it's implemented with the |
366 // real TransportController code, but with fake TransportChannels underneath. | 509 // real TransportController code, but with fake TransportChannels underneath. |
367 class FakeTransportController : public TransportController { | 510 class FakeTransportController : public TransportController { |
368 public: | 511 public: |
369 FakeTransportController() | 512 FakeTransportController() |
370 : TransportController(rtc::Thread::Current(), | 513 : TransportController(rtc::Thread::Current(), |
371 rtc::Thread::Current(), | 514 rtc::Thread::Current(), |
372 nullptr) {} | 515 nullptr), |
| 516 fail_create_channel_(false) {} |
373 | 517 |
374 explicit FakeTransportController(bool redetermine_role_on_ice_restart) | 518 explicit FakeTransportController(bool redetermine_role_on_ice_restart) |
375 : TransportController(rtc::Thread::Current(), | 519 : TransportController(rtc::Thread::Current(), |
376 rtc::Thread::Current(), | 520 rtc::Thread::Current(), |
377 nullptr, | 521 nullptr, |
378 redetermine_role_on_ice_restart) {} | 522 redetermine_role_on_ice_restart), |
| 523 fail_create_channel_(false) {} |
379 | 524 |
380 explicit FakeTransportController(IceRole role) | 525 explicit FakeTransportController(IceRole role) |
381 : TransportController(rtc::Thread::Current(), | 526 : TransportController(rtc::Thread::Current(), |
382 rtc::Thread::Current(), | 527 rtc::Thread::Current(), |
383 nullptr) { | 528 nullptr), |
| 529 fail_create_channel_(false) { |
384 SetIceRole(role); | 530 SetIceRole(role); |
385 } | 531 } |
386 | 532 |
387 explicit FakeTransportController(rtc::Thread* network_thread) | 533 explicit FakeTransportController(rtc::Thread* network_thread) |
388 : TransportController(rtc::Thread::Current(), network_thread, nullptr) {} | 534 : TransportController(rtc::Thread::Current(), network_thread, nullptr), |
| 535 fail_create_channel_(false) {} |
389 | 536 |
390 FakeTransportController(rtc::Thread* network_thread, IceRole role) | 537 FakeTransportController(rtc::Thread* network_thread, IceRole role) |
391 : TransportController(rtc::Thread::Current(), network_thread, nullptr) { | 538 : TransportController(rtc::Thread::Current(), network_thread, nullptr), |
| 539 fail_create_channel_(false) { |
392 SetIceRole(role); | 540 SetIceRole(role); |
393 } | 541 } |
394 | 542 |
395 FakeTransportChannel* GetFakeTransportChannel_n( | 543 FakeTransport* GetTransport_n(const std::string& transport_name) { |
396 const std::string& transport_name, | 544 return static_cast<FakeTransport*>( |
397 int component) { | 545 TransportController::GetTransport_n(transport_name)); |
398 return static_cast<FakeTransportChannel*>( | |
399 get_channel_for_testing(transport_name, component)); | |
400 } | 546 } |
401 | 547 |
402 // Simulate the exchange of transport descriptions, and the gathering and | |
403 // exchange of ICE candidates. | |
404 void Connect(FakeTransportController* dest) { | 548 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(); | |
428 network_thread()->Invoke<void>( | 549 network_thread()->Invoke<void>( |
429 RTC_FROM_HERE, | 550 RTC_FROM_HERE, |
430 rtc::Bind(&FakeTransportController::SetChannelDestinations_n, this, | 551 rtc::Bind(&FakeTransportController::Connect_n, this, dest)); |
431 dest)); | 552 } |
| 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); |
432 } | 561 } |
433 | 562 |
434 FakeCandidatePair* CreateFakeCandidatePair( | 563 FakeCandidatePair* CreateFakeCandidatePair( |
435 const rtc::SocketAddress& local_address, | 564 const rtc::SocketAddress& local_address, |
436 int16_t local_network_id, | 565 int16_t local_network_id, |
437 const rtc::SocketAddress& remote_address, | 566 const rtc::SocketAddress& remote_address, |
438 int16_t remote_network_id) { | 567 int16_t remote_network_id) { |
439 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, | 568 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, |
440 "foundation", local_network_id, 0); | 569 "foundation", local_network_id, 0); |
441 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, | 570 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, |
442 "foundation", remote_network_id, 0); | 571 "foundation", remote_network_id, 0); |
443 return new FakeCandidatePair(local_candidate, remote_candidate); | 572 return new FakeCandidatePair(local_candidate, remote_candidate); |
444 } | 573 } |
445 | 574 |
446 protected: | 575 void set_fail_channel_creation(bool fail_channel_creation) { |
447 // The ICE channel is never actually used by TransportController directly, | 576 fail_create_channel_ = fail_channel_creation; |
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; | |
454 } | 577 } |
455 | 578 |
456 TransportChannelImpl* CreateDtlsTransportChannel_n( | 579 protected: |
457 const std::string& transport_name, | 580 Transport* CreateTransport_n(const std::string& transport_name) override { |
458 int component, | 581 #ifdef HAVE_QUIC |
459 TransportChannelImpl*) override { | 582 if (quic()) { |
460 return new FakeTransportChannel(transport_name, component); | 583 return new FakeQuicTransport(transport_name); |
| 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 } |
461 } | 615 } |
462 | 616 |
463 private: | 617 private: |
464 void SetChannelDestinations_n(FakeTransportController* dest) { | 618 bool fail_create_channel_; |
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 } | |
475 }; | 619 }; |
476 | 620 |
477 } // namespace cricket | 621 } // namespace cricket |
478 | 622 |
479 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 623 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
OLD | NEW |