Split include.hpp

This commit is contained in:
Paul-Louis Ageneau
2021-02-28 14:32:59 +01:00
parent 7880d31126
commit 54d0cb898d
20 changed files with 214 additions and 163 deletions

View File

@ -40,6 +40,7 @@
#endif #endif
#include "log.hpp" #include "log.hpp"
#include "utils.hpp"
#include <cstddef> #include <cstddef>
#include <functional> #include <functional>
@ -52,13 +53,13 @@
namespace rtc { namespace rtc {
using std::nullopt;
using std::byte; using std::byte;
using std::nullopt;
using std::shared_ptr;
using std::string; using std::string;
using std::string_view; using std::string_view;
using std::shared_ptr;
using std::weak_ptr;
using std::unique_ptr; using std::unique_ptr;
using std::weak_ptr;
using binary = std::vector<byte>; using binary = std::vector<byte>;
using binary_ptr = std::shared_ptr<binary>; using binary_ptr = std::shared_ptr<binary>;
@ -69,117 +70,6 @@ using std::uint32_t;
using std::uint64_t; using std::uint64_t;
using std::uint8_t; using std::uint8_t;
const size_t MAX_NUMERICNODE_LEN = 48; // Max IPv6 string representation length
const size_t MAX_NUMERICSERV_LEN = 6; // Max port string representation length
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
const size_t DEFAULT_MAX_MESSAGE_SIZE = 65536; // Remote max message size if not specified in SDP
const size_t LOCAL_MAX_MESSAGE_SIZE = 256 * 1024; // Local max message size
const size_t RECV_QUEUE_LIMIT = 1024 * 1024; // Max per-channel queue size
const int THREADPOOL_SIZE = 4; // Number of threads in the global thread pool
const size_t DEFAULT_IPV4_MTU = 1200; // IPv4 safe MTU value recommended by RFC 8261
// overloaded helper
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// weak_ptr bind helper
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) {
using result_type = typename decltype(bound)::result_type;
if (auto shared_this = weak_this.lock())
return bound(args...);
else
return static_cast<result_type>(false);
};
}
// scope_guard helper
class scope_guard {
public:
scope_guard(std::function<void()> func) : function(std::move(func)) {}
scope_guard(scope_guard &&other) = delete;
scope_guard(const scope_guard &) = delete;
void operator=(const scope_guard &) = delete;
~scope_guard() {
if (function)
function();
}
private:
std::function<void()> function;
};
// callback with built-in synchronization
template <typename... Args> class synchronized_callback {
public:
synchronized_callback() = default;
synchronized_callback(synchronized_callback &&cb) { *this = std::move(cb); }
synchronized_callback(const synchronized_callback &cb) { *this = cb; }
synchronized_callback(std::function<void(Args...)> func) { *this = std::move(func); }
~synchronized_callback() { *this = nullptr; }
synchronized_callback &operator=(synchronized_callback &&cb) {
std::scoped_lock lock(mutex, cb.mutex);
callback = std::move(cb.callback);
cb.callback = nullptr;
return *this;
}
synchronized_callback &operator=(const synchronized_callback &cb) {
std::scoped_lock lock(mutex, cb.mutex);
callback = cb.callback;
return *this;
}
synchronized_callback &operator=(std::function<void(Args...)> func) {
std::lock_guard lock(mutex);
callback = std::move(func);
return *this;
}
void operator()(Args... args) const {
std::lock_guard lock(mutex);
if (callback)
callback(std::move(args)...);
}
operator bool() const {
std::lock_guard lock(mutex);
return callback ? true : false;
}
std::function<void(Args...)> wrap() const {
return [this](Args... args) { (*this)(std::move(args)...); };
}
private:
std::function<void(Args...)> callback;
mutable std::recursive_mutex mutex;
};
// pimpl base class
template<typename T> using impl_ptr = std::shared_ptr<T>;
template <typename T> class CheshireCat {
public:
CheshireCat(impl_ptr<T> impl) : mImpl(std::move(impl)) {}
template <typename... Args>
CheshireCat(Args... args) : mImpl(std::make_shared<T>(std::move(args)...)) {}
virtual ~CheshireCat() = default;
protected:
impl_ptr<T> impl() { return mImpl; }
impl_ptr<const T> impl() const { return mImpl; }
private:
impl_ptr<T> mImpl;
};
} // namespace rtc } // namespace rtc
#endif #endif

128
include/rtc/utils.hpp Normal file
View File

@ -0,0 +1,128 @@
/**
* Copyright (c) 2019-2021 Paul-Louis Ageneau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef RTC_UTILS_H
#define RTC_UTILS_H
#include <functional>
#include <memory>
#include <mutex>
namespace rtc {
// overloaded helper
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
// weak_ptr bind helper
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) {
using result_type = typename decltype(bound)::result_type;
if (auto shared_this = weak_this.lock())
return bound(args...);
else
return static_cast<result_type>(false);
};
}
// scope_guard helper
class scope_guard {
public:
scope_guard(std::function<void()> func) : function(std::move(func)) {}
scope_guard(scope_guard &&other) = delete;
scope_guard(const scope_guard &) = delete;
void operator=(const scope_guard &) = delete;
~scope_guard() {
if (function)
function();
}
private:
std::function<void()> function;
};
// callback with built-in synchronization
template <typename... Args> class synchronized_callback {
public:
synchronized_callback() = default;
synchronized_callback(synchronized_callback &&cb) { *this = std::move(cb); }
synchronized_callback(const synchronized_callback &cb) { *this = cb; }
synchronized_callback(std::function<void(Args...)> func) { *this = std::move(func); }
~synchronized_callback() { *this = nullptr; }
synchronized_callback &operator=(synchronized_callback &&cb) {
std::scoped_lock lock(mutex, cb.mutex);
callback = std::move(cb.callback);
cb.callback = nullptr;
return *this;
}
synchronized_callback &operator=(const synchronized_callback &cb) {
std::scoped_lock lock(mutex, cb.mutex);
callback = cb.callback;
return *this;
}
synchronized_callback &operator=(std::function<void(Args...)> func) {
std::lock_guard lock(mutex);
callback = std::move(func);
return *this;
}
void operator()(Args... args) const {
std::lock_guard lock(mutex);
if (callback)
callback(std::move(args)...);
}
operator bool() const {
std::lock_guard lock(mutex);
return callback ? true : false;
}
std::function<void(Args...)> wrap() const {
return [this](Args... args) { (*this)(std::move(args)...); };
}
private:
std::function<void(Args...)> callback;
mutable std::recursive_mutex mutex;
};
// pimpl base class
template <typename T> using impl_ptr = std::shared_ptr<T>;
template <typename T> class CheshireCat {
public:
CheshireCat(impl_ptr<T> impl) : mImpl(std::move(impl)) {}
template <typename... Args>
CheshireCat(Args... args) : mImpl(std::make_shared<T>(std::move(args)...)) {}
virtual ~CheshireCat() = default;
protected:
impl_ptr<T> impl() { return mImpl; }
impl_ptr<const T> impl() const { return mImpl; }
private:
impl_ptr<T> mImpl;
};
} // namespace rtc
#endif

View File

@ -17,6 +17,7 @@
*/ */
#include "candidate.hpp" #include "candidate.hpp"
#include "globals.hpp"
#include <algorithm> #include <algorithm>
#include <array> #include <array>

View File

@ -43,8 +43,6 @@
using namespace rtc; using namespace rtc;
using std::optional; using std::optional;
using std::shared_ptr;
using std::string;
using std::chrono::milliseconds; using std::chrono::milliseconds;
namespace { namespace {

View File

@ -17,6 +17,7 @@
*/ */
#include "channel.hpp" #include "channel.hpp"
#include "globals.hpp"
#include "impl/channel.hpp" #include "impl/channel.hpp"

View File

@ -17,6 +17,7 @@
*/ */
#include "datachannel.hpp" #include "datachannel.hpp"
#include "globals.hpp"
#include "include.hpp" #include "include.hpp"
#include "peerconnection.hpp" #include "peerconnection.hpp"

View File

@ -28,7 +28,6 @@
#include <sstream> #include <sstream>
#include <unordered_map> #include <unordered_map>
using std::shared_ptr;
using std::chrono::system_clock; using std::chrono::system_clock;
namespace { namespace {

41
src/globals.hpp Normal file
View File

@ -0,0 +1,41 @@
/**
* Copyright (c) 2019-2021 Paul-Louis Ageneau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef RTC_GLOBALS_H
#define RTC_GLOBALS_H
#include "include.hpp"
namespace rtc {
const size_t MAX_NUMERICNODE_LEN = 48; // Max IPv6 string representation length
const size_t MAX_NUMERICSERV_LEN = 6; // Max port string representation length
const uint16_t DEFAULT_SCTP_PORT = 5000; // SCTP port to use by default
const size_t DEFAULT_MAX_MESSAGE_SIZE = 65536; // Remote max message size if not specified in SDP
const size_t LOCAL_MAX_MESSAGE_SIZE = 256 * 1024; // Local max message size
const size_t RECV_QUEUE_LIMIT = 1024 * 1024; // Max per-channel queue size
const int THREADPOOL_SIZE = 4; // Number of threads in the global thread pool (>= 2)
const size_t DEFAULT_IPV4_MTU = 1200; // IPv4 safe MTU value recommended by RFC 8261
} // namespace rtc
#endif

View File

@ -22,9 +22,6 @@
namespace rtc { namespace rtc {
using std::make_shared;
using std::shared_ptr;
typedef enum { typedef enum {
NUSM_noMatch, NUSM_noMatch,
NUSM_firstZero, NUSM_firstZero,
@ -74,7 +71,7 @@ NalUnitStartSequenceMatch StartSequenceMatchSucc(NalUnitStartSequenceMatch match
} }
shared_ptr<NalUnits> H264RtpPacketizer::splitMessage(binary_ptr message) { shared_ptr<NalUnits> H264RtpPacketizer::splitMessage(binary_ptr message) {
auto nalus = make_shared<NalUnits>(); auto nalus = std::make_shared<NalUnits>();
if (separator == Separator::Length) { if (separator == Separator::Length) {
unsigned long long index = 0; unsigned long long index = 0;
while (index < message->size()) { while (index < message->size()) {

View File

@ -17,6 +17,7 @@
*/ */
#include "datachannel.hpp" #include "datachannel.hpp"
#include "globals.hpp"
#include "include.hpp" #include "include.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
#include "peerconnection.hpp" #include "peerconnection.hpp"

View File

@ -17,6 +17,7 @@
*/ */
#include "dtlstransport.hpp" #include "dtlstransport.hpp"
#include "globals.hpp"
#include "icetransport.hpp" #include "icetransport.hpp"
#include <chrono> #include <chrono>
@ -34,11 +35,6 @@
using namespace std::chrono; using namespace std::chrono;
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::weak_ptr;
namespace rtc::impl { namespace rtc::impl {
#if USE_GNUTLS #if USE_GNUTLS
@ -597,4 +593,4 @@ long DtlsTransport::BioMethodCtrl(BIO * /*bio*/, int cmd, long /*num*/, void * /
#endif #endif
} // namespace rtc } // namespace rtc::impl

View File

@ -20,6 +20,7 @@
#include "peerconnection.hpp" #include "peerconnection.hpp"
#include "certificate.hpp" #include "certificate.hpp"
#include "dtlstransport.hpp" #include "dtlstransport.hpp"
#include "globals.hpp"
#include "icetransport.hpp" #include "icetransport.hpp"
#include "include.hpp" #include "include.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
@ -63,7 +64,8 @@ static LogCounter
"Number of unknown RTCP packet types over past second"); "Number of unknown RTCP packet types over past second");
PeerConnection::PeerConnection(Configuration config_) PeerConnection::PeerConnection(Configuration config_)
: config(std::move(config_)), mCertificate(make_certificate()), mProcessor(std::make_unique<Processor>()) { : config(std::move(config_)), mCertificate(make_certificate()),
mProcessor(std::make_unique<Processor>()) {
PLOG_VERBOSE << "Creating PeerConnection"; PLOG_VERBOSE << "Creating PeerConnection";
if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd) if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd)
@ -181,32 +183,32 @@ 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 = [this, auto stateChangeCallback =
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)
return; return;
switch (transportState) { switch (transportState) {
case DtlsTransport::State::Connected: case DtlsTransport::State::Connected:
if (auto remote = remoteDescription(); remote && remote->hasApplication()) if (auto remote = remoteDescription(); remote && remote->hasApplication())
initSctpTransport(); initSctpTransport();
else else
changeState(State::Connected); changeState(State::Connected);
mProcessor->enqueue(&PeerConnection::openTracks, this); mProcessor->enqueue(&PeerConnection::openTracks, this);
break; break;
case DtlsTransport::State::Failed: case DtlsTransport::State::Failed:
changeState(State::Failed); changeState(State::Failed);
break; break;
case DtlsTransport::State::Disconnected: case DtlsTransport::State::Disconnected:
changeState(State::Disconnected); changeState(State::Disconnected);
break; break;
default: default:
// Ignore // Ignore
break; break;
} }
}; };
shared_ptr<DtlsTransport> transport; shared_ptr<DtlsTransport> transport;
if (auto local = localDescription(); local && local->hasAudioOrVideo()) { if (auto local = localDescription(); local && local->hasAudioOrVideo()) {

View File

@ -18,6 +18,7 @@
#include "sctptransport.hpp" #include "sctptransport.hpp"
#include "dtlstransport.hpp" #include "dtlstransport.hpp"
#include "globals.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
#include <chrono> #include <chrono>
@ -808,4 +809,4 @@ int SctpTransport::WriteCallback(void *ptr, void *data, size_t len, uint8_t tos,
return transport->handleWrite(static_cast<byte *>(data), len, tos, set_df); return transport->handleWrite(static_cast<byte *>(data), len, tos, set_df);
} }
} // namespace rtc } // namespace rtc::impl

View File

@ -17,6 +17,7 @@
*/ */
#include "tcptransport.hpp" #include "tcptransport.hpp"
#include "globals.hpp"
#if RTC_ENABLE_WEBSOCKET #if RTC_ENABLE_WEBSOCKET

View File

@ -28,11 +28,6 @@
using namespace std::chrono; using namespace std::chrono;
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::weak_ptr;
namespace rtc::impl { namespace rtc::impl {
#if USE_GNUTLS #if USE_GNUTLS

View File

@ -17,6 +17,7 @@
*/ */
#include "track.hpp" #include "track.hpp"
#include "globals.hpp"
#include "logcounter.hpp" #include "logcounter.hpp"
namespace rtc::impl { namespace rtc::impl {

View File

@ -21,11 +21,6 @@
#if RTC_ENABLE_WEBSOCKET #if RTC_ENABLE_WEBSOCKET
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::weak_ptr;
namespace rtc::impl { namespace rtc::impl {
VerifiedTlsTransport::VerifiedTlsTransport(shared_ptr<TcpTransport> lower, string host, VerifiedTlsTransport::VerifiedTlsTransport(shared_ptr<TcpTransport> lower, string host,

View File

@ -19,6 +19,7 @@
#if RTC_ENABLE_WEBSOCKET #if RTC_ENABLE_WEBSOCKET
#include "websocket.hpp" #include "websocket.hpp"
#include "globals.hpp"
#include "include.hpp" #include "include.hpp"
#include "threadpool.hpp" #include "threadpool.hpp"

View File

@ -17,6 +17,7 @@
*/ */
#include "init.hpp" #include "init.hpp"
#include "globals.hpp"
#include "impl/certificate.hpp" #include "impl/certificate.hpp"
#include "impl/dtlstransport.hpp" #include "impl/dtlstransport.hpp"

View File

@ -19,6 +19,7 @@
#if RTC_ENABLE_WEBSOCKET #if RTC_ENABLE_WEBSOCKET
#include "websocket.hpp" #include "websocket.hpp"
#include "globals.hpp"
#include "include.hpp" #include "include.hpp"
#include "impl/websocket.hpp" #include "impl/websocket.hpp"