In short, the caller places a x-opaque line in SDP for each m= section that
uses datagram transport. If the answerer supports datagram transport, it will
parse this line and create a datagram transport. It will then echo the x-opaque
line into the answer (to indicate that it accepted use of datagram transport).
If the offer and answer contain exactly the same x-opaque line, both peers will
use datagram transport. If the x-opaque line is omitted from the answer (or is
different in the answer) they will fall back to RTP.
Note that a different x-opaque line in the answer means the answerer did not
understand something in the negotiation proto. Since WebRTC cannot know what
was misunderstood, or whether it's still possible to use the datagram transport,
it must fall back to RTP. This may change in the future, possibly by passing
the answer to the datagram transport, but it's good enough for now.
Negotiation consists of four parts:
1. DatagramTransport exposes transport parameters for both client and server
perspectives. The client just echoes what it received from the server (modulo
any fields it might not have understood).
2. SDP adds a x-opaque line for opaque transport parameters. Identical to
x-mt, but this is specific to datagram transport and goes in each m= section,
and appears in the answer as well as the offer.
- This is propagated to Jsep as part of the TransportDescription.
- SDP files: transport_description.h,cc, transport_description_factory.h,cc,
media_session.cc, webrtc_sdp.cc
3. JsepTransport/Controller:
- Exposes opaque parameters for each mid (m= section). On offerer, this means
pre-allocating a datagram transport and getting its parameters. On the
answerer, this means echoing the offerer's parameters.
- Uses a composite RTP transport to receive from either default RTP or
datagram transport until both offer and answer arrive.
- If a provisional answer arrives, sets the composite to send on the
provisionally selected transport.
- Once both offer and answer are set, deletes the unneeded transports and
keeps whichever transport is selected.
4. PeerConnection pulls transport parameters out of Jsep and adds them to SDP.
Bug: webrtc:9719
Change-Id: Ifcc428c8d76fb77dcc8abaa79507c620bcfb31b9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/140920
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Bjorn Mellem <mellem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28198}
165 lines
5.9 KiB
C++
165 lines
5.9 KiB
C++
/*
|
|
* Copyright 2012 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 P2P_BASE_TRANSPORT_DESCRIPTION_H_
|
|
#define P2P_BASE_TRANSPORT_DESCRIPTION_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/algorithm/container.h"
|
|
#include "absl/types/optional.h"
|
|
#include "p2p/base/p2p_constants.h"
|
|
#include "rtc_base/ssl_fingerprint.h"
|
|
|
|
namespace cricket {
|
|
|
|
// SEC_ENABLED and SEC_REQUIRED should only be used if the session
|
|
// was negotiated over TLS, to protect the inline crypto material
|
|
// exchange.
|
|
// SEC_DISABLED: No crypto in outgoing offer, ignore any supplied crypto.
|
|
// SEC_ENABLED: Crypto in outgoing offer and answer (if supplied in offer).
|
|
// SEC_REQUIRED: Crypto in outgoing offer and answer. Fail any offer with absent
|
|
// or unsupported crypto.
|
|
// TODO(deadbeef): Remove this or rename it to something more appropriate, like
|
|
// SdesPolicy.
|
|
enum SecurePolicy { SEC_DISABLED, SEC_ENABLED, SEC_REQUIRED };
|
|
|
|
// Whether our side of the call is driving the negotiation, or the other side.
|
|
enum IceRole { ICEROLE_CONTROLLING = 0, ICEROLE_CONTROLLED, ICEROLE_UNKNOWN };
|
|
|
|
// ICE RFC 5245 implementation type.
|
|
enum IceMode {
|
|
ICEMODE_FULL, // As defined in http://tools.ietf.org/html/rfc5245#section-4.1
|
|
ICEMODE_LITE // As defined in http://tools.ietf.org/html/rfc5245#section-4.2
|
|
};
|
|
|
|
// RFC 4145 - http://tools.ietf.org/html/rfc4145#section-4
|
|
// 'active': The endpoint will initiate an outgoing connection.
|
|
// 'passive': The endpoint will accept an incoming connection.
|
|
// 'actpass': The endpoint is willing to accept an incoming
|
|
// connection or to initiate an outgoing connection.
|
|
enum ConnectionRole {
|
|
CONNECTIONROLE_NONE = 0,
|
|
CONNECTIONROLE_ACTIVE,
|
|
CONNECTIONROLE_PASSIVE,
|
|
CONNECTIONROLE_ACTPASS,
|
|
CONNECTIONROLE_HOLDCONN,
|
|
};
|
|
|
|
struct IceParameters {
|
|
// TODO(honghaiz): Include ICE mode in this structure to match the ORTC
|
|
// struct:
|
|
// http://ortc.org/wp-content/uploads/2016/03/ortc.html#idl-def-RTCIceParameters
|
|
std::string ufrag;
|
|
std::string pwd;
|
|
bool renomination = false;
|
|
IceParameters() = default;
|
|
IceParameters(const std::string& ice_ufrag,
|
|
const std::string& ice_pwd,
|
|
bool ice_renomination)
|
|
: ufrag(ice_ufrag), pwd(ice_pwd), renomination(ice_renomination) {}
|
|
|
|
bool operator==(const IceParameters& other) const {
|
|
return ufrag == other.ufrag && pwd == other.pwd &&
|
|
renomination == other.renomination;
|
|
}
|
|
bool operator!=(const IceParameters& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
|
|
extern const char CONNECTIONROLE_ACTIVE_STR[];
|
|
extern const char CONNECTIONROLE_PASSIVE_STR[];
|
|
extern const char CONNECTIONROLE_ACTPASS_STR[];
|
|
extern const char CONNECTIONROLE_HOLDCONN_STR[];
|
|
|
|
constexpr auto* ICE_OPTION_TRICKLE = "trickle";
|
|
constexpr auto* ICE_OPTION_RENOMINATION = "renomination";
|
|
|
|
bool StringToConnectionRole(const std::string& role_str, ConnectionRole* role);
|
|
bool ConnectionRoleToString(const ConnectionRole& role, std::string* role_str);
|
|
|
|
// Parameters for an opaque transport protocol which may be plugged into WebRTC.
|
|
struct OpaqueTransportParameters {
|
|
// Protocol used by this opaque transport. Two endpoints that support the
|
|
// same protocol are expected to be able to understand the contents of each
|
|
// others' |parameters| fields. If those parameters are compatible, the
|
|
// endpoints are expected to use this transport protocol.
|
|
std::string protocol;
|
|
|
|
// Opaque parameters for this transport. These parameters are serialized in a
|
|
// manner determined by the |protocol|. They can be parsed and understood by
|
|
// the plugin that supports |protocol|.
|
|
std::string parameters;
|
|
|
|
bool operator==(const OpaqueTransportParameters& other) const {
|
|
return protocol == other.protocol && parameters == other.parameters;
|
|
}
|
|
|
|
bool operator!=(const OpaqueTransportParameters& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
|
|
struct TransportDescription {
|
|
TransportDescription();
|
|
TransportDescription(const std::vector<std::string>& transport_options,
|
|
const std::string& ice_ufrag,
|
|
const std::string& ice_pwd,
|
|
IceMode ice_mode,
|
|
ConnectionRole role,
|
|
const rtc::SSLFingerprint* identity_fingerprint);
|
|
TransportDescription(const std::string& ice_ufrag,
|
|
const std::string& ice_pwd);
|
|
TransportDescription(const TransportDescription& from);
|
|
~TransportDescription();
|
|
|
|
TransportDescription& operator=(const TransportDescription& from);
|
|
|
|
// TODO(deadbeef): Rename to HasIceOption, etc.
|
|
bool HasOption(const std::string& option) const {
|
|
return absl::c_linear_search(transport_options, option);
|
|
}
|
|
void AddOption(const std::string& option) {
|
|
transport_options.push_back(option);
|
|
}
|
|
bool secure() const { return identity_fingerprint != nullptr; }
|
|
|
|
IceParameters GetIceParameters() {
|
|
return IceParameters(ice_ufrag, ice_pwd,
|
|
HasOption(ICE_OPTION_RENOMINATION));
|
|
}
|
|
|
|
static rtc::SSLFingerprint* CopyFingerprint(const rtc::SSLFingerprint* from) {
|
|
if (!from)
|
|
return NULL;
|
|
|
|
return new rtc::SSLFingerprint(*from);
|
|
}
|
|
|
|
// These are actually ICE options (appearing in the ice-options attribute in
|
|
// SDP).
|
|
// TODO(deadbeef): Rename to ice_options.
|
|
std::vector<std::string> transport_options;
|
|
std::string ice_ufrag;
|
|
std::string ice_pwd;
|
|
IceMode ice_mode;
|
|
ConnectionRole connection_role;
|
|
|
|
std::unique_ptr<rtc::SSLFingerprint> identity_fingerprint;
|
|
absl::optional<OpaqueTransportParameters> opaque_parameters;
|
|
};
|
|
|
|
} // namespace cricket
|
|
|
|
#endif // P2P_BASE_TRANSPORT_DESCRIPTION_H_
|