Compare commits

...

16 Commits

Author SHA1 Message Date
e4ab5273fc Bumped version to 0.12.3 2021-05-07 21:24:17 +02:00
bf0b3ce1b9 Resolve use of deprecated ::result_type typedef.
Also adds #include <utility> since this file names std::move.

```
         D:\buildtrees\libdatachannel\src\v0.12.0-2d418b9dcd.clean\include\rtc\utils.hpp(35,23): error C4996: 'std::_Weak_result_type<std::_Is_memfunptr<void (__cdecl rtc::impl::PeerConnection::* )(std::weak_ptr<_Ty>)>,void>::result_type': warning STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. You can define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [D:\buildtrees\libdatachannel\x64-uwp-dbg\datachannel.vcxproj]
         D:\buildtrees\libdatachannel\src\v0.12.0-2d418b9dcd.clean\include\rtc\utils.hpp(35,23): error C4996: 'std::_Weak_result_type<std::_Is_memfunptr<void (__cdecl rtc::impl::PeerConnection::* )(rtc::Candidate)>,void>::result_type': warning STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. You can define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [D:\buildtrees\libdatachannel\x64-uwp-dbg\datachannel.vcxproj]
         D:\buildtrees\libdatachannel\src\v0.12.0-2d418b9dcd.clean\include\rtc\utils.hpp(35,23): error C4996: 'std::_Weak_result_type<std::_Is_memfunptr<bool (__cdecl rtc::impl::PeerConnection::* )(const std::string &) const>,void>::result_type': warning STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. You can define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [D:\buildtrees\libdatachannel\x64-uwp-dbg\datachannel.vcxproj]
         D:\buildtrees\libdatachannel\src\v0.12.0-2d418b9dcd.clean\include\rtc\utils.hpp(35,23): error C4996: 'std::_Weak_result_type<std::_Is_memfunptr<void (__cdecl rtc::impl::PeerConnection::* )(rtc::message_ptr)>,void>::result_type': warning STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. You can define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [D:\buildtrees\libdatachannel\x64-uwp-dbg\datachannel.vcxproj]
         D:\buildtrees\libdatachannel\src\v0.12.0-2d418b9dcd.clean\include\rtc\utils.hpp(35,23): error C4996: 'std::_Weak_result_type<std::_Is_memfunptr<void (__cdecl rtc::impl::PeerConnection::* )(uint16_t,size_t)>,void>::result_type': warning STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. You can define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [D:\buildtrees\libdatachannel\x64-uwp-dbg\datachannel.vcxproj]
```
2021-04-20 09:20:56 +02:00
655175d21e Bumped version to 0.12.2 2021-04-14 12:24:12 +02:00
c85943e916 support finding openssl form homebrew on M1 Macs
homebrew changed its default installation paths for M1 Macs
2021-04-14 12:22:26 +02:00
1cc7910bf1 Made impl::DataChannel destructor virtual 2021-04-13 22:29:25 +02:00
62b435a4aa Fixed compilation warnings 2021-04-10 16:22:05 +02:00
9da756bd12 Updated Jamfile 2021-04-10 10:54:10 +02:00
f5b584f536 Handle empty RTCIceCandidate.candidate as "end of candidates" indicator 2021-04-08 15:10:26 +02:00
3eb8ab567e Bumped version to 0.12.1 2021-04-07 17:45:03 +02:00
f1a7afb28e Merge pull request #392 from paullouisageneau/fix-htonll
Fix htonll fallback implementation
2021-04-07 16:01:53 +02:00
9a7b672d6e Fixed htonll fallback implementation 2021-04-07 15:50:11 +02:00
9da58f4343 Updated Readme 2021-04-06 19:02:33 +02:00
ef2e7c609a Merge pull request #390 from paullouisageneau/fix-dc-double-offer
Fix DataChannel stream number assignment on double offer
2021-04-06 18:52:44 +02:00
d330738b41 Fixed synchronization in DataChannel::shiftStream() 2021-04-06 18:44:29 +02:00
791e6b1e32 Fixed DataChannel shifting on double offer 2021-04-06 18:39:12 +02:00
b5884c84fc Fixed mistakes in Doc 2021-04-04 17:07:17 +02:00
13 changed files with 42 additions and 36 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.7) cmake_minimum_required(VERSION 3.7)
project(libdatachannel project(libdatachannel
VERSION 0.12.0 VERSION 0.12.3
LANGUAGES CXX) LANGUAGES CXX)
set(PROJECT_DESCRIPTION "WebRTC Data Channels Library") set(PROJECT_DESCRIPTION "WebRTC Data Channels Library")

6
DOC.md
View File

@ -88,7 +88,7 @@ Arguments:
- `iceServersCount` (optional): number of URLs in the array pointed by `iceServers` (0 if unused) - `iceServersCount` (optional): number of URLs in the array pointed by `iceServers` (0 if unused)
- `certificateType` (optional): certificate type, either `RTC_CERTIFICATE_ECDSA` or `RTC_CERTIFICATE_RSA` (0 or `RTC_CERTIFICATE_DEFAULT` if default) - `certificateType` (optional): certificate type, either `RTC_CERTIFICATE_ECDSA` or `RTC_CERTIFICATE_RSA` (0 or `RTC_CERTIFICATE_DEFAULT` if default)
- `enableIceTcp`: if true, generate TCP candidates for ICE (ignored with libjuice as ICE backend) - `enableIceTcp`: if true, generate TCP candidates for ICE (ignored with libjuice as ICE backend)
- `disableAutoNegociation`: if true, the user is responsible for calling `rtcSetLocalDescription` after creating a Data Channel and after setting the remote description - `disableAutoNegotiation`: if true, the user is responsible for calling `rtcSetLocalDescription` after creating a Data Channel and after setting the remote description
- `portRangeBegin` (optional): first port (included) of the allowed local port range (0 if unused) - `portRangeBegin` (optional): first port (included) of the allowed local port range (0 if unused)
- `portRangeEnd` (optional): last port (included) of the allowed local port (0 if unused) - `portRangeEnd` (optional): last port (included) of the allowed local port (0 if unused)
- `mtu` (optional): manually set the Maximum Transfer Unit (MTU) for the connection (0 if automatic) - `mtu` (optional): manually set the Maximum Transfer Unit (MTU) for the connection (0 if automatic)
@ -165,7 +165,7 @@ int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb)
int rtcSetLocalDescription(int pc, const char *type) int rtcSetLocalDescription(int pc, const char *type)
``` ```
Initiates the handshake process. Following this call, the local description callback will be called with the local description, which must be sent to the remote peer by the user's method of choice. Note this call is implicit after `rtcSetRemoteDescription` and `rtcCreateDataChannel` if `disableAutoNegociation` was not set on Peer Connection creation. Initiates the handshake process. Following this call, the local description callback will be called with the local description, which must be sent to the remote peer by the user's method of choice. Note this call is implicit after `rtcSetRemoteDescription` and `rtcCreateDataChannel` if `disableAutoNegotiation` was not set on Peer Connection creation.
Arguments: Arguments:
- `pc`: the Peer Connection identifier - `pc`: the Peer Connection identifier
@ -326,7 +326,7 @@ If `local`, `remote`, or both, are `NULL`, the corresponding candidate is not co
### Data Channel ### Data Channel
#### rtcAddDataChannel #### rtcCreateDataChannel
``` ```
int rtcCreateDataChannel(int pc, const char *label) int rtcCreateDataChannel(int pc, const char *label)

View File

@ -12,9 +12,12 @@ feature.compose <gnutls>on
lib libdatachannel lib libdatachannel
: # sources : # sources
[ glob ./src/*.cpp ] [ glob ./src/*.cpp ]
[ glob ./src/impl/*.cpp ]
: # requirements : # requirements
<cxxstd>17 <cxxstd>17
<include>./include
<include>./include/rtc <include>./include/rtc
<include>./src
<define>RTC_ENABLE_MEDIA=0 <define>RTC_ENABLE_MEDIA=0
<define>RTC_ENABLE_WEBSOCKET=0 <define>RTC_ENABLE_WEBSOCKET=0
<define>USE_NICE=0 <define>USE_NICE=0
@ -143,7 +146,7 @@ rule make_libjuice_openssl ( targets * : sources * : properties * )
{ {
# on macOS, default to pick up openssl from the homebrew installation # on macOS, default to pick up openssl from the homebrew installation
# brew install openssl # brew install openssl
OPENSSL_INCLUDE = /usr/local/opt/openssl/include ; OPENSSL_INCLUDE = /opt/homebrew/opt/openssl /usr/local/opt/openssl/include ;
} }
if $(OPENSSL_INCLUDE) != "" if $(OPENSSL_INCLUDE) != ""
@ -191,7 +194,7 @@ rule openssl-lib-path ( properties * )
{ {
# on macOS, default to pick up openssl from the homebrew installation # on macOS, default to pick up openssl from the homebrew installation
# brew install openssl # brew install openssl
OPENSSL_LIB = /usr/local/opt/openssl/lib ; OPENSSL_LIB = /opt/homebrew/opt/openssl/lib /usr/local/opt/openssl/lib ;
} }
else if <target-os>windows in $(properties) && $(OPENSSL_LIB) = "" else if <target-os>windows in $(properties) && $(OPENSSL_LIB) = ""
{ {
@ -217,7 +220,7 @@ rule openssl-include-path ( properties * )
{ {
# on macOS, default to pick up openssl from the homebrew installation # on macOS, default to pick up openssl from the homebrew installation
# brew install openssl # brew install openssl
OPENSSL_INCLUDE = /usr/local/opt/openssl/include ; OPENSSL_INCLUDE = /opt/homebrew/opt/openssl/include /usr/local/opt/openssl/include ;
} }
else if <target-os>windows in $(properties) && $(OPENSSL_INCLUDE) = "" else if <target-os>windows in $(properties) && $(OPENSSL_INCLUDE) = ""
{ {

View File

@ -2,7 +2,7 @@
libdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets in C++17 with C bindings for POSIX platforms (including GNU/Linux, Android, and Apple macOS) and Microsoft Windows. libdatachannel is a standalone implementation of WebRTC Data Channels, WebRTC Media Transport, and WebSockets in C++17 with C bindings for POSIX platforms (including GNU/Linux, Android, and Apple macOS) and Microsoft Windows.
The library aims at being both straightforward and lightweight with a minimum of external dependencies, to enable direct connectivity between native applications and web browsers without the pain of importing Google's bloated [reference library](https://webrtc.googlesource.com/src/). The interface consists of somewhat simplified versions of the JavaScript WebRTC and WebSocket APIs present in browsers, in order to ease the design of cross-environment applications. The library aims at being both straightforward and lightweight with minimal external dependencies, to enable direct connectivity between native applications and web browsers without the pain of importing Google's bloated [reference library](https://webrtc.googlesource.com/src/). The interface consists of somewhat simplified versions of the JavaScript WebRTC and WebSocket APIs present in browsers, in order to ease the design of cross-environment applications.
It can be compiled with multiple backends: It can be compiled with multiple backends:
- The security layer can be provided through [OpenSSL](https://www.openssl.org/) or [GnuTLS](https://www.gnutls.org/). - The security layer can be provided through [OpenSSL](https://www.openssl.org/) or [GnuTLS](https://www.gnutls.org/).
@ -19,7 +19,7 @@ Only [GnuTLS](https://www.gnutls.org/) or [OpenSSL](https://www.openssl.org/) ar
Submodules: Submodules:
- libjuice: https://github.com/paullouisageneau/libjuice - libjuice: https://github.com/paullouisageneau/libjuice
- usrsctp: https://github.com/sctplab/usrsctp - usrsctp: https://github.com/sctplab/usrsctp
- libsrtp: https://github.com/cisco/libsrtp - libsrtp: https://github.com/cisco/libsrtp (if compiled with media support)
## Building ## Building
@ -124,6 +124,8 @@ The library implements the following communication protocols:
### WebRTC Data Channels and Media Transport ### WebRTC Data Channels and Media Transport
The library implements WebRTC Peer Connections with both Data Channels and Media Transport. Media transport is optional and can be disabled at compile time.
Protocol stack: Protocol stack:
- SCTP-based Data Channels ([RFC8831](https://tools.ietf.org/html/rfc8831)) - SCTP-based Data Channels ([RFC8831](https://tools.ietf.org/html/rfc8831))
- SRTP-based Media Transport ([RFC8834](https://tools.ietf.org/html/rfc8834)) - SRTP-based Media Transport ([RFC8834](https://tools.ietf.org/html/rfc8834))

View File

@ -118,7 +118,7 @@ function createPeerConnection(ws, id) {
pc.onconnectionstatechange = () => console.log(`Connection state: ${pc.connectionState}`); pc.onconnectionstatechange = () => console.log(`Connection state: ${pc.connectionState}`);
pc.onicegatheringstatechange = () => console.log(`Gathering state: ${pc.iceGatheringState}`); pc.onicegatheringstatechange = () => console.log(`Gathering state: ${pc.iceGatheringState}`);
pc.onicecandidate = (e) => { pc.onicecandidate = (e) => {
if (e.candidate) { if (e.candidate && e.candidate.candidate) {
// Send candidate // Send candidate
sendLocalCandidate(ws, id, e.candidate); sendLocalCandidate(ws, id, e.candidate);
} }

View File

@ -33,7 +33,7 @@
#ifndef htonll #ifndef htonll
#define htonll(x) \ #define htonll(x) \
((uint64_t)htonl(((uint64_t)(x)&0xFFFFFFFF) << 32) | (uint64_t)htonl((uint64_t)(x) >> 32)) ((uint64_t)(((uint64_t)htonl((uint32_t)(x))) << 32) | (uint64_t)htonl((uint32_t)((x) >> 32)))
#endif #endif
#ifndef ntohll #ifndef ntohll
#define ntohll(x) htonll(x) #define ntohll(x) htonll(x)

View File

@ -22,6 +22,7 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <utility>
namespace rtc { namespace rtc {
@ -32,11 +33,10 @@ template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// weak_ptr bind helper // weak_ptr bind helper
template <typename F, typename T, typename... Args> auto weak_bind(F &&f, T *t, Args &&..._args) { template <typename F, typename T, typename... Args> auto weak_bind(F &&f, T *t, Args &&..._args) {
return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&...args) { return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&...args) {
using result_type = typename decltype(bound)::result_type;
if (auto shared_this = weak_this.lock()) if (auto shared_this = weak_this.lock())
return bound(args...); return bound(args...);
else else
return static_cast<result_type>(false); return static_cast<decltype(bound(args...))>(false);
}; };
} }

View File

@ -170,6 +170,7 @@ size_t DataChannel::maxMessageSize() const {
} }
void DataChannel::shiftStream() { void DataChannel::shiftStream() {
std::shared_lock lock(mMutex);
if (mStream % 2 == 1) if (mStream % 2 == 1)
mStream -= 1; mStream -= 1;
} }

View File

@ -36,7 +36,7 @@ struct PeerConnection;
struct DataChannel : Channel, std::enable_shared_from_this<DataChannel> { struct DataChannel : Channel, std::enable_shared_from_this<DataChannel> {
DataChannel(weak_ptr<PeerConnection> pc, uint16_t stream, string label, string protocol, DataChannel(weak_ptr<PeerConnection> pc, uint16_t stream, string label, string protocol,
Reliability reliability); Reliability reliability);
~DataChannel(); virtual ~DataChannel();
void close(); void close();
void remoteClose(); void remoteClose();

View File

@ -189,7 +189,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
auto certificate = mCertificate.get(); auto certificate = mCertificate.get();
auto lower = std::atomic_load(&mIceTransport); auto lower = std::atomic_load(&mIceTransport);
auto verifierCallback = weak_bind(&PeerConnection::checkFingerprint, this, _1); auto verifierCallback = weak_bind(&PeerConnection::checkFingerprint, this, _1);
auto stateChangeCallback = auto dtlsStateChangeCallback =
[this, weak_this = weak_from_this()](DtlsTransport::State transportState) { [this, weak_this = weak_from_this()](DtlsTransport::State transportState) {
auto shared_this = weak_this.lock(); auto shared_this = weak_this.lock();
if (!shared_this) if (!shared_this)
@ -224,7 +224,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
// DTLS-SRTP // DTLS-SRTP
transport = std::make_shared<DtlsSrtpTransport>( transport = std::make_shared<DtlsSrtpTransport>(
lower, certificate, config.mtu, verifierCallback, lower, certificate, config.mtu, verifierCallback,
weak_bind(&PeerConnection::forwardMedia, this, _1), stateChangeCallback); weak_bind(&PeerConnection::forwardMedia, this, _1), dtlsStateChangeCallback);
#else #else
PLOG_WARNING << "Ignoring media support (not compiled with media support)"; PLOG_WARNING << "Ignoring media support (not compiled with media support)";
#endif #endif
@ -233,7 +233,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
if (!transport) { if (!transport) {
// DTLS only // DTLS only
transport = std::make_shared<DtlsTransport>(lower, certificate, config.mtu, transport = std::make_shared<DtlsTransport>(lower, certificate, config.mtu,
verifierCallback, stateChangeCallback); verifierCallback, dtlsStateChangeCallback);
} }
std::atomic_store(&mDtlsTransport, transport); std::atomic_store(&mDtlsTransport, transport);
@ -262,6 +262,9 @@ shared_ptr<SctpTransport> PeerConnection::initSctpTransport() {
if (!remote || !remote->application()) if (!remote || !remote->application())
throw std::logic_error("Starting SCTP transport without application description"); throw std::logic_error("Starting SCTP transport without application description");
// This is the last occasion to ensure the stream numbers are coherent with the role
shiftDataChannels();
uint16_t sctpPort = remote->application()->sctpPort().value_or(DEFAULT_SCTP_PORT); uint16_t sctpPort = remote->application()->sctpPort().value_or(DEFAULT_SCTP_PORT);
auto lower = std::atomic_load(&mDtlsTransport); auto lower = std::atomic_load(&mDtlsTransport);
auto transport = std::make_shared<SctpTransport>( auto transport = std::make_shared<SctpTransport>(
@ -549,8 +552,7 @@ void PeerConnection::forwardBufferedAmount(uint16_t stream, size_t amount) {
channel->triggerBufferedAmount(amount); channel->triggerBufferedAmount(amount);
} }
shared_ptr<DataChannel> PeerConnection::emplaceDataChannel(Description::Role role, string label, shared_ptr<DataChannel> PeerConnection::emplaceDataChannel(string label, DataChannelInit init) {
DataChannelInit init) {
std::unique_lock lock(mDataChannelsMutex); // we are going to emplace std::unique_lock lock(mDataChannelsMutex); // we are going to emplace
uint16_t stream; uint16_t stream;
if (init.id) { if (init.id) {
@ -558,6 +560,13 @@ shared_ptr<DataChannel> PeerConnection::emplaceDataChannel(Description::Role rol
if (stream == 65535) if (stream == 65535)
throw std::invalid_argument("Invalid DataChannel id"); throw std::invalid_argument("Invalid DataChannel id");
} else { } else {
// RFC 5763: The answerer MUST use either a setup attribute value of setup:active or
// setup:passive. [...] Thus, setup:active is RECOMMENDED.
// See https://tools.ietf.org/html/rfc5763#section-5
// Therefore, we assume passive role if we are the offerer.
auto iceTransport = getIceTransport();
auto role = iceTransport ? iceTransport->role() : Description::Role::Passive;
// RFC 8832: The peer that initiates opening a data channel selects a stream identifier for // RFC 8832: The peer that initiates opening a data channel selects a stream identifier for
// which the corresponding incoming and outgoing streams are unused. If the side is acting // which the corresponding incoming and outgoing streams are unused. If the side is acting
// as the DTLS client, it MUST choose an even stream identifier; if the side is acting as // as the DTLS client, it MUST choose an even stream identifier; if the side is acting as
@ -729,7 +738,7 @@ void PeerConnection::validateRemoteDescription(const Description &description) {
} }
void PeerConnection::processLocalDescription(Description description) { void PeerConnection::processLocalDescription(Description description) {
const size_t localSctpPort = DEFAULT_SCTP_PORT; const uint16_t localSctpPort = DEFAULT_SCTP_PORT;
const size_t localMaxMessageSize = const size_t localMaxMessageSize =
config.maxMessageSize.value_or(DEFAULT_LOCAL_MAX_MESSAGE_SIZE); config.maxMessageSize.value_or(DEFAULT_LOCAL_MAX_MESSAGE_SIZE);
@ -907,6 +916,10 @@ void PeerConnection::processRemoteDescription(Description description) {
auto iceTransport = initIceTransport(); auto iceTransport = initIceTransport();
iceTransport->setRemoteDescription(std::move(description)); iceTransport->setRemoteDescription(std::move(description));
// Since we assumed passive role during DataChannel creation, we might need to shift the stream
// numbers from odd to even.
shiftDataChannels();
if (description.hasApplication()) { if (description.hasApplication()) {
auto dtlsTransport = std::atomic_load(&mDtlsTransport); auto dtlsTransport = std::atomic_load(&mDtlsTransport);
auto sctpTransport = std::atomic_load(&mSctpTransport); auto sctpTransport = std::atomic_load(&mSctpTransport);

View File

@ -65,8 +65,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
void forwardBufferedAmount(uint16_t stream, size_t amount); void forwardBufferedAmount(uint16_t stream, size_t amount);
optional<string> getMidFromSsrc(uint32_t ssrc); optional<string> getMidFromSsrc(uint32_t ssrc);
shared_ptr<DataChannel> emplaceDataChannel(Description::Role role, string label, shared_ptr<DataChannel> emplaceDataChannel(string label, DataChannelInit init);
DataChannelInit init);
shared_ptr<DataChannel> findDataChannel(uint16_t stream); shared_ptr<DataChannel> findDataChannel(uint16_t stream);
void shiftDataChannels(); void shiftDataChannels();
void iterateDataChannels(std::function<void(shared_ptr<DataChannel> channel)> func); void iterateDataChannels(std::function<void(shared_ptr<DataChannel> channel)> func);

View File

@ -39,7 +39,7 @@
#ifndef htonll #ifndef htonll
#define htonll(x) \ #define htonll(x) \
((uint64_t)htonl(((uint64_t)(x)&0xFFFFFFFF) << 32) | (uint64_t)htonl((uint64_t)(x) >> 32)) ((uint64_t)(((uint64_t)htonl((uint32_t)(x))) << 32) | (uint64_t)htonl((uint32_t)((x) >> 32)))
#endif #endif
#ifndef ntohll #ifndef ntohll
#define ntohll(x) htonll(x) #define ntohll(x) htonll(x)

View File

@ -223,11 +223,6 @@ void PeerConnection::setRemoteDescription(Description description) {
// This is an offer, we need to answer // This is an offer, we need to answer
if (!impl()->config.disableAutoNegotiation) if (!impl()->config.disableAutoNegotiation)
setLocalDescription(Description::Type::Answer); setLocalDescription(Description::Type::Answer);
} else {
// This is an answer
// Since we assumed passive role during DataChannel creation, we need to shift the
// stream numbers by one to shift them from odd to even.
impl()->shiftDataChannels();
} }
for (const auto &candidate : remoteCandidates) for (const auto &candidate : remoteCandidates)
@ -250,14 +245,7 @@ optional<string> PeerConnection::remoteAddress() const {
} }
shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) { shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) {
// RFC 5763: The answerer MUST use either a setup attribute value of setup:active or auto channelImpl = impl()->emplaceDataChannel(std::move(label), std::move(init));
// setup:passive. [...] Thus, setup:active is RECOMMENDED.
// See https://tools.ietf.org/html/rfc5763#section-5
// Therefore, we assume passive role when we are the offerer.
auto iceTransport = impl()->getIceTransport();
auto role = iceTransport ? iceTransport->role() : Description::Role::Passive;
auto channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
auto channel = std::make_shared<DataChannel>(channelImpl); auto channel = std::make_shared<DataChannel>(channelImpl);
if (auto transport = impl()->getSctpTransport()) if (auto transport = impl()->getSctpTransport())