2 #include <sys/socket.h>
9 #ifndef SO_MAX_PACING_RATE
10 #define SO_MAX_PACING_RATE 47
13 UDPStream::UDPStream(const sockaddr_in6 &dst, uint32_t pacing_rate, int ttl, int multicast_iface_index)
16 sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
18 // Oops. Ignore this output, then.
23 if (setsockopt(sock, SOL_SOCKET, SO_MAX_PACING_RATE, &pacing_rate, sizeof(pacing_rate)) == -1) {
24 if (pacing_rate != ~0U) {
25 log_perror("setsockopt(SO_MAX_PACING_RATE)");
30 // Seemingly the IPv4 parameters are used for sending to IPv4,
31 // even on an AF_INET6 socket, so we need to set both.
32 if (setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
33 log_perror("setsockopt(IP_TTL)");
35 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) {
36 log_perror("setsockopt(IP_MULTICAST_TTL)");
38 if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) == -1) {
39 log_perror("setsockopt(IPV6_UNICAST_HOPS)");
41 if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) {
42 log_perror("setsockopt(IPV6_MULTICAST_HOPS)");
46 if (multicast_iface_index != -1) {
48 memset(&mr, 0, sizeof(mr));
49 mr.imr_ifindex = multicast_iface_index;
50 if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mr, sizeof(mr)) == -1) {
51 log_perror("setsockopt(IP_MULTICAST_IF)");
53 if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_iface_index, sizeof(multicast_iface_index)) == -1) {
54 log_perror("setsockopt(IPV6_MULTICAST_IF)");
59 UDPStream::~UDPStream()
66 void UDPStream::send(const char *data, size_t bytes)
71 ssize_t err = sendto(sock, data, bytes, 0, reinterpret_cast<sockaddr *>(&dst), sizeof(dst));