This should complete multicast output support.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <net/if.h>
#include <sys/socket.h>
#include <map>
#include <string>
udpstream.ttl = atoi(ttl_it->second.c_str());
}
+ // Parse the multicast interface index.
+ map<string, string>::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;
}
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 {
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
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()) {
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;
}
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<int> &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;
+#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#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);
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()
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);