2014-10-28 22:20:11 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2009 The WebRTC Project Authors. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
#ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
|
|
|
|
|
#define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
|
2014-10-28 22:20:11 +00:00
|
|
|
|
|
|
|
|
#include <map>
|
2016-04-26 03:13:22 -07:00
|
|
|
#include <memory>
|
2014-10-28 22:20:11 +00:00
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2016-03-29 17:27:21 -07:00
|
|
|
#include "webrtc/p2p/base/candidatepairinterface.h"
|
2014-10-28 22:20:11 +00:00
|
|
|
#include "webrtc/p2p/base/transport.h"
|
|
|
|
|
#include "webrtc/p2p/base/transportchannel.h"
|
2015-09-23 11:50:27 -07:00
|
|
|
#include "webrtc/p2p/base/transportcontroller.h"
|
2014-10-28 22:20:11 +00:00
|
|
|
#include "webrtc/p2p/base/transportchannelimpl.h"
|
2015-09-23 11:50:27 -07:00
|
|
|
#include "webrtc/base/bind.h"
|
2014-10-28 22:20:11 +00:00
|
|
|
#include "webrtc/base/buffer.h"
|
|
|
|
|
#include "webrtc/base/fakesslidentity.h"
|
|
|
|
|
#include "webrtc/base/messagequeue.h"
|
|
|
|
|
#include "webrtc/base/sigslot.h"
|
|
|
|
|
#include "webrtc/base/sslfingerprint.h"
|
2015-09-23 11:50:27 -07:00
|
|
|
#include "webrtc/base/thread.h"
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2016-08-05 11:14:50 -07:00
|
|
|
#ifdef HAVE_QUIC
|
|
|
|
|
#include "webrtc/p2p/quic/quictransport.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2014-10-28 22:20:11 +00:00
|
|
|
namespace cricket {
|
|
|
|
|
|
|
|
|
|
class FakeTransport;
|
|
|
|
|
|
2015-10-15 07:26:07 -07:00
|
|
|
namespace {
|
2014-10-28 22:20:11 +00:00
|
|
|
struct PacketMessageData : public rtc::MessageData {
|
2015-09-23 11:50:27 -07:00
|
|
|
PacketMessageData(const char* data, size_t len) : packet(data, len) {}
|
2014-10-28 22:20:11 +00:00
|
|
|
rtc::Buffer packet;
|
|
|
|
|
};
|
2015-10-15 07:26:07 -07:00
|
|
|
} // namespace
|
2014-10-28 22:20:11 +00:00
|
|
|
|
|
|
|
|
// Fake transport channel class, which can be passed to anything that needs a
|
|
|
|
|
// transport channel. Can be informed of another FakeTransportChannel via
|
|
|
|
|
// SetDestination.
|
2015-08-27 10:12:24 +02:00
|
|
|
// TODO(hbos): Move implementation to .cc file, this and other classes in file.
|
2014-10-28 22:20:11 +00:00
|
|
|
class FakeTransportChannel : public TransportChannelImpl,
|
|
|
|
|
public rtc::MessageHandler {
|
|
|
|
|
public:
|
2016-02-19 20:43:45 -08:00
|
|
|
explicit FakeTransportChannel(const std::string& name, int component)
|
2015-09-23 11:50:27 -07:00
|
|
|
: TransportChannelImpl(name, component),
|
|
|
|
|
dtls_fingerprint_("", nullptr, 0) {}
|
|
|
|
|
~FakeTransportChannel() { Reset(); }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
uint64_t IceTiebreaker() const { return tiebreaker_; }
|
2014-10-28 22:20:11 +00:00
|
|
|
IceMode remote_ice_mode() const { return remote_ice_mode_; }
|
|
|
|
|
const std::string& ice_ufrag() const { return ice_ufrag_; }
|
|
|
|
|
const std::string& ice_pwd() const { return ice_pwd_; }
|
|
|
|
|
const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
|
|
|
|
|
const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
|
|
|
|
|
const rtc::SSLFingerprint& dtls_fingerprint() const {
|
|
|
|
|
return dtls_fingerprint_;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
// If async, will send packets by "Post"-ing to message queue instead of
|
|
|
|
|
// synchronously "Send"-ing.
|
|
|
|
|
void SetAsync(bool async) { async_ = async; }
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
TransportChannelState GetState() const override {
|
2014-12-04 07:56:02 +00:00
|
|
|
if (connection_count_ == 0) {
|
2015-09-23 11:50:27 -07:00
|
|
|
return had_connection_ ? TransportChannelState::STATE_FAILED
|
|
|
|
|
: TransportChannelState::STATE_INIT;
|
2014-12-04 07:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (connection_count_ == 1) {
|
|
|
|
|
return TransportChannelState::STATE_COMPLETED;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
return TransportChannelState::STATE_CONNECTING;
|
2014-12-04 07:56:02 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
void SetIceRole(IceRole role) override { role_ = role; }
|
|
|
|
|
IceRole GetIceRole() const override { return role_; }
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
void SetIceTiebreaker(uint64_t tiebreaker) override {
|
2015-09-08 12:11:54 +02:00
|
|
|
tiebreaker_ = tiebreaker;
|
|
|
|
|
}
|
2016-08-31 08:18:11 -07:00
|
|
|
void SetIceParameters(const IceParameters& ice_params) override {
|
|
|
|
|
ice_ufrag_ = ice_params.ufrag;
|
|
|
|
|
ice_pwd_ = ice_params.pwd;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-08-31 08:18:11 -07:00
|
|
|
void SetRemoteIceParameters(const IceParameters& params) override {
|
|
|
|
|
remote_ice_ufrag_ = params.ufrag;
|
|
|
|
|
remote_ice_pwd_ = params.pwd;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
|
2015-09-23 11:50:27 -07:00
|
|
|
bool SetRemoteFingerprint(const std::string& alg,
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
const uint8_t* digest,
|
2015-09-08 12:11:54 +02:00
|
|
|
size_t digest_len) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2015-09-08 12:11:54 +02:00
|
|
|
bool SetSslRole(rtc::SSLRole role) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
ssl_role_ = role;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2015-09-08 12:11:54 +02:00
|
|
|
bool GetSslRole(rtc::SSLRole* role) const override {
|
2014-10-28 22:20:11 +00:00
|
|
|
*role = ssl_role_;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void MaybeStartGathering() override {
|
|
|
|
|
if (gathering_state_ == kIceGatheringNew) {
|
|
|
|
|
gathering_state_ = kIceGatheringGathering;
|
|
|
|
|
SignalGatheringState(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IceGatheringState gathering_state() const override {
|
|
|
|
|
return gathering_state_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Reset() {
|
2014-10-28 22:20:11 +00:00
|
|
|
if (state_ != STATE_INIT) {
|
|
|
|
|
state_ = STATE_INIT;
|
|
|
|
|
if (dest_) {
|
|
|
|
|
dest_->state_ = STATE_INIT;
|
2015-09-23 11:50:27 -07:00
|
|
|
dest_->dest_ = nullptr;
|
|
|
|
|
dest_ = nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void SetWritable(bool writable) { set_writable(writable); }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2016-05-04 17:16:34 -07:00
|
|
|
// Simulates the two transport channels connecting to each other.
|
|
|
|
|
// If |asymmetric| is true this method only affects this FakeTransportChannel.
|
|
|
|
|
// If false, it affects |dest| as well.
|
|
|
|
|
void SetDestination(FakeTransportChannel* dest, bool asymmetric = false) {
|
2016-06-29 13:07:16 -07:00
|
|
|
if (state_ == STATE_INIT && dest) {
|
2014-10-28 22:20:11 +00:00
|
|
|
// This simulates the delivery of candidates.
|
|
|
|
|
dest_ = dest;
|
2015-09-23 11:50:27 -07:00
|
|
|
if (local_cert_ && dest_->local_cert_) {
|
2014-10-28 22:20:11 +00:00
|
|
|
do_dtls_ = true;
|
|
|
|
|
NegotiateSrtpCiphers();
|
|
|
|
|
}
|
|
|
|
|
state_ = STATE_CONNECTED;
|
|
|
|
|
set_writable(true);
|
2016-05-04 17:16:34 -07:00
|
|
|
if (!asymmetric) {
|
|
|
|
|
dest->SetDestination(this, true);
|
|
|
|
|
}
|
2014-10-28 22:20:11 +00:00
|
|
|
} else if (state_ == STATE_CONNECTED && !dest) {
|
|
|
|
|
// Simulates loss of connectivity, by asymmetrically forgetting dest_.
|
2015-09-23 11:50:27 -07:00
|
|
|
dest_ = nullptr;
|
2016-06-29 13:07:16 -07:00
|
|
|
state_ = STATE_INIT;
|
2014-10-28 22:20:11 +00:00
|
|
|
set_writable(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetConnectionCount(size_t connection_count) {
|
|
|
|
|
size_t old_connection_count = connection_count_;
|
|
|
|
|
connection_count_ = connection_count;
|
2015-09-23 11:50:27 -07:00
|
|
|
if (connection_count)
|
|
|
|
|
had_connection_ = true;
|
2016-05-24 13:15:02 -07:00
|
|
|
// In this fake transport channel, |connection_count_| determines the
|
|
|
|
|
// transport channel state.
|
2014-10-28 22:20:11 +00:00
|
|
|
if (connection_count_ < old_connection_count)
|
2016-05-24 13:15:02 -07:00
|
|
|
SignalStateChanged(this);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void SetCandidatesGatheringComplete() {
|
|
|
|
|
if (gathering_state_ != kIceGatheringComplete) {
|
|
|
|
|
gathering_state_ = kIceGatheringComplete;
|
|
|
|
|
SignalGatheringState(this);
|
|
|
|
|
}
|
2015-07-08 11:08:35 -07:00
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void SetReceiving(bool receiving) { set_receiving(receiving); }
|
|
|
|
|
|
2016-07-01 13:59:29 -07:00
|
|
|
void SetIceConfig(const IceConfig& config) override { ice_config_ = config; }
|
2015-07-13 12:19:33 -07:00
|
|
|
|
2016-07-01 13:59:29 -07:00
|
|
|
int receiving_timeout() const { return ice_config_.receiving_timeout; }
|
|
|
|
|
bool gather_continually() const { return ice_config_.gather_continually(); }
|
2015-09-23 11:50:27 -07:00
|
|
|
|
|
|
|
|
int SendPacket(const char* data,
|
|
|
|
|
size_t len,
|
|
|
|
|
const rtc::PacketOptions& options,
|
|
|
|
|
int flags) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
if (state_ != STATE_CONNECTED) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags != PF_SRTP_BYPASS && flags != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PacketMessageData* packet = new PacketMessageData(data, len);
|
|
|
|
|
if (async_) {
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
if (async_delay_ms_) {
|
|
|
|
|
rtc::Thread::Current()->PostDelayed(RTC_FROM_HERE, async_delay_ms_,
|
|
|
|
|
this, 0, packet);
|
|
|
|
|
} else {
|
|
|
|
|
rtc::Thread::Current()->Post(RTC_FROM_HERE, this, 0, packet);
|
|
|
|
|
}
|
2014-10-28 22:20:11 +00:00
|
|
|
} else {
|
2016-06-10 14:17:27 -07:00
|
|
|
rtc::Thread::Current()->Send(RTC_FROM_HERE, this, 0, packet);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-05-02 08:18:55 -07:00
|
|
|
rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
|
2015-10-15 07:26:07 -07:00
|
|
|
SignalSentPacket(this, sent_packet);
|
2014-10-28 22:20:11 +00:00
|
|
|
return static_cast<int>(len);
|
|
|
|
|
}
|
2015-09-23 11:50:27 -07:00
|
|
|
int SetOption(rtc::Socket::Option opt, int value) override { return true; }
|
|
|
|
|
bool GetOption(rtc::Socket::Option opt, int* value) override { return true; }
|
|
|
|
|
int GetError() override { return 0; }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void AddRemoteCandidate(const Candidate& candidate) override {
|
|
|
|
|
remote_candidates_.push_back(candidate);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-03-14 11:59:18 -07:00
|
|
|
|
|
|
|
|
void RemoveRemoteCandidate(const Candidate& candidate) override {}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
const Candidates& remote_candidates() const { return remote_candidates_; }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
void OnMessage(rtc::Message* msg) override {
|
2015-09-23 11:50:27 -07:00
|
|
|
PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata);
|
rtc::Buffer improvements
1. Constructors, SetData(), and AppendData() now accept uint8_t*,
int8_t*, and char*. Previously, they accepted void*, meaning that
any kind of pointer was accepted. I think requiring an explicit
cast in cases where the input array isn't already of a byte-sized
type is a better compromise between convenience and safety.
2. data() can now return a uint8_t* instead of a char*, which seems
more appropriate for a byte array, and is harder to mix up with
zero-terminated C strings. data<int8_t>() is also available so
that callers that want that type instead won't have to cast, as
is data<char>() (which remains the default until all existing
callers have been fixed).
3. Constructors, SetData(), and AppendData() now accept arrays
natively, not just decayed to pointers. The advantage of this is
that callers don't have to pass the size separately.
4. There are new constructors that allow setting size and capacity
without initializing the array. Previously, this had to be done
separately after construction.
5. Instead of TransferTo(), Buffer now supports swap(), and move
construction and assignment, and has a Pass() method that works
just like std::move(). (The Pass method is modeled after
scoped_ptr::Pass().)
R=jmarusic@webrtc.org, tommi@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/42989004
Cr-Commit-Position: refs/heads/master@{#9033}
2015-04-20 14:03:07 +02:00
|
|
|
dest_->SignalReadPacket(dest_, data->packet.data<char>(),
|
|
|
|
|
data->packet.size(), rtc::CreatePacketTime(0), 0);
|
2014-10-28 22:20:11 +00:00
|
|
|
delete data;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
bool SetLocalCertificate(
|
2016-04-29 06:09:15 -07:00
|
|
|
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
|
2015-09-23 11:50:27 -07:00
|
|
|
local_cert_ = certificate;
|
2014-10-28 22:20:11 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
|
2014-10-28 22:20:11 +00:00
|
|
|
remote_cert_ = cert;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
bool IsDtlsActive() const override { return do_dtls_; }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
srtp_ciphers_ = ciphers;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
bool GetSrtpCryptoSuite(int* crypto_suite) override {
|
|
|
|
|
if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
|
|
|
|
|
*crypto_suite = chosen_crypto_suite_;
|
2014-10-28 22:20:11 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
bool GetSslCipherSuite(int* cipher_suite) override { return false; }
|
2015-02-11 22:34:36 +00:00
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
|
2015-09-23 11:50:27 -07:00
|
|
|
return local_cert_;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-26 03:13:22 -07:00
|
|
|
std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
|
2016-04-06 05:15:06 -07:00
|
|
|
const override {
|
2016-04-26 03:13:22 -07:00
|
|
|
return remote_cert_ ? std::unique_ptr<rtc::SSLCertificate>(
|
2016-04-06 05:15:06 -07:00
|
|
|
remote_cert_->GetReference())
|
|
|
|
|
: nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
bool ExportKeyingMaterial(const std::string& label,
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
const uint8_t* context,
|
2015-09-08 12:11:54 +02:00
|
|
|
size_t context_len,
|
|
|
|
|
bool use_context,
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
uint8_t* result,
|
2015-09-08 12:11:54 +02:00
|
|
|
size_t result_len) override {
|
2015-11-18 19:41:53 -08:00
|
|
|
if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
|
2014-10-28 22:20:11 +00:00
|
|
|
memset(result, 0xff, result_len);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
bool GetStats(ConnectionInfos* infos) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
ConnectionInfo info;
|
|
|
|
|
infos->clear();
|
|
|
|
|
infos->push_back(info);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
|
|
|
|
|
ssl_max_version_ = version;
|
|
|
|
|
}
|
|
|
|
|
rtc::SSLProtocolVersion ssl_max_protocol_version() const {
|
|
|
|
|
return ssl_max_version_;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-05 11:47:22 -07:00
|
|
|
void SetMetricsObserver(webrtc::MetricsObserverInterface* observer) override {
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-28 22:20:11 +00:00
|
|
|
private:
|
2016-05-04 17:16:34 -07:00
|
|
|
void NegotiateSrtpCiphers() {
|
|
|
|
|
for (std::vector<int>::const_iterator it1 = srtp_ciphers_.begin();
|
|
|
|
|
it1 != srtp_ciphers_.end(); ++it1) {
|
|
|
|
|
for (std::vector<int>::const_iterator it2 = dest_->srtp_ciphers_.begin();
|
|
|
|
|
it2 != dest_->srtp_ciphers_.end(); ++it2) {
|
|
|
|
|
if (*it1 == *it2) {
|
|
|
|
|
chosen_crypto_suite_ = *it1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-29 13:07:16 -07:00
|
|
|
enum State { STATE_INIT, STATE_CONNECTED };
|
2015-09-23 11:50:27 -07:00
|
|
|
FakeTransportChannel* dest_ = nullptr;
|
|
|
|
|
State state_ = STATE_INIT;
|
|
|
|
|
bool async_ = false;
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
int async_delay_ms_ = 0;
|
2015-09-23 11:50:27 -07:00
|
|
|
Candidates remote_candidates_;
|
|
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
|
|
|
|
|
rtc::FakeSSLCertificate* remote_cert_ = nullptr;
|
|
|
|
|
bool do_dtls_ = false;
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> srtp_ciphers_;
|
|
|
|
|
int chosen_crypto_suite_ = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
2016-07-01 13:59:29 -07:00
|
|
|
IceConfig ice_config_;
|
2015-09-23 11:50:27 -07:00
|
|
|
IceRole role_ = ICEROLE_UNKNOWN;
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
uint64_t tiebreaker_ = 0;
|
2014-10-28 22:20:11 +00:00
|
|
|
std::string ice_ufrag_;
|
|
|
|
|
std::string ice_pwd_;
|
|
|
|
|
std::string remote_ice_ufrag_;
|
|
|
|
|
std::string remote_ice_pwd_;
|
2015-09-23 11:50:27 -07:00
|
|
|
IceMode remote_ice_mode_ = ICEMODE_FULL;
|
2016-01-11 15:27:03 -08:00
|
|
|
rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
|
2014-10-28 22:20:11 +00:00
|
|
|
rtc::SSLFingerprint dtls_fingerprint_;
|
2015-09-23 11:50:27 -07:00
|
|
|
rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
|
|
|
|
|
size_t connection_count_ = 0;
|
|
|
|
|
IceGatheringState gathering_state_ = kIceGatheringNew;
|
|
|
|
|
bool had_connection_ = false;
|
2014-10-28 22:20:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Fake transport class, which can be passed to anything that needs a Transport.
|
|
|
|
|
// Can be informed of another FakeTransport via SetDestination (low-tech way
|
|
|
|
|
// of doing candidates)
|
|
|
|
|
class FakeTransport : public Transport {
|
|
|
|
|
public:
|
|
|
|
|
typedef std::map<int, FakeTransportChannel*> ChannelMap;
|
2015-09-23 11:50:27 -07:00
|
|
|
|
|
|
|
|
explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {}
|
|
|
|
|
|
|
|
|
|
// Note that we only have a constructor with the allocator parameter so it can
|
|
|
|
|
// be wrapped by a DtlsTransport.
|
|
|
|
|
FakeTransport(const std::string& name, PortAllocator* allocator)
|
|
|
|
|
: Transport(name, nullptr) {}
|
|
|
|
|
|
|
|
|
|
~FakeTransport() { DestroyAllChannels(); }
|
2014-10-28 22:20:11 +00:00
|
|
|
|
|
|
|
|
const ChannelMap& channels() const { return channels_; }
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
// If async, will send packets by "Post"-ing to message queue instead of
|
|
|
|
|
// synchronously "Send"-ing.
|
2014-10-28 22:20:11 +00:00
|
|
|
void SetAsync(bool async) { async_ = async; }
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
|
2016-05-04 17:16:34 -07:00
|
|
|
|
|
|
|
|
// If |asymmetric| is true, only set the destination for this transport, and
|
|
|
|
|
// not |dest|.
|
|
|
|
|
void SetDestination(FakeTransport* dest, bool asymmetric = false) {
|
2014-10-28 22:20:11 +00:00
|
|
|
dest_ = dest;
|
2015-09-23 11:50:27 -07:00
|
|
|
for (const auto& kv : channels_) {
|
|
|
|
|
kv.second->SetLocalCertificate(certificate_);
|
2016-05-04 17:16:34 -07:00
|
|
|
SetChannelDestination(kv.first, kv.second, asymmetric);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetWritable(bool writable) {
|
2015-09-23 11:50:27 -07:00
|
|
|
for (const auto& kv : channels_) {
|
|
|
|
|
kv.second->SetWritable(writable);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void SetLocalCertificate(
|
|
|
|
|
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
|
2015-08-27 10:12:24 +02:00
|
|
|
certificate_ = certificate;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2015-09-23 11:50:27 -07:00
|
|
|
bool GetLocalCertificate(
|
|
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
|
|
|
|
|
if (!certificate_)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
*certificate = certificate_;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetSslRole(rtc::SSLRole* role) const override {
|
|
|
|
|
if (channels_.empty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return channels_.begin()->second->GetSslRole(role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override {
|
|
|
|
|
ssl_max_version_ = version;
|
|
|
|
|
for (const auto& kv : channels_) {
|
|
|
|
|
kv.second->set_ssl_max_protocol_version(ssl_max_version_);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
rtc::SSLProtocolVersion ssl_max_protocol_version() const {
|
|
|
|
|
return ssl_max_version_;
|
|
|
|
|
}
|
2014-10-28 22:20:11 +00:00
|
|
|
|
|
|
|
|
using Transport::local_description;
|
|
|
|
|
using Transport::remote_description;
|
2016-04-29 20:20:54 -07:00
|
|
|
using Transport::VerifyCertificateFingerprint;
|
|
|
|
|
using Transport::NegotiateRole;
|
2014-10-28 22:20:11 +00:00
|
|
|
|
|
|
|
|
protected:
|
2015-09-08 12:11:54 +02:00
|
|
|
TransportChannelImpl* CreateTransportChannel(int component) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
if (channels_.find(component) != channels_.end()) {
|
2015-09-23 11:50:27 -07:00
|
|
|
return nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-02-19 20:43:45 -08:00
|
|
|
FakeTransportChannel* channel = new FakeTransportChannel(name(), component);
|
2015-09-23 11:50:27 -07:00
|
|
|
channel->set_ssl_max_protocol_version(ssl_max_version_);
|
2014-10-28 22:20:11 +00:00
|
|
|
channel->SetAsync(async_);
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
channel->SetAsyncDelay(async_delay_ms_);
|
2016-05-04 17:16:34 -07:00
|
|
|
SetChannelDestination(component, channel, false);
|
2014-10-28 22:20:11 +00:00
|
|
|
channels_[component] = channel;
|
|
|
|
|
return channel;
|
|
|
|
|
}
|
2015-09-23 11:50:27 -07:00
|
|
|
|
2015-09-08 12:11:54 +02:00
|
|
|
void DestroyTransportChannel(TransportChannelImpl* channel) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
channels_.erase(channel->component());
|
|
|
|
|
delete channel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
FakeTransportChannel* GetFakeChannel(int component) {
|
2015-09-23 11:50:27 -07:00
|
|
|
auto it = channels_.find(component);
|
|
|
|
|
return (it != channels_.end()) ? it->second : nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2015-09-23 11:50:27 -07:00
|
|
|
|
2016-05-04 17:16:34 -07:00
|
|
|
void SetChannelDestination(int component,
|
|
|
|
|
FakeTransportChannel* channel,
|
|
|
|
|
bool asymmetric) {
|
2015-09-23 11:50:27 -07:00
|
|
|
FakeTransportChannel* dest_channel = nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
if (dest_) {
|
|
|
|
|
dest_channel = dest_->GetFakeChannel(component);
|
2016-05-04 17:16:34 -07:00
|
|
|
if (dest_channel && !asymmetric) {
|
2015-09-08 12:11:54 +02:00
|
|
|
dest_channel->SetLocalCertificate(dest_->certificate_);
|
2015-09-23 11:50:27 -07:00
|
|
|
}
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-05-04 17:16:34 -07:00
|
|
|
channel->SetDestination(dest_channel, asymmetric);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note, this is distinct from the Channel map owned by Transport.
|
|
|
|
|
// This map just tracks the FakeTransportChannels created by this class.
|
2015-09-23 11:50:27 -07:00
|
|
|
// It's mainly needed so that we can access a FakeTransportChannel directly,
|
|
|
|
|
// even if wrapped by a DtlsTransportChannelWrapper.
|
2014-10-28 22:20:11 +00:00
|
|
|
ChannelMap channels_;
|
2015-09-23 11:50:27 -07:00
|
|
|
FakeTransport* dest_ = nullptr;
|
|
|
|
|
bool async_ = false;
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
int async_delay_ms_ = 0;
|
2015-08-27 10:12:24 +02:00
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
|
2016-01-11 15:27:03 -08:00
|
|
|
rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
|
2014-10-28 22:20:11 +00:00
|
|
|
};
|
|
|
|
|
|
2016-08-05 11:14:50 -07:00
|
|
|
#ifdef HAVE_QUIC
|
|
|
|
|
class FakeQuicTransport : public QuicTransport {
|
|
|
|
|
public:
|
|
|
|
|
FakeQuicTransport(const std::string& transport_name)
|
|
|
|
|
: QuicTransport(transport_name, nullptr, nullptr) {}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
QuicTransportChannel* CreateTransportChannel(int component) override {
|
|
|
|
|
FakeTransportChannel* fake_ice_transport_channel =
|
|
|
|
|
new FakeTransportChannel(name(), component);
|
|
|
|
|
return new QuicTransportChannel(fake_ice_transport_channel);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-03-29 17:27:21 -07:00
|
|
|
// Fake candidate pair class, which can be passed to BaseChannel for testing
|
|
|
|
|
// purposes.
|
|
|
|
|
class FakeCandidatePair : public CandidatePairInterface {
|
|
|
|
|
public:
|
|
|
|
|
FakeCandidatePair(const Candidate& local_candidate,
|
|
|
|
|
const Candidate& remote_candidate)
|
|
|
|
|
: local_candidate_(local_candidate),
|
|
|
|
|
remote_candidate_(remote_candidate) {}
|
|
|
|
|
const Candidate& local_candidate() const override { return local_candidate_; }
|
|
|
|
|
const Candidate& remote_candidate() const override {
|
|
|
|
|
return remote_candidate_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Candidate local_candidate_;
|
|
|
|
|
Candidate remote_candidate_;
|
|
|
|
|
};
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
// Fake TransportController class, which can be passed into a BaseChannel object
|
|
|
|
|
// for test purposes. Can be connected to other FakeTransportControllers via
|
|
|
|
|
// Connect().
|
|
|
|
|
//
|
|
|
|
|
// This fake is unusual in that for the most part, it's implemented with the
|
|
|
|
|
// real TransportController code, but with fake TransportChannels underneath.
|
|
|
|
|
class FakeTransportController : public TransportController {
|
2014-10-28 22:20:11 +00:00
|
|
|
public:
|
2015-09-23 11:50:27 -07:00
|
|
|
FakeTransportController()
|
|
|
|
|
: TransportController(rtc::Thread::Current(),
|
|
|
|
|
rtc::Thread::Current(),
|
|
|
|
|
nullptr),
|
|
|
|
|
fail_create_channel_(false) {}
|
|
|
|
|
|
2016-08-26 20:59:24 -07:00
|
|
|
explicit FakeTransportController(bool redetermine_role_on_ice_restart)
|
|
|
|
|
: TransportController(rtc::Thread::Current(),
|
|
|
|
|
rtc::Thread::Current(),
|
|
|
|
|
nullptr,
|
|
|
|
|
redetermine_role_on_ice_restart),
|
|
|
|
|
fail_create_channel_(false) {}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
explicit FakeTransportController(IceRole role)
|
|
|
|
|
: TransportController(rtc::Thread::Current(),
|
|
|
|
|
rtc::Thread::Current(),
|
|
|
|
|
nullptr),
|
|
|
|
|
fail_create_channel_(false) {
|
|
|
|
|
SetIceRole(role);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 00:54:57 -07:00
|
|
|
explicit FakeTransportController(rtc::Thread* network_thread)
|
|
|
|
|
: TransportController(rtc::Thread::Current(), network_thread, nullptr),
|
2015-09-23 11:50:27 -07:00
|
|
|
fail_create_channel_(false) {}
|
|
|
|
|
|
2016-10-17 00:54:57 -07:00
|
|
|
FakeTransportController(rtc::Thread* network_thread, IceRole role)
|
|
|
|
|
: TransportController(rtc::Thread::Current(), network_thread, nullptr),
|
2015-09-23 11:50:27 -07:00
|
|
|
fail_create_channel_(false) {
|
|
|
|
|
SetIceRole(role);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-12 09:20:31 +02:00
|
|
|
FakeTransport* GetTransport_n(const std::string& transport_name) {
|
2014-10-28 22:20:11 +00:00
|
|
|
return static_cast<FakeTransport*>(
|
2016-05-12 09:20:31 +02:00
|
|
|
TransportController::GetTransport_n(transport_name));
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
void Connect(FakeTransportController* dest) {
|
2016-05-12 09:20:31 +02:00
|
|
|
network_thread()->Invoke<void>(
|
2016-06-10 14:17:27 -07:00
|
|
|
RTC_FROM_HERE,
|
2016-05-12 09:20:31 +02:00
|
|
|
rtc::Bind(&FakeTransportController::Connect_n, this, dest));
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-05-12 09:20:31 +02:00
|
|
|
TransportChannel* CreateTransportChannel_n(const std::string& transport_name,
|
2015-09-23 11:50:27 -07:00
|
|
|
int component) override {
|
2014-10-28 22:20:11 +00:00
|
|
|
if (fail_create_channel_) {
|
2015-09-23 11:50:27 -07:00
|
|
|
return nullptr;
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
2016-05-12 09:20:31 +02:00
|
|
|
return TransportController::CreateTransportChannel_n(transport_name,
|
2015-09-23 11:50:27 -07:00
|
|
|
component);
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-29 17:27:21 -07:00
|
|
|
FakeCandidatePair* CreateFakeCandidatePair(
|
|
|
|
|
const rtc::SocketAddress& local_address,
|
|
|
|
|
int16_t local_network_id,
|
|
|
|
|
const rtc::SocketAddress& remote_address,
|
|
|
|
|
int16_t remote_network_id) {
|
|
|
|
|
Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0,
|
|
|
|
|
"foundation", local_network_id, 0);
|
|
|
|
|
Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0,
|
|
|
|
|
"foundation", remote_network_id, 0);
|
|
|
|
|
return new FakeCandidatePair(local_candidate, remote_candidate);
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-28 22:20:11 +00:00
|
|
|
void set_fail_channel_creation(bool fail_channel_creation) {
|
|
|
|
|
fail_create_channel_ = fail_channel_creation;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
protected:
|
2016-05-12 09:20:31 +02:00
|
|
|
Transport* CreateTransport_n(const std::string& transport_name) override {
|
2016-08-05 11:14:50 -07:00
|
|
|
#ifdef HAVE_QUIC
|
|
|
|
|
if (quic()) {
|
|
|
|
|
return new FakeQuicTransport(transport_name);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2015-09-23 11:50:27 -07:00
|
|
|
return new FakeTransport(transport_name);
|
2015-09-18 13:50:22 -07:00
|
|
|
}
|
|
|
|
|
|
2016-05-12 09:20:31 +02:00
|
|
|
void Connect_n(FakeTransportController* dest) {
|
2015-09-23 11:50:27 -07:00
|
|
|
// Simulate the exchange of candidates.
|
2016-05-12 09:20:31 +02:00
|
|
|
ConnectChannels_n();
|
|
|
|
|
dest->ConnectChannels_n();
|
2015-09-23 11:50:27 -07:00
|
|
|
for (auto& kv : transports()) {
|
|
|
|
|
FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
|
2016-05-12 09:20:31 +02:00
|
|
|
transport->SetDestination(dest->GetTransport_n(kv.first));
|
2015-09-23 11:50:27 -07:00
|
|
|
}
|
2015-09-23 02:16:58 -07:00
|
|
|
}
|
|
|
|
|
|
2016-05-12 09:20:31 +02:00
|
|
|
void ConnectChannels_n() {
|
2016-04-11 15:10:52 -07:00
|
|
|
TransportDescription faketransport_desc(
|
|
|
|
|
std::vector<std::string>(),
|
|
|
|
|
rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
|
|
|
|
|
rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), cricket::ICEMODE_FULL,
|
|
|
|
|
cricket::CONNECTIONROLE_NONE, nullptr);
|
2015-09-23 11:50:27 -07:00
|
|
|
for (auto& kv : transports()) {
|
|
|
|
|
FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
|
2016-04-11 15:10:52 -07:00
|
|
|
// Set local transport description for FakeTransport before connecting.
|
|
|
|
|
// Otherwise, the RTC_CHECK in Transport.ConnectChannel will fail.
|
|
|
|
|
if (!transport->local_description()) {
|
|
|
|
|
transport->SetLocalTransportDescription(faketransport_desc,
|
|
|
|
|
cricket::CA_OFFER, nullptr);
|
|
|
|
|
}
|
2015-09-23 11:50:27 -07:00
|
|
|
transport->MaybeStartGathering();
|
2014-10-28 22:20:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool fail_create_channel_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace cricket
|
|
|
|
|
|
2015-09-23 11:50:27 -07:00
|
|
|
#endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
|