From: Steinar H. Gunderson Date: Sat, 26 Apr 2014 18:01:00 +0000 (+0200) Subject: Support setting outgoing interface for multicast. X-Git-Tag: 1.1.0~6 X-Git-Url: https://git.sesse.net/?p=cubemap;a=commitdiff_plain;h=0eac9253f23925734e256c63081e157c68c70704 Support setting outgoing interface for multicast. This should complete multicast output support. --- diff --git a/config.cpp b/config.cpp index 57bf10a..f474f8c 100644 --- a/config.cpp +++ b/config.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -298,6 +299,18 @@ bool parse_udpstream(const ConfigLine &line, Config *config) udpstream.ttl = atoi(ttl_it->second.c_str()); } + // Parse the multicast interface index. + map::const_iterator multicast_iface_it = line.parameters.find("multicast_output_interface"); + if (multicast_iface_it == line.parameters.end()) { + udpstream.multicast_iface_index = -1; + } else { + udpstream.multicast_iface_index = if_nametoindex(multicast_iface_it->second.c_str()); + if (udpstream.multicast_iface_index == 0) { + log(ERROR, "Interface '%s' does not exist", multicast_iface_it->second.c_str()); + return false; + } + } + config->udpstreams.push_back(udpstream); return true; } diff --git a/config.h b/config.h index d5b0411..3014b48 100644 --- a/config.h +++ b/config.h @@ -22,6 +22,7 @@ struct UDPStreamConfig { std::string src; // Can be empty. uint32_t pacing_rate; // In bytes per second. Default is ~0U (no limit). int ttl; // Default is -1 (use operating system default). + int multicast_iface_index; // Default is -1 (use operating system default). }; struct AcceptorConfig { diff --git a/cubemap.config.sample b/cubemap.config.sample index a68bfb8..6378642 100644 --- a/cubemap.config.sample +++ b/cubemap.config.sample @@ -38,4 +38,4 @@ stream /test.flv.metacube src=http://gruessi.zrh.sesse.net:4013/test.flv encodin stream /udp.ts src=udp://@:1234 backlog_size=1048576 pacing_rate_kbit=2000 udpstream [2001:67c:29f4::50]:5000 src=http://pannekake.samfundet.no:9094/frikanalen.ts.metacube udpstream 193.35.52.50:5001 src=http://pannekake.samfundet.no:9094/frikanalen.ts.metacube -udpstream 233.252.0.1:5002 src=http://pannekake.samfundet.no:9094/frikanalen.ts.metacube ttl=32 +udpstream 233.252.0.1:5002 src=http://pannekake.samfundet.no:9094/frikanalen.ts.metacube ttl=32 multicast_output_interface=eth1 diff --git a/main.cpp b/main.cpp index eaec887..14f6323 100644 --- a/main.cpp +++ b/main.cpp @@ -204,7 +204,8 @@ void create_streams(const Config &config, int stream_index = servers->add_udpstream( udpstream_config.dst, udpstream_config.pacing_rate, - udpstream_config.ttl); + udpstream_config.ttl, + udpstream_config.multicast_iface_index); string src = udpstream_config.src; if (!src.empty()) { diff --git a/serverpool.cpp b/serverpool.cpp index 021cf1d..4684d8c 100644 --- a/serverpool.cpp +++ b/serverpool.cpp @@ -121,9 +121,9 @@ int ServerPool::add_stream_from_serialized(const StreamProto &stream, const vect return num_http_streams++; } -int ServerPool::add_udpstream(const sockaddr_in6 &dst, int pacing_rate, int ttl) +int ServerPool::add_udpstream(const sockaddr_in6 &dst, int pacing_rate, int ttl, int multicast_iface_index) { - udp_streams.push_back(new UDPStream(dst, pacing_rate, ttl)); + udp_streams.push_back(new UDPStream(dst, pacing_rate, ttl, multicast_iface_index)); return num_http_streams + udp_streams.size() - 1; } diff --git a/serverpool.h b/serverpool.h index 07d9a5d..8fa46e2 100644 --- a/serverpool.h +++ b/serverpool.h @@ -32,7 +32,7 @@ public: int add_stream(const std::string &url, size_t backlog_size, Stream::Encoding encoding); int add_stream_from_serialized(const StreamProto &stream, const std::vector &data_fds); void delete_stream(const std::string &url); - int add_udpstream(const sockaddr_in6 &dst, int pacing_rate, int ttl); + int add_udpstream(const sockaddr_in6 &dst, int pacing_rate, int ttl, int multicast_iface_index); // Returns the stream index for the given URL (e.g. /foo.ts). Returns -1 on failure. int lookup_stream_by_url(const std::string &url) const; diff --git a/udpstream.cpp b/udpstream.cpp index 74d6ef0..7747649 100644 --- a/udpstream.cpp +++ b/udpstream.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -9,7 +10,7 @@ #define SO_MAX_PACING_RATE 47 #endif -UDPStream::UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl) +UDPStream::UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl, int multicast_iface_index) : dst(dst) { sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); @@ -41,6 +42,18 @@ UDPStream::UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl) log_perror("setsockopt(IPV6_MULTICAST_HOPS)"); } } + + if (multicast_iface_index != -1) { + ip_mreqn mr; + memset(&mr, 0, sizeof(mr)); + mr.imr_ifindex = multicast_iface_index; + if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mr, sizeof(mr)) == -1) { + log_perror("setsockopt(IP_MULTICAST_IF)"); + } + if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_iface_index, sizeof(multicast_iface_index)) == -1) { + log_perror("setsockopt(IPV6_MULTICAST_IF)"); + } + } } UDPStream::~UDPStream() diff --git a/udpstream.h b/udpstream.h index 4a2de65..ede738e 100644 --- a/udpstream.h +++ b/udpstream.h @@ -16,7 +16,7 @@ class MarkPool; class UDPStream { public: - UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl); + UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl, int multicast_iface_index); ~UDPStream(); void send(const char *data, size_t bytes);