multiplex: add socket factory

This commit is contained in:
Heikki Tampio 2023-04-03 11:48:14 +03:00
parent 1311cd777b
commit ae6726731c
5 changed files with 145 additions and 1 deletions

View File

@ -68,6 +68,7 @@ target_sources(${PROJECT_NAME} PRIVATE
src/srtp/srtp.cc
src/srtp/srtcp.cc
src/wrapper_c.cc
src/socketfactory.cc
)
source_group(src/srtp src/srtp/.*)
@ -118,6 +119,7 @@ target_sources(${PROJECT_NAME} PRIVATE
src/srtp/base.hh
src/srtp/srtp.hh
src/srtp/srtcp.hh
src/socketfactory.hh
include/uvgrtp/util.hh
include/uvgrtp/clock.hh

View File

@ -12,6 +12,7 @@ namespace uvgrtp {
class media_stream;
class zrtp;
class socketfactory;
/** \brief Provides ZRTP synchronization and can be used to create uvgrtp::media_stream objects
*
@ -61,6 +62,9 @@ namespace uvgrtp {
*/
uvgrtp::media_stream *create_stream(uint16_t src_port, uint16_t dst_port, rtp_format_t fmt, int rce_flags);
// socket factory, add docs
uvgrtp::media_stream* create_stream(uint16_t src_port, uint16_t dst_port, rtp_format_t fmt, int rce_flags, uvgrtp::socketfactory sf);
/**
* \brief Create a unidirectional media_stream for an RTP session
*

View File

@ -1,7 +1,7 @@
#include "uvgrtp/session.hh"
#include "uvgrtp/media_stream.hh"
#include "socketfactory.hh"
#include "crypto.hh"
#include "zrtp.hh"
#include "debug.hh"
@ -163,6 +163,122 @@ uvgrtp::media_stream* uvgrtp::session::create_stream(uint16_t src_port, uint16_t
return stream;
}
uvgrtp::media_stream* uvgrtp::session::create_stream(uint16_t src_port, uint16_t dst_port, rtp_format_t fmt, int rce_flags, uvgrtp::socketfactory sf)
{
if (rce_flags & RCE_OBSOLETE) {
UVG_LOG_WARN("You are using a flag that has either been removed or has been enabled by default. Consider updating RCE flags");
}
if ((rce_flags & RCE_SEND_ONLY) && (rce_flags & RCE_RECEIVE_ONLY)) {
UVG_LOG_ERROR("Cannot both use RCE_SEND_ONLY and RCE_RECEIVE_ONLY!");
rtp_errno = RTP_NOT_SUPPORTED;
return nullptr;
}
// select which address the one address we got as a parameter is
if (generic_address_ != "")
{
if (rce_flags & RCE_RECEIVE_ONLY)
{
local_address_ = generic_address_;
}
else
{
remote_address_ = generic_address_;
}
}
else if ((rce_flags & RCE_RECEIVE_ONLY) && local_address_ == "")
{
UVG_LOG_ERROR("RCE_RECEIVE_ONLY requires local address!");
rtp_errno = RTP_INVALID_VALUE;
return nullptr;
}
else if ((rce_flags & RCE_SEND_ONLY) && remote_address_ == "")
{
UVG_LOG_ERROR("RCE_SEND_ONLY requires remote address!");
rtp_errno = RTP_INVALID_VALUE;
return nullptr;
}
if ((rce_flags & RCE_RECEIVE_ONLY) && src_port == 0)
{
UVG_LOG_ERROR("RCE_RECEIVE_ONLY requires source port!");
rtp_errno = RTP_INVALID_VALUE;
return nullptr;
}
if ((rce_flags & RCE_SEND_ONLY) && dst_port == 0)
{
UVG_LOG_ERROR("RCE_SEND_ONLY requires destination port!");
rtp_errno = RTP_INVALID_VALUE;
return nullptr;
}
uvgrtp::media_stream* stream =
new uvgrtp::media_stream(cname_, remote_address_, local_address_, src_port, dst_port, fmt, rce_flags);
if (rce_flags & RCE_SRTP) {
if (!uvgrtp::crypto::enabled()) {
UVG_LOG_ERROR("Recompile uvgRTP with -D__RTP_CRYPTO__");
delete stream;
rtp_errno = RTP_GENERIC_ERROR;
return nullptr;
}
if (rce_flags & RCE_SRTP_REPLAY_PROTECTION)
rce_flags |= RCE_SRTP_AUTHENTICATE_RTP;
if (rce_flags & RCE_SRTP_KMNGMNT_ZRTP) {
if (rce_flags & (RCE_SRTP_KEYSIZE_192 | RCE_SRTP_KEYSIZE_256)) {
UVG_LOG_ERROR("Only 128-bit keys are supported with ZRTP");
delete stream;
return nullptr;
}
if (!(rce_flags & RCE_ZRTP_DIFFIE_HELLMAN_MODE) &&
!(rce_flags & RCE_ZRTP_MULTISTREAM_MODE)) {
UVG_LOG_INFO("ZRTP mode not selected, using Diffie-Hellman mode");
rce_flags |= RCE_ZRTP_DIFFIE_HELLMAN_MODE;
}
session_mtx_.lock();
if (!zrtp_) {
zrtp_ = std::shared_ptr<uvgrtp::zrtp>(new uvgrtp::zrtp());
}
session_mtx_.unlock();
if (stream->init(zrtp_) != RTP_OK) {
UVG_LOG_ERROR("Failed to initialize media stream %s:%d/%d", remote_address_.c_str(), src_port, dst_port);
delete stream;
return nullptr;
}
}
else if (rce_flags & RCE_SRTP_KMNGMNT_USER) {
UVG_LOG_DEBUG("SRTP with user-managed keys enabled, postpone initialization");
}
else {
UVG_LOG_ERROR("SRTP key management scheme not specified!");
rtp_errno = RTP_INVALID_VALUE;
delete stream;
return nullptr;
}
}
else {
if (stream->init() != RTP_OK) {
UVG_LOG_ERROR("Failed to initialize media stream %s:%d/%d", remote_address_.c_str(), src_port, dst_port);
delete stream;
return nullptr;
}
}
session_mtx_.lock();
streams_.insert(std::make_pair(stream->get_key(), stream));
session_mtx_.unlock();
return stream;
}
rtp_error_t uvgrtp::session::destroy_stream(uvgrtp::media_stream *stream)
{
if (!stream)

4
src/socketfactory.cc Normal file
View File

@ -0,0 +1,4 @@
#include "socketfactory.hh"
uvgrtp::socketfactory::socketfactory()
{}

18
src/socketfactory.hh Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "uvgrtp/util.hh"
#include <string>
namespace uvgrtp {
class socketfactory {
public:
socketfactory();
private:
std::string local_address_;
uint16_t local_port_;
};
}