Compare commits

...

13 Commits

8 changed files with 76 additions and 37 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.13.0 VERSION 0.13.3
LANGUAGES CXX) LANGUAGES CXX)
set(PROJECT_DESCRIPTION "WebRTC Data Channels Library") set(PROJECT_DESCRIPTION "WebRTC Data Channels Library")
@ -327,7 +327,7 @@ if(WARNINGS_AS_ERRORS)
endif() endif()
endif() endif()
install(TARGETS datachannel EXPORT datachannel-export install(TARGETS datachannel EXPORT libdatachannel-config
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
@ -338,7 +338,7 @@ install(FILES ${LIBDATACHANNEL_HEADERS}
) )
install( install(
EXPORT datachannel-export EXPORT libdatachannel-config
NAMESPACE LibDatachannel:: NAMESPACE LibDatachannel::
DESTINATION share/cmake/libdatachannel DESTINATION share/cmake/libdatachannel
) )

2
deps/libjuice vendored

View File

@ -22,6 +22,7 @@
#include "common.hpp" #include "common.hpp"
#include <chrono> #include <chrono>
#include <iostream>
namespace rtc { namespace rtc {
@ -42,8 +43,8 @@ RTC_CPP_EXPORT void InitLogger(LogLevel level, LogCallback callback = nullptr);
RTC_CPP_EXPORT void InitLogger(plog::Severity severity, plog::IAppender *appender = nullptr); RTC_CPP_EXPORT void InitLogger(plog::Severity severity, plog::IAppender *appender = nullptr);
#endif #endif
RTC_EXPORT void Preload(); RTC_CPP_EXPORT void Preload();
RTC_EXPORT void Cleanup(); RTC_CPP_EXPORT void Cleanup();
struct SctpSettings { struct SctpSettings {
// For the following settings, not set means optimized default // For the following settings, not set means optimized default
@ -56,8 +57,10 @@ struct SctpSettings {
optional<std::chrono::milliseconds> delayedSackTime; optional<std::chrono::milliseconds> delayedSackTime;
}; };
RTC_EXPORT void SetSctpSettings(SctpSettings s); RTC_CPP_EXPORT void SetSctpSettings(SctpSettings s);
} // namespace rtc } // namespace rtc
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::LogLevel level);
#endif #endif

View File

@ -93,7 +93,7 @@ void Candidate::parse(string candidate) {
{"so", TransportType::TcpSo}}; {"so", TransportType::TcpSo}};
const std::array prefixes{"a=", "candidate:"}; const std::array prefixes{"a=", "candidate:"};
for (const string &prefix : prefixes) for (string prefix : prefixes)
if (match_prefix(candidate, prefix)) if (match_prefix(candidate, prefix))
candidate.erase(0, prefix.size()); candidate.erase(0, prefix.size());

View File

@ -980,18 +980,17 @@ std::ostream &operator<<(std::ostream &out, rtc::Description::Type type) {
std::ostream &operator<<(std::ostream &out, rtc::Description::Role role) { std::ostream &operator<<(std::ostream &out, rtc::Description::Role role) {
using Role = rtc::Description::Role; using Role = rtc::Description::Role;
const char *str;
// Used for SDP generation, do not change // Used for SDP generation, do not change
switch (role) { switch (role) {
case Role::Active: case Role::Active:
str = "active"; out << "active";
break; break;
case Role::Passive: case Role::Passive:
str = "passive"; out << "passive";
break; break;
default: default:
str = "actpass"; out << "actpass";
break; break;
} }
return out << str; return out;
} }

View File

@ -93,3 +93,31 @@ void Cleanup() { Init::Cleanup(); }
void SetSctpSettings(SctpSettings s) { Init::SetSctpSettings(std::move(s)); } void SetSctpSettings(SctpSettings s) { Init::SetSctpSettings(std::move(s)); }
} // namespace rtc } // namespace rtc
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::LogLevel level) {
switch (level) {
case rtc::LogLevel::Fatal:
out << "fatal";
break;
case rtc::LogLevel::Error:
out << "error";
break;
case rtc::LogLevel::Warning:
out << "warning";
break;
case rtc::LogLevel::Info:
out << "info";
break;
case rtc::LogLevel::Debug:
out << "debug";
break;
case rtc::LogLevel::Verbose:
out << "verbose";
break;
default:
out << "none";
break;
}
return out;
}

View File

@ -85,8 +85,30 @@ static LogCounter
static LogCounter COUNTER_BAD_SCTP_STATUS(plog::warning, static LogCounter COUNTER_BAD_SCTP_STATUS(plog::warning,
"Number of SCTP packets received with a bad status"); "Number of SCTP packets received with a bad status");
std::unordered_set<SctpTransport *> SctpTransport::Instances; class SctpTransport::InstancesSet {
std::shared_mutex SctpTransport::InstancesMutex; public:
void insert(SctpTransport *instance) {
std::unique_lock lock(mMutex);
mSet.insert(instance);
}
void erase(SctpTransport *instance) {
std::unique_lock lock(mMutex);
mSet.erase(instance);
}
using shared_lock = std::shared_lock<std::shared_mutex>;
optional<shared_lock> lock(SctpTransport *instance) {
shared_lock lock(mMutex);
return mSet.find(instance) != mSet.end() ? std::make_optional(std::move(lock)) : nullopt;
}
private:
std::unordered_set<SctpTransport *> mSet;
std::shared_mutex mMutex;
};
SctpTransport::InstancesSet *SctpTransport::Instances = new InstancesSet;
void SctpTransport::Init() { void SctpTransport::Init() {
usrsctp_init(0, &SctpTransport::WriteCallback, nullptr); usrsctp_init(0, &SctpTransport::WriteCallback, nullptr);
@ -143,10 +165,7 @@ SctpTransport::SctpTransport(shared_ptr<Transport> lower, const Configuration &c
PLOG_DEBUG << "Initializing SCTP transport"; PLOG_DEBUG << "Initializing SCTP transport";
usrsctp_register_address(this); usrsctp_register_address(this);
{ Instances->insert(this);
std::unique_lock lock(InstancesMutex);
Instances.insert(this);
}
mSock = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, nullptr, nullptr, 0, nullptr); mSock = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, nullptr, nullptr, 0, nullptr);
if (!mSock) if (!mSock)
@ -285,10 +304,7 @@ SctpTransport::~SctpTransport() {
close(); close();
usrsctp_deregister_address(this); usrsctp_deregister_address(this);
{ Instances->erase(this);
std::unique_lock lock(InstancesMutex);
Instances.erase(this);
}
} }
void SctpTransport::start() { void SctpTransport::start() {
@ -416,9 +432,6 @@ void SctpTransport::incoming(message_ptr message) {
PLOG_VERBOSE << "Incoming size=" << message->size(); PLOG_VERBOSE << "Incoming size=" << message->size();
// TODO: There seems to be a possible data race between usrsctp_sendv() and usrsctp_conninput()
// As a mitigation, lock the send mutex before calling usrsctp_conninput()
std::lock_guard lock(mSendMutex);
usrsctp_conninput(this, message->data(), message->size(), 0); usrsctp_conninput(this, message->data(), message->size(), 0);
} }
@ -851,10 +864,7 @@ optional<milliseconds> SctpTransport::rtt() {
void SctpTransport::UpcallCallback(struct socket *, void *arg, int /* flags */) { void SctpTransport::UpcallCallback(struct socket *, void *arg, int /* flags */) {
auto *transport = static_cast<SctpTransport *>(arg); auto *transport = static_cast<SctpTransport *>(arg);
std::shared_lock lock(InstancesMutex); if(auto lock = Instances->lock(transport))
if (Instances.find(transport) == Instances.end())
return;
transport->handleUpcall(); transport->handleUpcall();
} }
@ -863,11 +873,10 @@ int SctpTransport::WriteCallback(void *ptr, void *data, size_t len, uint8_t tos,
// Workaround for sctplab/usrsctp#405: Send callback is invoked on already closed socket // Workaround for sctplab/usrsctp#405: Send callback is invoked on already closed socket
// https://github.com/sctplab/usrsctp/issues/405 // https://github.com/sctplab/usrsctp/issues/405
std::shared_lock lock(InstancesMutex); if(auto lock = Instances->lock(transport))
if (Instances.find(transport) == Instances.end())
return -1;
return transport->handleWrite(static_cast<byte *>(data), len, tos, set_df); return transport->handleWrite(static_cast<byte *>(data), len, tos, set_df);
else
return -1;
} }
} // namespace rtc::impl } // namespace rtc::impl

View File

@ -120,8 +120,8 @@ private:
static void UpcallCallback(struct socket *sock, void *arg, int flags); static void UpcallCallback(struct socket *sock, void *arg, int flags);
static int WriteCallback(void *sctp_ptr, void *data, size_t len, uint8_t tos, uint8_t set_df); static int WriteCallback(void *sctp_ptr, void *data, size_t len, uint8_t tos, uint8_t set_df);
static std::unordered_set<SctpTransport *> Instances; class InstancesSet;
static std::shared_mutex InstancesMutex; static InstancesSet *Instances;
}; };
} // namespace rtc::impl } // namespace rtc::impl