multiplex: Multicast receiver streams get a new socket by default, even with multiplexing

This commit is contained in:
Heikki Tampio 2023-05-09 14:44:39 +03:00
parent a3ca6dd2c7
commit c31190cd80
4 changed files with 45 additions and 15 deletions

View File

@ -71,10 +71,11 @@ uvgrtp::media_stream::~media_stream()
{
reception_flow_->stop();
}
/*
if (sfp_)
{
sfp_->stop();
}
}*/
// TODO: I would take a close look at what happens when pull_frame is called
// and media stream is destroyed. Note that this is the only way to stop pull
@ -93,30 +94,55 @@ rtp_error_t uvgrtp::media_stream::init_connection()
rtp_error_t ret = RTP_GENERIC_ERROR;
ipv6_ = sfp_->get_ipv6();
// First check if the given address is a multicast address. If it is, it automatically gets its own socket,
// regardless of any socket multiplexing measures
sockaddr_in6 multicast_sockaddr6_;
sockaddr_in multicast_sockaddr_;
bool multicast = false;
if (ipv6_ && src_port_ != 0 && local_address_ != "") {
multicast_sockaddr6_ = uvgrtp::socket::create_ip6_sockaddr(local_address_, src_port_);
if (uvgrtp::socket::is_multicast(multicast_sockaddr6_)) {
socket_ = sfp_->create_new_socket();
new_socket_ = true;
multicast = true;
}
}
else if (src_port_ != 0 && local_address_ != "") {
multicast_sockaddr_ = uvgrtp::socket::create_sockaddr(AF_INET, local_address_, src_port_);
if (uvgrtp::socket::is_multicast(multicast_sockaddr_)) {
socket_ = sfp_->create_new_socket();
new_socket_ = true;
multicast = true;
}
}
// If the given local address is not a multicast address, either create a new socket or fetch the existing
// socket if socket multiplexing is used
// Source port is given and is not in use -> create new socket
if (src_port_ != 0 && !sfp_->is_port_in_use(src_port_)) {
if (!multicast && src_port_ != 0 && !sfp_->is_port_in_use(src_port_)) {
socket_ = sfp_->create_new_socket();
new_socket_ = true;
}
// Source port is in use -> fetch the existing socket
else {
else if (!multicast) {
socket_ = sfp_->get_socket_ptr(src_port_);
if (!socket_) {
socket_ = sfp_->create_new_socket();
new_socket_ = true;
}
}
holepuncher_ = std::unique_ptr<uvgrtp::holepuncher>(new uvgrtp::holepuncher(socket_));
holepuncher_ = std::unique_ptr<uvgrtp::holepuncher>(new uvgrtp::holepuncher(socket_));
if (!(rce_flags_ & RCE_RECEIVE_ONLY) && remote_address_ != "" && dst_port_ != 0)
{
// no reason to fail sending even if binding fails so we set remote address first
if (ipv6_) {
remote_sockaddr_ip6_ = socket_->create_ip6_sockaddr(remote_address_, dst_port_);
remote_sockaddr_ip6_ = uvgrtp::socket::create_ip6_sockaddr(remote_address_, dst_port_);
}
else {
remote_sockaddr_ = socket_->create_sockaddr(AF_INET, remote_address_, dst_port_);
remote_sockaddr_ = uvgrtp::socket::create_sockaddr(AF_INET, remote_address_, dst_port_);
}
holepuncher_->set_remote_address(remote_sockaddr_, remote_sockaddr_ip6_);
}

View File

@ -38,6 +38,10 @@ uvgrtp::session::~session()
for (auto&i : streams_) {
(void)destroy_stream(i.second);
}
if (sf_)
{
sf_->stop();
}
streams_.clear();
sf_ = nullptr;
}

View File

@ -270,7 +270,7 @@ int uvgrtp::socket::check_family(std::string addr)
return -1;
}
sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short port) const
sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short port)
{
assert(family == AF_INET);
@ -285,7 +285,7 @@ sockaddr_in uvgrtp::socket::create_sockaddr(short family, unsigned host, short p
return addr;
}
sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, short port) const
sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, short port)
{
assert(family == AF_INET);
@ -301,7 +301,7 @@ sockaddr_in uvgrtp::socket::create_sockaddr(short family, std::string host, shor
}
// This function seems to not be currently used anywhere
sockaddr_in6 uvgrtp::socket::create_ip6_sockaddr(unsigned host, short port) const
sockaddr_in6 uvgrtp::socket::create_ip6_sockaddr(unsigned host, short port)
{
sockaddr_in6 addr;
@ -315,7 +315,7 @@ sockaddr_in6 uvgrtp::socket::create_ip6_sockaddr(unsigned host, short port) cons
return addr;
}
sockaddr_in6 uvgrtp::socket::create_ip6_sockaddr(std::string host, short port) const
sockaddr_in6 uvgrtp::socket::create_ip6_sockaddr(std::string host, short port)
{
sockaddr_in6 addr;
memset(&addr, 0, sizeof(addr));

View File

@ -146,16 +146,16 @@ namespace uvgrtp {
/* Create sockaddr_in (IPv4) object using the provided information
* NOTE: "family" must be AF_INET */
sockaddr_in create_sockaddr(short family, unsigned host, short port) const;
static sockaddr_in create_sockaddr(short family, unsigned host, short port);
/* Create sockaddr_in object using the provided information
* NOTE: "family" must be AF_INET */
sockaddr_in create_sockaddr(short family, std::string host, short port) const;
static sockaddr_in create_sockaddr(short family, std::string host, short port);
/* Create sockaddr_in6 (IPv6) object using the provided information */
sockaddr_in6 create_ip6_sockaddr(unsigned host, short port) const;
sockaddr_in6 create_ip6_sockaddr(std::string host, short port) const;
sockaddr_in6 create_ip6_sockaddr_any(short src_port);
static sockaddr_in6 create_ip6_sockaddr(unsigned host, short port);
static sockaddr_in6 create_ip6_sockaddr(std::string host, short port);
static sockaddr_in6 create_ip6_sockaddr_any(short src_port);
std::string get_socket_path_string() const;