diff --git a/node/src/PlainTransport.ts b/node/src/PlainTransport.ts index 423a6851081..baa3810fb57 100644 --- a/node/src/PlainTransport.ts +++ b/node/src/PlainTransport.ts @@ -109,7 +109,8 @@ export type PlainTransportOptions = diff --git a/node/src/Router.ts b/node/src/Router.ts index 224a33f4533..824e5c67b96 100644 --- a/node/src/Router.ts +++ b/node/src/Router.ts @@ -727,11 +727,6 @@ export class Router }; } - if (enableMulticast) - { - logger.debug('createPlainTransport() | enableMulticast'); - } - const transportId = generateUUIDv4(); /* Build Request. */ diff --git a/node/src/tests/test-PlainTransport.ts b/node/src/tests/test-PlainTransport.ts index 05f78499b4c..dcb1592f55c 100644 --- a/node/src/tests/test-PlainTransport.ts +++ b/node/src/tests/test-PlainTransport.ts @@ -318,14 +318,21 @@ test('router.createPlainTransport() with non bindable IP rejects with Error', as test('router.createPlainTransport() with enableMulticast succeeds', async () => { - // Use default cryptoSuite: 'AES_CM_128_HMAC_SHA1_80'. - const transport1 = await router.createPlainTransport( - { - listenIp : '127.0.0.1', - enableMulticast: true - }); + let transport1: mediasoup.types.PlainTransport; - expect(typeof transport1.id).toBe('string'); + await expect(async () => + { + transport1 = await router.createPlainTransport( + { + listenIp : '127.0.0.1', + enableMulticast : true + }); + }).not.toThrow(); + + if (transport1) + { + transport1.close(); + } }, 2000); test('plainTransport.getStats() succeeds', async () => diff --git a/rust/src/messages.rs b/rust/src/messages.rs index 1eb50f46ccb..89ddd6dc974 100644 --- a/rust/src/messages.rs +++ b/rust/src/messages.rs @@ -911,6 +911,7 @@ pub(crate) struct RouterCreatePlainTransportData { sctp_send_buffer_size: u32, enable_srtp: bool, srtp_crypto_suite: SrtpCryptoSuite, + enable_multicast: bool, is_data_channel: bool, } @@ -931,6 +932,7 @@ impl RouterCreatePlainTransportData { sctp_send_buffer_size: plain_transport_options.sctp_send_buffer_size, enable_srtp: plain_transport_options.enable_srtp, srtp_crypto_suite: plain_transport_options.srtp_crypto_suite, + enable_multicast: plain_transport_options.enable_multicast, is_data_channel: false, } } @@ -955,6 +957,7 @@ impl RouterCreatePlainTransportData { comedia: self.comedia, enable_srtp: self.enable_srtp, srtp_crypto_suite: Some(SrtpCryptoSuite::to_fbs(self.srtp_crypto_suite)), + enable_multicast: self.enable_multicast, } } } diff --git a/rust/src/router/plain_transport.rs b/rust/src/router/plain_transport.rs index ab5c7a0f47a..e1fcdd40ae3 100644 --- a/rust/src/router/plain_transport.rs +++ b/rust/src/router/plain_transport.rs @@ -73,7 +73,7 @@ pub struct PlainTransportOptions { /// The SRTP crypto suite to be used if enableSrtp is set. /// Default 'AesCm128HmacSha180'. pub srtp_crypto_suite: SrtpCryptoSuite, - /// Enable Multicast. + /// Enable multicast for UDP in case listening IP is a multicast valid IP. /// Default false. pub enable_multicast: bool, /// Custom application data. @@ -95,6 +95,7 @@ impl PlainTransportOptions { sctp_send_buffer_size: 262_144, enable_srtp: false, srtp_crypto_suite: SrtpCryptoSuite::default(), + enable_multicast: false, app_data: AppData::default(), } } diff --git a/rust/tests/integration/plain_transport.rs b/rust/tests/integration/plain_transport.rs index c968c395b5e..02f33465860 100644 --- a/rust/tests/integration/plain_transport.rs +++ b/rust/tests/integration/plain_transport.rs @@ -265,6 +265,32 @@ fn create_succeeds() { assert_eq!(transport_dump.sctp_state, transport2.sctp_state()); } } + + { + let transport = router + .create_plain_transport({ + let mut plain_transport_options = PlainTransportOptions::new(ListenInfo { + protocol: Protocol::Udp, + ip: IpAddr::V4(Ipv4Addr::LOCALHOST), + announced_ip: Some("4.4.4.4".parse().unwrap()), + port: None, + send_buffer_size: None, + recv_buffer_size: None, + }); + plain_transport_options.enable_multicast = true; + + plain_transport_options + }) + .await + .expect("Failed to create Plain transport"); + + let router_dump = router.dump().await.expect("Failed to dump router"); + assert_eq!(router_dump.transport_ids, { + let mut set = HashedSet::default(); + set.insert(transport.id()); + set + }); + } }); } diff --git a/worker/include/RTC/PlainTransport.hpp b/worker/include/RTC/PlainTransport.hpp index 37e2d063f32..ad9783618ff 100644 --- a/worker/include/RTC/PlainTransport.hpp +++ b/worker/include/RTC/PlainTransport.hpp @@ -85,7 +85,6 @@ namespace RTC size_t srtpMasterLength{ 0 }; std::string srtpKeyBase64; bool connectCalled{ false }; // Whether connect() was succesfully called. - bool multicast{ false }; }; } // namespace RTC diff --git a/worker/include/RTC/PortManager.hpp b/worker/include/RTC/PortManager.hpp index 80d57a3b1a5..37154c5d125 100644 --- a/worker/include/RTC/PortManager.hpp +++ b/worker/include/RTC/PortManager.hpp @@ -47,7 +47,8 @@ namespace RTC private: static uv_handle_t* Bind(Transport transport, std::string& ip, bool enableMulticast = false); - static uv_handle_t* Bind(Transport transport, std::string& ip, uint16_t port, bool enableMulticast = false); + static uv_handle_t* Bind( + Transport transport, std::string& ip, uint16_t port, bool enableMulticast = false); static void Unbind(Transport transport, std::string& ip, uint16_t port); static std::vector& GetPorts(Transport transport, const std::string& ip); diff --git a/worker/include/Utils.hpp b/worker/include/Utils.hpp index 46537dede12..40001a1791d 100644 --- a/worker/include/Utils.hpp +++ b/worker/include/Utils.hpp @@ -87,7 +87,7 @@ namespace Utils static void NormalizeIp(std::string& ip); - static bool IsMulticast(const struct sockaddr_storage* addr, const int& family); + static bool IsMulticast(const struct sockaddr_storage* addr, const int family); }; class File diff --git a/worker/src/RTC/PlainTransport.cpp b/worker/src/RTC/PlainTransport.cpp index 9350ccd9436..c4331d95c1a 100644 --- a/worker/src/RTC/PlainTransport.cpp +++ b/worker/src/RTC/PlainTransport.cpp @@ -155,18 +155,17 @@ namespace RTC this->srtpKeyBase64 = Utils::String::Base64Encode(this->srtpKey); } - this->multicast = options->enableMulticast(); - try { // This may throw. if (this->listenInfo.port != 0) { - this->udpSocket = new RTC::UdpSocket(this, this->listenInfo.ip, this->listenInfo.port, this->multicast); + this->udpSocket = new RTC::UdpSocket( + this, this->listenInfo.ip, this->listenInfo.port, options->enableMulticast()); } else { - this->udpSocket = new RTC::UdpSocket(this, this->listenInfo.ip, this->multicast); + this->udpSocket = new RTC::UdpSocket(this, this->listenInfo.ip, options->enableMulticast()); } if (this->listenInfo.sendBufferSize != 0) @@ -186,12 +185,13 @@ namespace RTC // This may throw. if (this->rtcpListenInfo.port != 0) { - this->rtcpUdpSocket = - new RTC::UdpSocket(this, this->rtcpListenInfo.ip, this->rtcpListenInfo.port, this->multicast); + this->rtcpUdpSocket = new RTC::UdpSocket( + this, this->rtcpListenInfo.ip, this->rtcpListenInfo.port, options->enableMulticast()); } else { - this->rtcpUdpSocket = new RTC::UdpSocket(this, this->rtcpListenInfo.ip, this->multicast); + this->rtcpUdpSocket = + new RTC::UdpSocket(this, this->rtcpListenInfo.ip, options->enableMulticast()); } if (this->rtcpListenInfo.sendBufferSize != 0) diff --git a/worker/src/RTC/PortManager.cpp b/worker/src/RTC/PortManager.cpp index badc110ff99..83ea56cfc66 100644 --- a/worker/src/RTC/PortManager.cpp +++ b/worker/src/RTC/PortManager.cpp @@ -218,13 +218,13 @@ namespace RTC case Transport::UDP: { #if defined(__linux__) - if (enableMulticast && Utils::IP::IsMulticast(&bindAddr, family)) + if (enableMulticast && Utils::IP::IsMulticast(std::addressof(bindAddr), family)) { - flags |= UV_UDP_REUSEADDR; MS_DEBUG_DEV("enabling UV_UDP_REUSEADDR"); + + flags |= UV_UDP_REUSEADDR; } #endif - err = uv_udp_bind( reinterpret_cast(uvHandle), reinterpret_cast(&bindAddr), @@ -481,13 +481,13 @@ namespace RTC case Transport::UDP: { #if defined(__linux__) - if (enableMulticast && Utils::IP::IsMulticast(&bindAddr, family)) + if (enableMulticast && Utils::IP::IsMulticast(std::addressof(bindAddr), family)) { - flags |= UV_UDP_REUSEADDR; MS_DEBUG_DEV("enabling UV_UDP_REUSEADDR"); + + flags |= UV_UDP_REUSEADDR; } #endif - err = uv_udp_bind( reinterpret_cast(uvHandle), reinterpret_cast(&bindAddr), diff --git a/worker/src/RTC/UdpSocket.cpp b/worker/src/RTC/UdpSocket.cpp index b7e3649a11a..38cff3bd873 100644 --- a/worker/src/RTC/UdpSocket.cpp +++ b/worker/src/RTC/UdpSocket.cpp @@ -12,15 +12,16 @@ namespace RTC UdpSocket::UdpSocket(Listener* listener, std::string& ip, bool enableMulticast) : // This may throw. - ::UdpSocketHandle::UdpSocketHandle(PortManager::BindUdp(ip, enableMulticast)), listener(listener) + ::UdpSocketHandle::UdpSocketHandle(PortManager::BindUdp(ip, enableMulticast)), + listener(listener) { MS_TRACE(); } UdpSocket::UdpSocket(Listener* listener, std::string& ip, uint16_t port, bool enableMulticast) : // This may throw. - ::UdpSocketHandle::UdpSocketHandle(PortManager::BindUdp(ip, port, enableMulticast)), listener(listener), - fixedPort(true) + ::UdpSocketHandle::UdpSocketHandle(PortManager::BindUdp(ip, port, enableMulticast)), + listener(listener), fixedPort(true) { MS_TRACE(); } diff --git a/worker/src/Utils/IP.cpp b/worker/src/Utils/IP.cpp index eff077d7cb1..8bef4747b0e 100644 --- a/worker/src/Utils/IP.cpp +++ b/worker/src/Utils/IP.cpp @@ -156,7 +156,7 @@ namespace Utils } } - bool IP::IsMulticast(const struct sockaddr_storage* addr, const int& family) + bool IP::IsMulticast(const struct sockaddr_storage* addr, const int family) { MS_TRACE(); @@ -165,21 +165,15 @@ namespace Utils case AF_INET: { uint32_t s_addr = ntohl((reinterpret_cast(addr))->sin_addr.s_addr); - if (s_addr >= 0xe0000000 && s_addr <= 0xefffffff) - { - return true; - } - break; + + return (s_addr >= 0xe0000000 && s_addr <= 0xefffffff); } case AF_INET6: { uint8_t _s6_addr = (reinterpret_cast(addr))->sin6_addr.s6_addr[0]; - if (_s6_addr == 0xFF) - { - return true; - } - break; + + return (_s6_addr == 0xFF); } default: @@ -187,7 +181,5 @@ namespace Utils MS_THROW_TYPE_ERROR("invalid family"); } } - - return false; } } // namespace Utils