]> git.sesse.net Git - cubemap/blobdiff - udpstream.cpp
Add suppor for raw (non-Metacube) inputs over HTTP. Only really useful for TS.
[cubemap] / udpstream.cpp
index 5ed16df2f177d22a72ff008937b5e68f0d45743a..77476499a69a2e13b61d1708ef366f222359424d 100644 (file)
@@ -1,15 +1,17 @@
+#include <string.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 
 #include "log.h"
-#include "markpool.h"
 #include "udpstream.h"
 #include "util.h"
 
-UDPStream::UDPStream(const sockaddr_in6 &dst, MarkPool *mark_pool)
-       : dst(dst),
-         mark_pool(mark_pool),
-         fwmark(0)
+#ifndef SO_MAX_PACING_RATE
+#define SO_MAX_PACING_RATE 47
+#endif
+
+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);
        if (sock == -1) {
@@ -18,12 +20,38 @@ UDPStream::UDPStream(const sockaddr_in6 &dst, MarkPool *mark_pool)
                return;
        }
 
-       if (mark_pool != NULL) {
-               fwmark = mark_pool->get_mark();
-               if (setsockopt(sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1) {                          
-                       if (fwmark != 0) {
-                               log_perror("setsockopt(SO_MARK)");
-                       }
+       if (setsockopt(sock, SOL_SOCKET, SO_MAX_PACING_RATE, &pacing_rate, sizeof(pacing_rate)) == -1) {
+               if (pacing_rate != ~0U) {
+                       log_perror("setsockopt(SO_MAX_PACING_RATE)");
+               }
+       }
+
+       if (ttl != -1) {
+               // Seemingly the IPv4 parameters are used for sending to IPv4,
+               // even on an AF_INET6 socket, so we need to set both.
+               if (setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) == -1) {
+                       log_perror("setsockopt(IP_TTL)");
+               }
+               if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) {
+                       log_perror("setsockopt(IP_MULTICAST_TTL)");
+               }
+               if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) == -1) {
+                       log_perror("setsockopt(IPV6_UNICAST_HOPS)");
+               }
+               if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) {
+                       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)");
                }
        }
 }
@@ -33,9 +61,6 @@ UDPStream::~UDPStream()
        if (sock != -1) {
                safe_close(sock);
        }
-       if (mark_pool != NULL) {
-               mark_pool->release_mark(fwmark);
-       }
 }
 
 void UDPStream::send(const char *data, size_t bytes)