Skip to content

Commit

Permalink
ListenInfo: Ignore given socket flags if not suitable for given IP fa…
Browse files Browse the repository at this point in the history
…mily or transport

For example, by design `libuv` will throw if a IPv4 socket is created with flag `UV_UDP_IPV6ONLY` or `UV_TCP_IPV6ONLY`.
  • Loading branch information
ibc committed Jan 3, 2024
1 parent 2d98c72 commit 2aaad62
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

* Avoid modification of user input data ([PR #1285](https://github.com/versatica/mediasoup/pull/1285)).
* `ListenInfo`: Add transport socket flags ([PR #1291](https://github.com/versatica/mediasoup/pull/1291)).
* `ListenInfo`: Ignore given socket flags if not suitable for given IP family or transport ([PR #1294](https://github.com/versatica/mediasoup/pull/1294)).
* Meson: Remove `-Db_pie=true -Db_staticpic=true` args ([PR #1293](https://github.com/versatica/mediasoup/pull/1293)).
* Add RTCP Sender Report trace event ([PR #1267](https://github.com/versatica/mediasoup/pull/1267) by @GithubUser8080).

Expand Down
3 changes: 2 additions & 1 deletion node/src/tests/test-PlainTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ if (!IS_WINDOWS)
protocol : 'udp',
ip : multicastIp,
port : port,
flags : { udpReusePort: true }
// NOTE: ipv6Only flag will be ignored since ip is IPv4.
flags : { udpReusePort: true, ipv6Only: true }
}
});

Expand Down
8 changes: 6 additions & 2 deletions node/src/tests/test-WebRtcTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,10 +641,14 @@ test('WebRtcTransport methods reject if closed', async () =>
test('router.createWebRtcTransport() with fixed port succeeds', async () =>
{

const port = await pickPort({ ip: '127.0.0.1', reserveTimeout: 0 });
const port = await pickPort({ type: 'tcp', ip: '127.0.0.1', reserveTimeout: 0 });
const webRtcTransport = await router.createWebRtcTransport(
{
listenInfos : [ { protocol: 'udp', ip: '127.0.0.1', port } ]
listenInfos :
[
// NOTE: udpReusePort flag will be ignored since protocol is TCP.
{ protocol: 'tcp', ip: '127.0.0.1', port, flags: { udpReusePort: true } }
]
});

expect(webRtcTransport.iceCandidates[0].port).toEqual(port);
Expand Down
3 changes: 2 additions & 1 deletion rust/tests/integration/plain_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,9 @@ fn create_two_transports_binding_to_same_ip_port_with_udp_reuse_port_flag_succee
ip: multicast_ip,
announced_ip: None,
port: Some(port),
// NOTE: ipv6Only flag will be ignored since ip is IPv4.
flags: Some(SocketFlags {
ipv6_only: false,
ipv6_only: true,
udp_reuse_port: true,
}),
send_buffer_size: None,
Expand Down
3 changes: 2 additions & 1 deletion worker/include/RTC/PortManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ namespace RTC
Transport transport, std::string& ip, uint16_t port, RTC::Transport::SocketFlags& flags);
static void Unbind(Transport transport, std::string& ip, uint16_t port);
static std::vector<bool>& GetPorts(Transport transport, const std::string& ip);
static uint8_t ConvertSocketFlags(RTC::Transport::SocketFlags& flags);
static uint8_t ConvertSocketFlags(
RTC::Transport::SocketFlags& flags, Transport transport, int family);

private:
thread_local static absl::flat_hash_map<std::string, std::vector<bool>> mapUdpIpPorts;
Expand Down
33 changes: 25 additions & 8 deletions worker/src/RTC/PortManager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#define MS_CLASS "RTC::PortManager"
#define MS_CLASS "PortManager"
// #define MS_LOG_DEV_LEVEL 3

#include "RTC/PortManager.hpp"
Expand Down Expand Up @@ -55,7 +55,7 @@ namespace RTC
uv_handle_t* uvHandle{ nullptr };
uint16_t port;
std::string transportStr;
uint8_t bitFlags = ConvertSocketFlags(flags);
uint8_t bitFlags = ConvertSocketFlags(flags, transport, family);

switch (transport)
{
Expand Down Expand Up @@ -378,7 +378,7 @@ namespace RTC
struct sockaddr_storage bindAddr; // NOLINT(cppcoreguidelines-pro-type-member-init)
uv_handle_t* uvHandle{ nullptr };
std::string transportStr;
uint8_t bitFlags = ConvertSocketFlags(flags);
uint8_t bitFlags = ConvertSocketFlags(flags, transport, family);

switch (transport)
{
Expand Down Expand Up @@ -692,19 +692,36 @@ namespace RTC
return emptyPorts;
}

uint8_t PortManager::ConvertSocketFlags(RTC::Transport::SocketFlags& flags)
uint8_t PortManager::ConvertSocketFlags(
RTC::Transport::SocketFlags& flags, Transport transport, int family)
{
MS_TRACE();

uint8_t bitFlags{ 0b00000000 };

if (flags.ipv6Only)
// Ignore ipv6Only in IPv4, otherwise libuv will throw.
if (flags.ipv6Only && family == AF_INET6)
{
bitFlags |= UV_UDP_IPV6ONLY;
bitFlags |= UV_TCP_IPV6ONLY; // Same flag number but anyway.
switch (transport)
{
case Transport::UDP:
{
bitFlags |= UV_UDP_IPV6ONLY;

break;
}

case Transport::TCP:
{
bitFlags |= UV_TCP_IPV6ONLY;

break;
}
}
}

if (flags.udpReusePort)
// Ignore udpReusePort in TCP, otherwise libuv will throw.
if (flags.udpReusePort && transport == Transport::UDP)
{
bitFlags |= UV_UDP_REUSEADDR;
}
Expand Down

0 comments on commit 2aaad62

Please sign in to comment.