11#include " udp_server.h"
2+ #include " api_config.h"
23#include " socket_utils.h"
34#include " stream_info_impl.h"
5+ #include < boost/asio/io_context.hpp>
46#include < boost/asio/ip/address.hpp>
7+ #include < boost/asio/ip/address_v4.hpp>
58#include < boost/asio/ip/multicast.hpp>
69#include < boost/asio/ip/udp.hpp>
7- #include < boost/asio/io_context.hpp>
8- #include < boost/asio/ip/address_v4.hpp>
910#include < exception>
1011#include < loguru.hpp>
1112#include < sstream>
@@ -32,11 +33,10 @@ udp_server::udp_server(const stream_info_impl_p &info, asio::io_context &io, udp
3233 (void *)this );
3334}
3435
35- udp_server::udp_server (const stream_info_impl_p &info, asio::io_context &io,
36- const std::string &address, uint16_t port, int ttl, const std::string &listen_address)
36+ udp_server::udp_server (const stream_info_impl_p &info, asio::io_context &io, ip::address addr,
37+ uint16_t port, int ttl, const std::string &listen_address)
3738 : info_(info), io_(io), socket_(std::make_shared<udp::socket>(io)),
3839 time_services_enabled_(false ) {
39- ip::address addr = ip::make_address (address);
4040 bool is_broadcast = addr == ip::address_v4::broadcast ();
4141
4242 // set up the endpoint where we listen (note: this is not yet the multicast address)
@@ -63,16 +63,28 @@ udp_server::udp_server(const stream_info_impl_p &info, asio::io_context &io,
6363 // bind to the listen endpoint
6464 socket_->bind (listen_endpoint);
6565
66- // join the multicast group, if any
66+ // join the multicast groups
6767 if (addr.is_multicast () && !is_broadcast) {
68- if (addr.is_v4 ())
69- socket_->set_option (
70- ip::multicast::join_group (addr.to_v4 (), listen_endpoint.address ().to_v4 ()));
71- else
72- socket_->set_option (ip::multicast::join_group (addr));
68+ bool joined_anywhere = false ;
69+ lslboost::system::error_code err;
70+ for (auto &if_ : api_config::get_instance ()->multicast_interfaces ) {
71+ DLOG_F (
72+ INFO, " Joining %s to %s" , if_.addr .to_string ().c_str (), addr.to_string ().c_str ());
73+ if (addr.is_v4 () && if_.addr .is_v4 ())
74+ socket_->set_option (ip::multicast::join_group (addr.to_v4 (), if_.addr .to_v4 ()), err);
75+ else if (addr.is_v6 () && if_.addr .is_v6 ())
76+ socket_->set_option (
77+ ip::multicast::join_group (addr.to_v6 (), if_.addr .to_v6 ().scope_id ()), err);
78+ if (err)
79+ LOG_F (WARNING, " Could not bind multicast responder for %s to interface %s (%s)" ,
80+ addr.to_string ().c_str (), if_.addr .to_string ().c_str (), err.message ().c_str ());
81+ else
82+ joined_anywhere = true ;
83+ }
84+ if (!joined_anywhere) throw std::runtime_error (" Could not join any multicast group" );
7385 }
7486 LOG_F (2 , " %s: Started multicast udp server at %s port %d (addr %p)" ,
75- this ->info_ ->name ().c_str (), address .c_str (), port, (void *)this );
87+ this ->info_ ->name ().c_str (), addr. to_string () .c_str (), port, (void *)this );
7688}
7789
7890// === externally issued asynchronous commands ===
0 commit comments