Reland "Move JsepTransport from p2p/base to pc/."
This is a reland of 4770fd935ac92400487bddd3b755753572e6d692 Original change's description: > Move JsepTransport from p2p/base to pc/. > > The JsepTransport class is moved to pc/ and the utility methods and > enums are moved to where they are used. > > With JsepTransport moved to pc/, JsepTransport can depend on objects in > pc/ including RtpTranport, SrtpTransport etc. > > Forked from https://webrtc-review.googlesource.com/c/src/+/31762/7 > > Bug: webrtc:8636 > Change-Id: I4e8569fe3012946e87deb280f6139f0fd98de34d > Reviewed-on: https://webrtc-review.googlesource.com/33701 > Reviewed-by: Steve Anton <steveanton@webrtc.org> > Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> > Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#21333} Bug: webrtc:8636 Change-Id: Ibce42be898b96dd8e0266b595611d2ffc86581a8 Reviewed-on: https://webrtc-review.googlesource.com/34586 Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Peter Thatcher <pthatcher@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21371}
This commit is contained in:
parent
c1ccf95687
commit
6e2e7ce419
@ -33,7 +33,6 @@ rtc_static_library("rtc_p2p") {
|
||||
"base/dtlstransportinternal.h",
|
||||
"base/icetransportinternal.cc",
|
||||
"base/icetransportinternal.h",
|
||||
"base/jseptransport.cc",
|
||||
"base/jseptransport.h",
|
||||
"base/p2pconstants.cc",
|
||||
"base/p2pconstants.h",
|
||||
@ -156,7 +155,6 @@ if (rtc_include_tests) {
|
||||
sources = [
|
||||
"base/asyncstuntcpsocket_unittest.cc",
|
||||
"base/dtlstransport_unittest.cc",
|
||||
"base/jseptransport_unittest.cc",
|
||||
"base/p2ptransportchannel_unittest.cc",
|
||||
"base/packetlossestimator_unittest.cc",
|
||||
"base/port_unittest.cc",
|
||||
|
||||
@ -16,13 +16,25 @@
|
||||
#include <vector>
|
||||
|
||||
#include "p2p/base/icetransportinternal.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/packettransportinternal.h"
|
||||
#include "rtc_base/sslstreamadapter.h"
|
||||
#include "rtc_base/stringencode.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
enum DtlsTransportState {
|
||||
// Haven't started negotiating.
|
||||
DTLS_TRANSPORT_NEW = 0,
|
||||
// Have started negotiating.
|
||||
DTLS_TRANSPORT_CONNECTING,
|
||||
// Negotiated, and has a secure connection.
|
||||
DTLS_TRANSPORT_CONNECTED,
|
||||
// Transport is closed.
|
||||
DTLS_TRANSPORT_CLOSED,
|
||||
// Failed due to some error in the handshake process.
|
||||
DTLS_TRANSPORT_FAILED,
|
||||
};
|
||||
|
||||
enum PacketFlags {
|
||||
PF_NORMAL = 0x00, // A normal packet.
|
||||
PF_SRTP_BYPASS = 0x01, // An encrypted SRTP packet; bypass any additional
|
||||
|
||||
@ -12,6 +12,30 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
IceConfig::IceConfig() = default;
|
||||
|
||||
IceConfig::IceConfig(int receiving_timeout_ms,
|
||||
int backup_connection_ping_interval,
|
||||
ContinualGatheringPolicy gathering_policy,
|
||||
bool prioritize_most_likely_candidate_pairs,
|
||||
int stable_writable_connection_ping_interval_ms,
|
||||
bool presume_writable_when_fully_relayed,
|
||||
int regather_on_failed_networks_interval_ms,
|
||||
int receiving_switching_delay_ms)
|
||||
: receiving_timeout(receiving_timeout_ms),
|
||||
backup_connection_ping_interval(backup_connection_ping_interval),
|
||||
continual_gathering_policy(gathering_policy),
|
||||
prioritize_most_likely_candidate_pairs(
|
||||
prioritize_most_likely_candidate_pairs),
|
||||
stable_writable_connection_ping_interval(
|
||||
stable_writable_connection_ping_interval_ms),
|
||||
presume_writable_when_fully_relayed(presume_writable_when_fully_relayed),
|
||||
regather_on_failed_networks_interval(
|
||||
regather_on_failed_networks_interval_ms),
|
||||
receiving_switching_delay(receiving_switching_delay_ms) {}
|
||||
|
||||
IceConfig::~IceConfig() = default;
|
||||
|
||||
IceTransportInternal::IceTransportInternal() = default;
|
||||
|
||||
IceTransportInternal::~IceTransportInternal() = default;
|
||||
|
||||
@ -12,11 +12,12 @@
|
||||
#define P2P_BASE_ICETRANSPORTINTERNAL_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/candidate.h"
|
||||
#include "p2p/base/candidatepairinterface.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/packettransportinternal.h"
|
||||
#include "p2p/base/port.h"
|
||||
#include "p2p/base/transportdescription.h"
|
||||
#include "rtc_base/stringencode.h"
|
||||
|
||||
@ -26,6 +27,106 @@ class MetricsObserverInterface;
|
||||
|
||||
namespace cricket {
|
||||
|
||||
typedef std::vector<Candidate> Candidates;
|
||||
|
||||
enum IceConnectionState {
|
||||
kIceConnectionConnecting = 0,
|
||||
kIceConnectionFailed,
|
||||
kIceConnectionConnected, // Writable, but still checking one or more
|
||||
// connections
|
||||
kIceConnectionCompleted,
|
||||
};
|
||||
|
||||
// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
|
||||
// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
|
||||
// style.
|
||||
enum IceGatheringState {
|
||||
kIceGatheringNew = 0,
|
||||
kIceGatheringGathering,
|
||||
kIceGatheringComplete,
|
||||
};
|
||||
|
||||
enum ContinualGatheringPolicy {
|
||||
// All port allocator sessions will stop after a writable connection is found.
|
||||
GATHER_ONCE = 0,
|
||||
// The most recent port allocator session will keep on running.
|
||||
GATHER_CONTINUALLY,
|
||||
// The most recent port allocator session will keep on running, and it will
|
||||
// try to recover connectivity if the channel becomes disconnected.
|
||||
GATHER_CONTINUALLY_AND_RECOVER,
|
||||
};
|
||||
|
||||
// ICE Nomination mode.
|
||||
enum class NominationMode {
|
||||
REGULAR, // Nominate once per ICE restart (Not implemented yet).
|
||||
AGGRESSIVE, // Nominate every connection except that it will behave as if
|
||||
// REGULAR when the remote is an ICE-LITE endpoint.
|
||||
SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm.
|
||||
// The details are described in P2PTransportChannel.
|
||||
};
|
||||
|
||||
// Information about ICE configuration.
|
||||
// TODO(deadbeef): Use rtc::Optional to represent unset values, instead of
|
||||
// -1.
|
||||
struct IceConfig {
|
||||
// The ICE connection receiving timeout value in milliseconds.
|
||||
int receiving_timeout = -1;
|
||||
// Time interval in milliseconds to ping a backup connection when the ICE
|
||||
// channel is strongly connected.
|
||||
int backup_connection_ping_interval = -1;
|
||||
|
||||
ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
|
||||
|
||||
bool gather_continually() const {
|
||||
return continual_gathering_policy == GATHER_CONTINUALLY ||
|
||||
continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER;
|
||||
}
|
||||
|
||||
// Whether we should prioritize Relay/Relay candidate when nothing
|
||||
// is writable yet.
|
||||
bool prioritize_most_likely_candidate_pairs = false;
|
||||
|
||||
// Writable connections are pinged at a slower rate once stablized.
|
||||
int stable_writable_connection_ping_interval = -1;
|
||||
|
||||
// If set to true, this means the ICE transport should presume TURN-to-TURN
|
||||
// candidate pairs will succeed, even before a binding response is received.
|
||||
bool presume_writable_when_fully_relayed = false;
|
||||
|
||||
// Interval to check on all networks and to perform ICE regathering on any
|
||||
// active network having no connection on it.
|
||||
rtc::Optional<int> regather_on_failed_networks_interval;
|
||||
|
||||
// Interval to perform ICE regathering on all networks
|
||||
// The delay in milliseconds is sampled from the uniform distribution [a, b]
|
||||
rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
|
||||
|
||||
// The time period in which we will not switch the selected connection
|
||||
// when a new connection becomes receiving but the selected connection is not
|
||||
// in case that the selected connection may become receiving soon.
|
||||
rtc::Optional<int> receiving_switching_delay;
|
||||
|
||||
// TODO(honghaiz): Change the default to regular nomination.
|
||||
// Default nomination mode if the remote does not support renomination.
|
||||
NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
|
||||
|
||||
// ICE checks (STUN pings) will not be sent at higher rate (lower interval)
|
||||
// than this, no matter what other settings there are.
|
||||
// Measure in milliseconds.
|
||||
rtc::Optional<int> ice_check_min_interval;
|
||||
|
||||
IceConfig();
|
||||
IceConfig(int receiving_timeout_ms,
|
||||
int backup_connection_ping_interval,
|
||||
ContinualGatheringPolicy gathering_policy,
|
||||
bool prioritize_most_likely_candidate_pairs,
|
||||
int stable_writable_connection_ping_interval_ms,
|
||||
bool presume_writable_when_fully_relayed,
|
||||
int regather_on_failed_networks_interval_ms,
|
||||
int receiving_switching_delay_ms);
|
||||
~IceConfig();
|
||||
};
|
||||
|
||||
// TODO(zhihuang): Replace this with
|
||||
// PeerConnectionInterface::IceConnectionState.
|
||||
enum class IceTransportState {
|
||||
|
||||
@ -11,373 +11,35 @@
|
||||
#ifndef P2P_BASE_JSEPTRANSPORT_H_
|
||||
#define P2P_BASE_JSEPTRANSPORT_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// TODO(deadbeef): This file used to be a dumping ground of various enums,
|
||||
// structs, etc., which have now moved to their own files. Delete this file
|
||||
// once no one is depending on it, and they start including the more specific
|
||||
// file(s) instead.
|
||||
|
||||
#include "api/candidate.h"
|
||||
#include "api/jsep.h"
|
||||
#include "api/optional.h"
|
||||
|
||||
// DTLS enums/structs.
|
||||
#include "p2p/base/dtlstransport.h"
|
||||
#include "p2p/base/dtlstransportinternal.h"
|
||||
|
||||
// ICE enums/structs.
|
||||
#include "p2p/base/icetransportinternal.h"
|
||||
|
||||
// Various constants.
|
||||
#include "p2p/base/p2pconstants.h"
|
||||
|
||||
// ConnectionInfo, among many other things.
|
||||
#include "p2p/base/port.h"
|
||||
|
||||
// SDP structures
|
||||
#include "p2p/base/sessiondescription.h"
|
||||
#include "p2p/base/transportinfo.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/messagequeue.h"
|
||||
#include "rtc_base/rtccertificate.h"
|
||||
#include "rtc_base/sigslot.h"
|
||||
#include "rtc_base/sslstreamadapter.h"
|
||||
|
||||
// Legacy typedef.
|
||||
namespace cricket {
|
||||
|
||||
class DtlsTransportInternal;
|
||||
enum class IceCandidatePairState;
|
||||
|
||||
typedef std::vector<Candidate> Candidates;
|
||||
|
||||
// TODO(deadbeef): Move all of these enums, POD types and utility methods to
|
||||
// another header file.
|
||||
|
||||
// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
|
||||
// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
|
||||
// style.
|
||||
enum IceConnectionState {
|
||||
kIceConnectionConnecting = 0,
|
||||
kIceConnectionFailed,
|
||||
kIceConnectionConnected, // Writable, but still checking one or more
|
||||
// connections
|
||||
kIceConnectionCompleted,
|
||||
};
|
||||
|
||||
enum DtlsTransportState {
|
||||
// Haven't started negotiating.
|
||||
DTLS_TRANSPORT_NEW = 0,
|
||||
// Have started negotiating.
|
||||
DTLS_TRANSPORT_CONNECTING,
|
||||
// Negotiated, and has a secure connection.
|
||||
DTLS_TRANSPORT_CONNECTED,
|
||||
// Transport is closed.
|
||||
DTLS_TRANSPORT_CLOSED,
|
||||
// Failed due to some error in the handshake process.
|
||||
DTLS_TRANSPORT_FAILED,
|
||||
};
|
||||
|
||||
// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
|
||||
// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
|
||||
// style.
|
||||
enum IceGatheringState {
|
||||
kIceGatheringNew = 0,
|
||||
kIceGatheringGathering,
|
||||
kIceGatheringComplete,
|
||||
};
|
||||
|
||||
enum ContinualGatheringPolicy {
|
||||
// All port allocator sessions will stop after a writable connection is found.
|
||||
GATHER_ONCE = 0,
|
||||
// The most recent port allocator session will keep on running.
|
||||
GATHER_CONTINUALLY,
|
||||
// The most recent port allocator session will keep on running, and it will
|
||||
// try to recover connectivity if the channel becomes disconnected.
|
||||
GATHER_CONTINUALLY_AND_RECOVER,
|
||||
};
|
||||
|
||||
// Stats that we can return about the connections for a transport channel.
|
||||
// TODO(hta): Rename to ConnectionStats
|
||||
struct ConnectionInfo {
|
||||
ConnectionInfo();
|
||||
ConnectionInfo(const ConnectionInfo&);
|
||||
~ConnectionInfo();
|
||||
|
||||
bool best_connection; // Is this the best connection we have?
|
||||
bool writable; // Has this connection received a STUN response?
|
||||
bool receiving; // Has this connection received anything?
|
||||
bool timeout; // Has this connection timed out?
|
||||
bool new_connection; // Is this a newly created connection?
|
||||
size_t rtt; // The STUN RTT for this connection.
|
||||
size_t sent_total_bytes; // Total bytes sent on this connection.
|
||||
size_t sent_bytes_second; // Bps over the last measurement interval.
|
||||
size_t sent_discarded_packets; // Number of outgoing packets discarded due to
|
||||
// socket errors.
|
||||
size_t sent_total_packets; // Number of total outgoing packets attempted for
|
||||
// sending.
|
||||
size_t sent_ping_requests_total; // Number of STUN ping request sent.
|
||||
size_t sent_ping_requests_before_first_response; // Number of STUN ping
|
||||
// sent before receiving the first response.
|
||||
size_t sent_ping_responses; // Number of STUN ping response sent.
|
||||
|
||||
size_t recv_total_bytes; // Total bytes received on this connection.
|
||||
size_t recv_bytes_second; // Bps over the last measurement interval.
|
||||
size_t recv_ping_requests; // Number of STUN ping request received.
|
||||
size_t recv_ping_responses; // Number of STUN ping response received.
|
||||
Candidate local_candidate; // The local candidate for this connection.
|
||||
Candidate remote_candidate; // The remote candidate for this connection.
|
||||
void* key; // A static value that identifies this conn.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
|
||||
IceCandidatePairState state;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
|
||||
uint64_t priority;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-nominated
|
||||
bool nominated;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
|
||||
uint64_t total_round_trip_time_ms;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
|
||||
rtc::Optional<uint32_t> current_round_trip_time_ms;
|
||||
};
|
||||
|
||||
// Information about all the connections of a channel.
|
||||
typedef std::vector<ConnectionInfo> ConnectionInfos;
|
||||
|
||||
// Information about a specific channel
|
||||
struct TransportChannelStats {
|
||||
TransportChannelStats();
|
||||
TransportChannelStats(const TransportChannelStats&);
|
||||
~TransportChannelStats();
|
||||
|
||||
int component = 0;
|
||||
ConnectionInfos connection_infos;
|
||||
int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
||||
int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
|
||||
DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
|
||||
};
|
||||
|
||||
// Information about all the channels of a transport.
|
||||
// TODO(hta): Consider if a simple vector is as good as a map.
|
||||
typedef std::vector<TransportChannelStats> TransportChannelStatsList;
|
||||
|
||||
// Information about the stats of a transport.
|
||||
struct TransportStats {
|
||||
TransportStats();
|
||||
~TransportStats();
|
||||
|
||||
std::string transport_name;
|
||||
TransportChannelStatsList channel_stats;
|
||||
};
|
||||
|
||||
// ICE Nomination mode.
|
||||
enum class NominationMode {
|
||||
REGULAR, // Nominate once per ICE restart (Not implemented yet).
|
||||
AGGRESSIVE, // Nominate every connection except that it will behave as if
|
||||
// REGULAR when the remote is an ICE-LITE endpoint.
|
||||
SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm.
|
||||
// The details are described in P2PTransportChannel.
|
||||
};
|
||||
|
||||
// Information about ICE configuration.
|
||||
// TODO(deadbeef): Use rtc::Optional to represent unset values, instead of
|
||||
// -1.
|
||||
struct IceConfig {
|
||||
// The ICE connection receiving timeout value in milliseconds.
|
||||
int receiving_timeout = -1;
|
||||
// Time interval in milliseconds to ping a backup connection when the ICE
|
||||
// channel is strongly connected.
|
||||
int backup_connection_ping_interval = -1;
|
||||
|
||||
ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
|
||||
|
||||
bool gather_continually() const {
|
||||
return continual_gathering_policy == GATHER_CONTINUALLY ||
|
||||
continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER;
|
||||
}
|
||||
|
||||
// Whether we should prioritize Relay/Relay candidate when nothing
|
||||
// is writable yet.
|
||||
bool prioritize_most_likely_candidate_pairs = false;
|
||||
|
||||
// Writable connections are pinged at a slower rate once stablized.
|
||||
int stable_writable_connection_ping_interval = -1;
|
||||
|
||||
// If set to true, this means the ICE transport should presume TURN-to-TURN
|
||||
// candidate pairs will succeed, even before a binding response is received.
|
||||
bool presume_writable_when_fully_relayed = false;
|
||||
|
||||
// Interval to check on all networks and to perform ICE regathering on any
|
||||
// active network having no connection on it.
|
||||
rtc::Optional<int> regather_on_failed_networks_interval;
|
||||
|
||||
// Interval to perform ICE regathering on all networks
|
||||
// The delay in milliseconds is sampled from the uniform distribution [a, b]
|
||||
rtc::Optional<rtc::IntervalRange> regather_all_networks_interval_range;
|
||||
|
||||
// The time period in which we will not switch the selected connection
|
||||
// when a new connection becomes receiving but the selected connection is not
|
||||
// in case that the selected connection may become receiving soon.
|
||||
rtc::Optional<int> receiving_switching_delay;
|
||||
|
||||
// TODO(honghaiz): Change the default to regular nomination.
|
||||
// Default nomination mode if the remote does not support renomination.
|
||||
NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE;
|
||||
|
||||
// ICE checks (STUN pings) will not be sent at higher rate (lower interval)
|
||||
// than this, no matter what other settings there are.
|
||||
// Measure in milliseconds.
|
||||
rtc::Optional<int> ice_check_min_interval;
|
||||
|
||||
IceConfig();
|
||||
IceConfig(int receiving_timeout_ms,
|
||||
int backup_connection_ping_interval,
|
||||
ContinualGatheringPolicy gathering_policy,
|
||||
bool prioritize_most_likely_candidate_pairs,
|
||||
int stable_writable_connection_ping_interval_ms,
|
||||
bool presume_writable_when_fully_relayed,
|
||||
int regather_on_failed_networks_interval_ms,
|
||||
int receiving_switching_delay_ms);
|
||||
~IceConfig();
|
||||
};
|
||||
|
||||
bool BadTransportDescription(const std::string& desc, std::string* err_desc);
|
||||
|
||||
bool IceCredentialsChanged(const std::string& old_ufrag,
|
||||
const std::string& old_pwd,
|
||||
const std::string& new_ufrag,
|
||||
const std::string& new_pwd);
|
||||
|
||||
// If a candidate is not acceptable, returns false and sets error.
|
||||
bool VerifyCandidate(const Candidate& candidate, std::string* error);
|
||||
bool VerifyCandidates(const Candidates& candidates, std::string* error);
|
||||
|
||||
// Helper class used by TransportController that processes
|
||||
// TransportDescriptions. A TransportDescription represents the
|
||||
// transport-specific properties of an SDP m= section, processed according to
|
||||
// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
|
||||
// (and possibly RTCP, if rtcp-mux isn't used).
|
||||
//
|
||||
// On Threading: Transport performs work solely on the network thread, and so
|
||||
// its methods should only be called on the network thread.
|
||||
//
|
||||
// TODO(deadbeef): Move this into /pc/ and out of /p2p/base/, since it's
|
||||
// PeerConnection-specific.
|
||||
class JsepTransport : public sigslot::has_slots<> {
|
||||
public:
|
||||
// |mid| is just used for log statements in order to identify the Transport.
|
||||
// Note that |certificate| is allowed to be null since a remote description
|
||||
// may be set before a local certificate is generated.
|
||||
JsepTransport(const std::string& mid,
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
|
||||
~JsepTransport() override;
|
||||
|
||||
// Returns the MID of this transport.
|
||||
const std::string& mid() const { return mid_; }
|
||||
|
||||
// Add or remove channel that is affected when a local/remote transport
|
||||
// description is set on this transport. Need to add all channels before
|
||||
// setting a transport description.
|
||||
bool AddChannel(DtlsTransportInternal* dtls, int component);
|
||||
bool RemoveChannel(int component);
|
||||
bool HasChannels() const;
|
||||
|
||||
bool ready_for_remote_candidates() const {
|
||||
return local_description_set_ && remote_description_set_;
|
||||
}
|
||||
|
||||
// Must be called before applying local session description.
|
||||
// Needed in order to verify the local fingerprint.
|
||||
void SetLocalCertificate(
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
|
||||
|
||||
// Get a copy of the local certificate provided by SetLocalCertificate.
|
||||
bool GetLocalCertificate(
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const;
|
||||
|
||||
// Set the local TransportDescription to be used by DTLS and ICE channels
|
||||
// that are part of this Transport.
|
||||
bool SetLocalTransportDescription(const TransportDescription& description,
|
||||
webrtc::SdpType type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Set the remote TransportDescription to be used by DTLS and ICE channels
|
||||
// that are part of this Transport.
|
||||
bool SetRemoteTransportDescription(const TransportDescription& description,
|
||||
webrtc::SdpType type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Set the "needs-ice-restart" flag as described in JSEP. After the flag is
|
||||
// set, offers should generate new ufrags/passwords until an ICE restart
|
||||
// occurs.
|
||||
//
|
||||
// This and the below method can be called safely from any thread as long as
|
||||
// SetXTransportDescription is not in progress.
|
||||
void SetNeedsIceRestartFlag();
|
||||
// Returns true if the ICE restart flag above was set, and no ICE restart has
|
||||
// occurred yet for this transport (by applying a local description with
|
||||
// changed ufrag/password).
|
||||
bool NeedsIceRestart() const;
|
||||
|
||||
// Returns role if negotiated, or empty Optional if it hasn't been negotiated
|
||||
// yet.
|
||||
rtc::Optional<rtc::SSLRole> GetSslRole() const;
|
||||
|
||||
// TODO(deadbeef): Make this const. See comment in transportcontroller.h.
|
||||
bool GetStats(TransportStats* stats);
|
||||
|
||||
// The current local transport description, possibly used
|
||||
// by the transport controller.
|
||||
const TransportDescription* local_description() const {
|
||||
return local_description_.get();
|
||||
}
|
||||
|
||||
// The current remote transport description, possibly used
|
||||
// by the transport controller.
|
||||
const TransportDescription* remote_description() const {
|
||||
return remote_description_.get();
|
||||
}
|
||||
|
||||
// TODO(deadbeef): The methods below are only public for testing. Should make
|
||||
// them utility functions or objects so they can be tested independently from
|
||||
// this class.
|
||||
|
||||
// Returns false if the certificate's identity does not match the fingerprint,
|
||||
// or either is NULL.
|
||||
bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate,
|
||||
const rtc::SSLFingerprint* fingerprint,
|
||||
std::string* error_desc) const;
|
||||
|
||||
private:
|
||||
// Negotiates the transport parameters based on the current local and remote
|
||||
// transport description, such as the ICE role to use, and whether DTLS
|
||||
// should be activated.
|
||||
//
|
||||
// Called when an answer TransportDescription is applied.
|
||||
bool NegotiateTransportDescription(webrtc::SdpType local_description_type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Negotiates the SSL role based off the offer and answer as specified by
|
||||
// RFC 4145, section-4.1. Returns false if the SSL role cannot be determined
|
||||
// from the local description and remote description.
|
||||
bool NegotiateRole(webrtc::SdpType local_description_type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters from the local description, such
|
||||
// as the ICE ufrag and pwd.
|
||||
bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters from the remote description to the
|
||||
// transport channel.
|
||||
bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters obtained via negotiation.
|
||||
bool ApplyNegotiatedTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
const std::string mid_;
|
||||
// needs-ice-restart bit as described in JSEP.
|
||||
bool needs_ice_restart_ = false;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
|
||||
rtc::Optional<rtc::SSLRole> ssl_role_;
|
||||
std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_;
|
||||
std::unique_ptr<TransportDescription> local_description_;
|
||||
std::unique_ptr<TransportDescription> remote_description_;
|
||||
bool local_description_set_ = false;
|
||||
bool remote_description_set_ = false;
|
||||
|
||||
// Candidate component => DTLS channel
|
||||
std::map<int, DtlsTransportInternal*> channels_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
}
|
||||
|
||||
#endif // P2P_BASE_JSEPTRANSPORT_H_
|
||||
|
||||
@ -41,8 +41,6 @@ class MockIceTransport : public IceTransportInternal {
|
||||
MOCK_METHOD0(GetError, int());
|
||||
MOCK_CONST_METHOD0(GetIceRole, cricket::IceRole());
|
||||
MOCK_METHOD1(GetStats, bool(cricket::ConnectionInfos* infos));
|
||||
MOCK_CONST_METHOD0(IsDtlsActive, bool());
|
||||
MOCK_CONST_METHOD1(GetSslRole, bool(rtc::SSLRole* role));
|
||||
|
||||
IceTransportState GetState() const override {
|
||||
return IceTransportState::STATE_INIT;
|
||||
|
||||
@ -101,6 +101,17 @@ static constexpr int DEFAULT_BACKUP_CONNECTION_PING_INTERVAL = 25 * 1000;
|
||||
static constexpr int a_is_better = 1;
|
||||
static constexpr int b_is_better = -1;
|
||||
|
||||
bool IceCredentialsChanged(const std::string& old_ufrag,
|
||||
const std::string& old_pwd,
|
||||
const std::string& new_ufrag,
|
||||
const std::string& new_pwd) {
|
||||
// The standard (RFC 5245 Section 9.1.1.1) says that ICE restarts MUST change
|
||||
// both the ufrag and password. However, section 9.2.1.1 says changing the
|
||||
// ufrag OR password indicates an ICE restart. So, to keep compatibility with
|
||||
// endpoints that only change one, we'll treat this as an ICE restart.
|
||||
return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
|
||||
}
|
||||
|
||||
P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
|
||||
int component,
|
||||
PortAllocator* allocator)
|
||||
|
||||
@ -48,6 +48,11 @@ extern const int WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL;
|
||||
extern const int STRONG_AND_STABLE_WRITABLE_CONNECTION_PING_INTERVAL;
|
||||
static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3;
|
||||
|
||||
bool IceCredentialsChanged(const std::string& old_ufrag,
|
||||
const std::string& old_pwd,
|
||||
const std::string& new_ufrag,
|
||||
const std::string& new_pwd);
|
||||
|
||||
// Adds the port on which the candidate originated.
|
||||
class RemoteCandidate : public Candidate {
|
||||
public:
|
||||
|
||||
@ -139,6 +139,34 @@ static std::string ComputeFoundation(const std::string& type,
|
||||
return rtc::ToString<uint32_t>(rtc::ComputeCrc32(ost.str()));
|
||||
}
|
||||
|
||||
ConnectionInfo::ConnectionInfo()
|
||||
: best_connection(false),
|
||||
writable(false),
|
||||
receiving(false),
|
||||
timeout(false),
|
||||
new_connection(false),
|
||||
rtt(0),
|
||||
sent_total_bytes(0),
|
||||
sent_bytes_second(0),
|
||||
sent_discarded_packets(0),
|
||||
sent_total_packets(0),
|
||||
sent_ping_requests_total(0),
|
||||
sent_ping_requests_before_first_response(0),
|
||||
sent_ping_responses(0),
|
||||
recv_total_bytes(0),
|
||||
recv_bytes_second(0),
|
||||
recv_ping_requests(0),
|
||||
recv_ping_responses(0),
|
||||
key(nullptr),
|
||||
state(IceCandidatePairState::WAITING),
|
||||
priority(0),
|
||||
nominated(false),
|
||||
total_round_trip_time_ms(0) {}
|
||||
|
||||
ConnectionInfo::ConnectionInfo(const ConnectionInfo&) = default;
|
||||
|
||||
ConnectionInfo::~ConnectionInfo() = default;
|
||||
|
||||
Port::Port(rtc::Thread* thread,
|
||||
const std::string& type,
|
||||
rtc::PacketSocketFactory* factory,
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "api/candidate.h"
|
||||
#include "api/optional.h"
|
||||
#include "p2p/base/candidatepairinterface.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/packetlossestimator.h"
|
||||
#include "p2p/base/packetsocketfactory.h"
|
||||
#include "p2p/base/portinterface.h"
|
||||
@ -104,6 +103,52 @@ enum class IceCandidatePairState {
|
||||
// frozen because we have not implemented ICE freezing logic.
|
||||
};
|
||||
|
||||
// Stats that we can return about the connections for a transport channel.
|
||||
// TODO(hta): Rename to ConnectionStats
|
||||
struct ConnectionInfo {
|
||||
ConnectionInfo();
|
||||
ConnectionInfo(const ConnectionInfo&);
|
||||
~ConnectionInfo();
|
||||
|
||||
bool best_connection; // Is this the best connection we have?
|
||||
bool writable; // Has this connection received a STUN response?
|
||||
bool receiving; // Has this connection received anything?
|
||||
bool timeout; // Has this connection timed out?
|
||||
bool new_connection; // Is this a newly created connection?
|
||||
size_t rtt; // The STUN RTT for this connection.
|
||||
size_t sent_total_bytes; // Total bytes sent on this connection.
|
||||
size_t sent_bytes_second; // Bps over the last measurement interval.
|
||||
size_t sent_discarded_packets; // Number of outgoing packets discarded due to
|
||||
// socket errors.
|
||||
size_t sent_total_packets; // Number of total outgoing packets attempted for
|
||||
// sending.
|
||||
size_t sent_ping_requests_total; // Number of STUN ping request sent.
|
||||
size_t sent_ping_requests_before_first_response; // Number of STUN ping
|
||||
// sent before receiving the first response.
|
||||
size_t sent_ping_responses; // Number of STUN ping response sent.
|
||||
|
||||
size_t recv_total_bytes; // Total bytes received on this connection.
|
||||
size_t recv_bytes_second; // Bps over the last measurement interval.
|
||||
size_t recv_ping_requests; // Number of STUN ping request received.
|
||||
size_t recv_ping_responses; // Number of STUN ping response received.
|
||||
Candidate local_candidate; // The local candidate for this connection.
|
||||
Candidate remote_candidate; // The remote candidate for this connection.
|
||||
void* key; // A static value that identifies this conn.
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-state
|
||||
IceCandidatePairState state;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-priority
|
||||
uint64_t priority;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-nominated
|
||||
bool nominated;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
|
||||
uint64_t total_round_trip_time_ms;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
|
||||
rtc::Optional<uint32_t> current_round_trip_time_ms;
|
||||
};
|
||||
|
||||
// Information about all the connections of a channel.
|
||||
typedef std::vector<ConnectionInfo> ConnectionInfos;
|
||||
|
||||
const char* ProtoToString(ProtocolType proto);
|
||||
bool StringToProto(const char* value, ProtocolType* proto);
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "p2p/base/basicpacketsocketfactory.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/relayport.h"
|
||||
#include "p2p/base/stunport.h"
|
||||
#include "p2p/base/tcpport.h"
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "api/candidate.h"
|
||||
#include "p2p/base/transportdescription.h"
|
||||
#include "rtc_base/asyncpacketsocket.h"
|
||||
#include "rtc_base/socketaddress.h"
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "p2p/base/jseptransport.h" // for ConnectionInfos
|
||||
#include "p2p/base/port.h" // for ConnectionInfos
|
||||
#include "rtc_base/criticalsection.h"
|
||||
#include "rtc_base/sigslot.h"
|
||||
#include "rtc_base/thread.h"
|
||||
|
||||
@ -42,6 +42,8 @@ rtc_static_library("rtc_pc_base") {
|
||||
"dtlssrtptransport.h",
|
||||
"externalhmac.cc",
|
||||
"externalhmac.h",
|
||||
"jseptransport.cc",
|
||||
"jseptransport.h",
|
||||
"mediamonitor.cc",
|
||||
"mediamonitor.h",
|
||||
"mediasession.cc",
|
||||
@ -257,6 +259,7 @@ if (rtc_include_tests) {
|
||||
"channelmanager_unittest.cc",
|
||||
"currentspeakermonitor_unittest.cc",
|
||||
"dtlssrtptransport_unittest.cc",
|
||||
"jseptransport_unittest.cc",
|
||||
"mediasession_unittest.cc",
|
||||
"rtcpmuxfilter_unittest.cc",
|
||||
"rtptransport_unittest.cc",
|
||||
|
||||
@ -8,13 +8,12 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "pc/jseptransport.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility> // for std::pair
|
||||
|
||||
#include "api/candidate.h"
|
||||
#include "p2p/base/dtlstransport.h"
|
||||
#include "p2p/base/p2pconstants.h"
|
||||
#include "p2p/base/p2ptransportchannel.h"
|
||||
#include "p2p/base/port.h"
|
||||
@ -26,6 +25,25 @@ using webrtc::SdpType;
|
||||
|
||||
namespace cricket {
|
||||
|
||||
TransportChannelStats::TransportChannelStats() = default;
|
||||
|
||||
TransportChannelStats::TransportChannelStats(const TransportChannelStats&) =
|
||||
default;
|
||||
|
||||
TransportChannelStats::~TransportChannelStats() = default;
|
||||
|
||||
TransportStats::TransportStats() = default;
|
||||
|
||||
TransportStats::~TransportStats() = default;
|
||||
|
||||
bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
|
||||
if (err_desc) {
|
||||
*err_desc = desc;
|
||||
}
|
||||
RTC_LOG(LS_ERROR) << desc;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool VerifyIceParams(const TransportDescription& desc) {
|
||||
// For legacy protocols.
|
||||
if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
|
||||
@ -42,128 +60,6 @@ static bool VerifyIceParams(const TransportDescription& desc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ConnectionInfo::ConnectionInfo()
|
||||
: best_connection(false),
|
||||
writable(false),
|
||||
receiving(false),
|
||||
timeout(false),
|
||||
new_connection(false),
|
||||
rtt(0),
|
||||
sent_total_bytes(0),
|
||||
sent_bytes_second(0),
|
||||
sent_discarded_packets(0),
|
||||
sent_total_packets(0),
|
||||
sent_ping_requests_total(0),
|
||||
sent_ping_requests_before_first_response(0),
|
||||
sent_ping_responses(0),
|
||||
recv_total_bytes(0),
|
||||
recv_bytes_second(0),
|
||||
recv_ping_requests(0),
|
||||
recv_ping_responses(0),
|
||||
key(nullptr),
|
||||
state(IceCandidatePairState::WAITING),
|
||||
priority(0),
|
||||
nominated(false),
|
||||
total_round_trip_time_ms(0) {}
|
||||
|
||||
ConnectionInfo::ConnectionInfo(const ConnectionInfo&) = default;
|
||||
|
||||
ConnectionInfo::~ConnectionInfo() = default;
|
||||
|
||||
TransportChannelStats::TransportChannelStats() = default;
|
||||
|
||||
TransportChannelStats::TransportChannelStats(const TransportChannelStats&) =
|
||||
default;
|
||||
|
||||
TransportChannelStats::~TransportChannelStats() = default;
|
||||
|
||||
TransportStats::TransportStats() = default;
|
||||
|
||||
TransportStats::~TransportStats() = default;
|
||||
|
||||
IceConfig::IceConfig() = default;
|
||||
|
||||
IceConfig::IceConfig(int receiving_timeout_ms,
|
||||
int backup_connection_ping_interval,
|
||||
ContinualGatheringPolicy gathering_policy,
|
||||
bool prioritize_most_likely_candidate_pairs,
|
||||
int stable_writable_connection_ping_interval_ms,
|
||||
bool presume_writable_when_fully_relayed,
|
||||
int regather_on_failed_networks_interval_ms,
|
||||
int receiving_switching_delay_ms)
|
||||
: receiving_timeout(receiving_timeout_ms),
|
||||
backup_connection_ping_interval(backup_connection_ping_interval),
|
||||
continual_gathering_policy(gathering_policy),
|
||||
prioritize_most_likely_candidate_pairs(
|
||||
prioritize_most_likely_candidate_pairs),
|
||||
stable_writable_connection_ping_interval(
|
||||
stable_writable_connection_ping_interval_ms),
|
||||
presume_writable_when_fully_relayed(presume_writable_when_fully_relayed),
|
||||
regather_on_failed_networks_interval(
|
||||
regather_on_failed_networks_interval_ms),
|
||||
receiving_switching_delay(receiving_switching_delay_ms) {}
|
||||
|
||||
IceConfig::~IceConfig() = default;
|
||||
|
||||
bool BadTransportDescription(const std::string& desc, std::string* err_desc) {
|
||||
if (err_desc) {
|
||||
*err_desc = desc;
|
||||
}
|
||||
RTC_LOG(LS_ERROR) << desc;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IceCredentialsChanged(const std::string& old_ufrag,
|
||||
const std::string& old_pwd,
|
||||
const std::string& new_ufrag,
|
||||
const std::string& new_pwd) {
|
||||
// The standard (RFC 5245 Section 9.1.1.1) says that ICE restarts MUST change
|
||||
// both the ufrag and password. However, section 9.2.1.1 says changing the
|
||||
// ufrag OR password indicates an ICE restart. So, to keep compatibility with
|
||||
// endpoints that only change one, we'll treat this as an ICE restart.
|
||||
return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
|
||||
}
|
||||
|
||||
bool VerifyCandidate(const Candidate& cand, std::string* error) {
|
||||
// No address zero.
|
||||
if (cand.address().IsNil() || cand.address().IsAnyIP()) {
|
||||
*error = "candidate has address of zero";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disallow all ports below 1024, except for 80 and 443 on public addresses.
|
||||
int port = cand.address().port();
|
||||
if (cand.protocol() == TCP_PROTOCOL_NAME &&
|
||||
(cand.tcptype() == TCPTYPE_ACTIVE_STR || port == 0)) {
|
||||
// Expected for active-only candidates per
|
||||
// http://tools.ietf.org/html/rfc6544#section-4.5 so no error.
|
||||
// Libjingle clients emit port 0, in "active" mode.
|
||||
return true;
|
||||
}
|
||||
if (port < 1024) {
|
||||
if ((port != 80) && (port != 443)) {
|
||||
*error = "candidate has port below 1024, but not 80 or 443";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cand.address().IsPrivateIP()) {
|
||||
*error = "candidate has port of 80 or 443 with private IP address";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifyCandidates(const Candidates& candidates, std::string* error) {
|
||||
for (const Candidate& candidate : candidates) {
|
||||
if (!VerifyCandidate(candidate, error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JsepTransport::JsepTransport(
|
||||
const std::string& mid,
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate)
|
||||
205
pc/jseptransport.h
Normal file
205
pc/jseptransport.h
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2004 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.
|
||||
*/
|
||||
|
||||
#ifndef PC_JSEPTRANSPORT_H_
|
||||
#define PC_JSEPTRANSPORT_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/candidate.h"
|
||||
#include "api/jsep.h"
|
||||
#include "api/optional.h"
|
||||
#include "p2p/base/dtlstransport.h"
|
||||
#include "p2p/base/p2pconstants.h"
|
||||
#include "p2p/base/sessiondescription.h"
|
||||
#include "p2p/base/transportinfo.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/messagequeue.h"
|
||||
#include "rtc_base/rtccertificate.h"
|
||||
#include "rtc_base/sigslot.h"
|
||||
#include "rtc_base/sslstreamadapter.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class DtlsTransportInternal;
|
||||
|
||||
struct TransportChannelStats {
|
||||
TransportChannelStats();
|
||||
TransportChannelStats(const TransportChannelStats&);
|
||||
~TransportChannelStats();
|
||||
|
||||
int component = 0;
|
||||
ConnectionInfos connection_infos;
|
||||
int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
||||
int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
|
||||
DtlsTransportState dtls_state = DTLS_TRANSPORT_NEW;
|
||||
};
|
||||
|
||||
// Information about all the channels of a transport.
|
||||
// TODO(hta): Consider if a simple vector is as good as a map.
|
||||
typedef std::vector<TransportChannelStats> TransportChannelStatsList;
|
||||
|
||||
// Information about the stats of a transport.
|
||||
struct TransportStats {
|
||||
TransportStats();
|
||||
~TransportStats();
|
||||
|
||||
std::string transport_name;
|
||||
TransportChannelStatsList channel_stats;
|
||||
};
|
||||
|
||||
bool BadTransportDescription(const std::string& desc, std::string* err_desc);
|
||||
|
||||
// Helper class used by TransportController that processes
|
||||
// TransportDescriptions. A TransportDescription represents the
|
||||
// transport-specific properties of an SDP m= section, processed according to
|
||||
// JSEP. Each transport consists of DTLS and ICE transport channels for RTP
|
||||
// (and possibly RTCP, if rtcp-mux isn't used).
|
||||
//
|
||||
// On Threading: Transport performs work solely on the network thread, and so
|
||||
// its methods should only be called on the network thread.
|
||||
class JsepTransport : public sigslot::has_slots<> {
|
||||
public:
|
||||
// |mid| is just used for log statements in order to identify the Transport.
|
||||
// Note that |certificate| is allowed to be null since a remote description
|
||||
// may be set before a local certificate is generated.
|
||||
JsepTransport(const std::string& mid,
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
|
||||
~JsepTransport() override;
|
||||
|
||||
// Returns the MID of this transport.
|
||||
const std::string& mid() const { return mid_; }
|
||||
|
||||
// Add or remove channel that is affected when a local/remote transport
|
||||
// description is set on this transport. Need to add all channels before
|
||||
// setting a transport description.
|
||||
bool AddChannel(DtlsTransportInternal* dtls, int component);
|
||||
bool RemoveChannel(int component);
|
||||
bool HasChannels() const;
|
||||
|
||||
bool ready_for_remote_candidates() const {
|
||||
return local_description_set_ && remote_description_set_;
|
||||
}
|
||||
|
||||
// Must be called before applying local session description.
|
||||
// Needed in order to verify the local fingerprint.
|
||||
void SetLocalCertificate(
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
|
||||
|
||||
// Get a copy of the local certificate provided by SetLocalCertificate.
|
||||
bool GetLocalCertificate(
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const;
|
||||
|
||||
// Set the local TransportDescription to be used by DTLS and ICE channels
|
||||
// that are part of this Transport.
|
||||
bool SetLocalTransportDescription(const TransportDescription& description,
|
||||
webrtc::SdpType type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Set the remote TransportDescription to be used by DTLS and ICE channels
|
||||
// that are part of this Transport.
|
||||
bool SetRemoteTransportDescription(const TransportDescription& description,
|
||||
webrtc::SdpType type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Set the "needs-ice-restart" flag as described in JSEP. After the flag is
|
||||
// set, offers should generate new ufrags/passwords until an ICE restart
|
||||
// occurs.
|
||||
//
|
||||
// This and the below method can be called safely from any thread as long as
|
||||
// SetXTransportDescription is not in progress.
|
||||
void SetNeedsIceRestartFlag();
|
||||
// Returns true if the ICE restart flag above was set, and no ICE restart has
|
||||
// occurred yet for this transport (by applying a local description with
|
||||
// changed ufrag/password).
|
||||
bool NeedsIceRestart() const;
|
||||
|
||||
// Returns role if negotiated, or empty Optional if it hasn't been negotiated
|
||||
// yet.
|
||||
rtc::Optional<rtc::SSLRole> GetSslRole() const;
|
||||
|
||||
// TODO(deadbeef): Make this const. See comment in transportcontroller.h.
|
||||
bool GetStats(TransportStats* stats);
|
||||
|
||||
// The current local transport description, possibly used
|
||||
// by the transport controller.
|
||||
const TransportDescription* local_description() const {
|
||||
return local_description_.get();
|
||||
}
|
||||
|
||||
// The current remote transport description, possibly used
|
||||
// by the transport controller.
|
||||
const TransportDescription* remote_description() const {
|
||||
return remote_description_.get();
|
||||
}
|
||||
|
||||
// TODO(deadbeef): The methods below are only public for testing. Should make
|
||||
// them utility functions or objects so they can be tested independently from
|
||||
// this class.
|
||||
|
||||
// Returns false if the certificate's identity does not match the fingerprint,
|
||||
// or either is NULL.
|
||||
bool VerifyCertificateFingerprint(const rtc::RTCCertificate* certificate,
|
||||
const rtc::SSLFingerprint* fingerprint,
|
||||
std::string* error_desc) const;
|
||||
|
||||
private:
|
||||
// Negotiates the transport parameters based on the current local and remote
|
||||
// transport description, such as the ICE role to use, and whether DTLS
|
||||
// should be activated.
|
||||
//
|
||||
// Called when an answer TransportDescription is applied.
|
||||
bool NegotiateTransportDescription(webrtc::SdpType local_description_type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Negotiates the SSL role based off the offer and answer as specified by
|
||||
// RFC 4145, section-4.1. Returns false if the SSL role cannot be determined
|
||||
// from the local description and remote description.
|
||||
bool NegotiateRole(webrtc::SdpType local_description_type,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters from the local description, such
|
||||
// as the ICE ufrag and pwd.
|
||||
bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters from the remote description to the
|
||||
// transport channel.
|
||||
bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters obtained via negotiation.
|
||||
bool ApplyNegotiatedTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
|
||||
const std::string mid_;
|
||||
// needs-ice-restart bit as described in JSEP.
|
||||
bool needs_ice_restart_ = false;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
|
||||
rtc::Optional<rtc::SSLRole> ssl_role_;
|
||||
std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_;
|
||||
std::unique_ptr<TransportDescription> local_description_;
|
||||
std::unique_ptr<TransportDescription> remote_description_;
|
||||
bool local_description_set_ = false;
|
||||
bool remote_description_set_ = false;
|
||||
|
||||
// Candidate component => DTLS channel
|
||||
std::map<int, DtlsTransportInternal*> channels_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // PC_JSEPTRANSPORT_H_
|
||||
@ -7,6 +7,7 @@
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
#include "pc/jseptransport.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -59,6 +60,13 @@ class JsepTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
transport_.reset(new JsepTransport("test content name", nullptr));
|
||||
}
|
||||
|
||||
bool IceCredentialsChanged(const std::string& old_ufrag,
|
||||
const std::string& old_pwd,
|
||||
const std::string& new_ufrag,
|
||||
const std::string& new_pwd) {
|
||||
return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<std::unique_ptr<FakeDtlsTransport>> fake_dtls_transports_;
|
||||
std::vector<std::unique_ptr<FakeIceTransport>> fake_ice_transports_;
|
||||
@ -26,9 +26,9 @@
|
||||
#include "media/base/mediaconstants.h"
|
||||
#include "media/base/mediaengine.h" // For DataChannelType
|
||||
#include "media/base/streamparams.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/sessiondescription.h"
|
||||
#include "p2p/base/transportdescriptionfactory.h"
|
||||
#include "pc/jseptransport.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
|
||||
@ -40,6 +40,47 @@ struct CandidatesData : public rtc::MessageData {
|
||||
cricket::Candidates candidates;
|
||||
};
|
||||
|
||||
bool VerifyCandidate(const cricket::Candidate& cand, std::string* error) {
|
||||
// No address zero.
|
||||
if (cand.address().IsNil() || cand.address().IsAnyIP()) {
|
||||
*error = "candidate has address of zero";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disallow all ports below 1024, except for 80 and 443 on public addresses.
|
||||
int port = cand.address().port();
|
||||
if (cand.protocol() == cricket::TCP_PROTOCOL_NAME &&
|
||||
(cand.tcptype() == cricket::TCPTYPE_ACTIVE_STR || port == 0)) {
|
||||
// Expected for active-only candidates per
|
||||
// http://tools.ietf.org/html/rfc6544#section-4.5 so no error.
|
||||
// Libjingle clients emit port 0, in "active" mode.
|
||||
return true;
|
||||
}
|
||||
if (port < 1024) {
|
||||
if ((port != 80) && (port != 443)) {
|
||||
*error = "candidate has port below 1024, but not 80 or 443";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cand.address().IsPrivateIP()) {
|
||||
*error = "candidate has port of 80 or 443 with private IP address";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifyCandidates(const cricket::Candidates& candidates,
|
||||
std::string* error) {
|
||||
for (const cricket::Candidate& candidate : candidates) {
|
||||
if (!VerifyCandidate(candidate, error)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace cricket {
|
||||
|
||||
@ -18,9 +18,9 @@
|
||||
|
||||
#include "api/candidate.h"
|
||||
#include "p2p/base/dtlstransport.h"
|
||||
#include "p2p/base/jseptransport.h"
|
||||
#include "p2p/base/p2ptransportchannel.h"
|
||||
#include "pc/dtlssrtptransport.h"
|
||||
#include "pc/jseptransport.h"
|
||||
#include "pc/rtptransport.h"
|
||||
#include "pc/srtptransport.h"
|
||||
#include "rtc_base/asyncinvoker.h"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user