]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
config/streaming: add possibility to set DSCP IP value for streaming, fixes #2701
authorJaroslav Kysela <perex@perex.cz>
Mon, 21 Sep 2015 12:51:48 +0000 (14:51 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 21 Sep 2015 12:51:48 +0000 (14:51 +0200)
src/config.c
src/config.h
src/satip/rtp.c
src/tcp.c
src/tcp.h
src/webui/webui.c

index 7f75f313acc2e7940c97591f353f23d90d7d1894..35c94e40efefcc4c8570951641ddb701bbaf643d 100644 (file)
@@ -33,6 +33,8 @@
 #include "url.h"
 #include "satip/server.h"
 
+#include <netinet/ip.h>
+
 void tvh_str_set(char **strp, const char *src);
 int tvh_str_update(char **strp, const char *src);
 
@@ -1546,6 +1548,7 @@ config_boot ( const char *path, gid_t gid, uid_t uid )
   config.idnode.in_class = &config_class;
   config.info_area = strdup("login,storage,time");
   config.cookie_expires = 7;
+  config.dscp = -1;
 
   /* Generate default */
   if (!path) {
@@ -1775,6 +1778,36 @@ config_class_info_area_list ( void *o, const char *lang )
   return m;
 }
 
+static htsmsg_t *
+config_class_dscp_list ( void *o, const char *lang )
+{
+  static const struct strtab tab[] = {
+    { N_("Default"), -1 },
+    { N_("CS0"),  IPTOS_CLASS_CS0 },
+    { N_("CS1"),  IPTOS_CLASS_CS1 },
+    { N_("AF11"), IPTOS_DSCP_AF11 },
+    { N_("AF12"), IPTOS_DSCP_AF12 },
+    { N_("AF13"), IPTOS_DSCP_AF13 },
+    { N_("CS2"),  IPTOS_CLASS_CS2 },
+    { N_("AF21"), IPTOS_DSCP_AF21 },
+    { N_("AF22"), IPTOS_DSCP_AF22 },
+    { N_("AF23"), IPTOS_DSCP_AF23 },
+    { N_("CS3"),  IPTOS_CLASS_CS3 },
+    { N_("AF31"), IPTOS_DSCP_AF31 },
+    { N_("AF32"), IPTOS_DSCP_AF32 },
+    { N_("AF33"), IPTOS_DSCP_AF33 },
+    { N_("CS4"),  IPTOS_CLASS_CS4 },
+    { N_("AF41"), IPTOS_DSCP_AF41 },
+    { N_("AF42"), IPTOS_DSCP_AF42 },
+    { N_("AF43"), IPTOS_DSCP_AF43 },
+    { N_("CS5"),  IPTOS_CLASS_CS5 },
+    { N_("EF"),   IPTOS_DSCP_EF },
+    { N_("CS6"),  IPTOS_CLASS_CS6 },
+    { N_("CS7"),  IPTOS_CLASS_CS7 },
+  };
+  return strtab2htsmsg(tab, 1, lang);
+}
+
 const idclass_t config_class = {
   .ic_snode      = &config.idnode,
   .ic_class      = "config",
@@ -1848,6 +1881,14 @@ const idclass_t config_class = {
       .off    = offsetof(config_t, cors_origin),
       .group  = 1
     },
+    {
+      .type   = PT_INT,
+      .id     = "dscp",
+      .name   = N_("DSCP/TOS for streaming"),
+      .off    = offsetof(config_t, dscp),
+      .list   = config_class_dscp_list,
+      .group  = 1
+    },
     {
       .type   = PT_STR,
       .islist = 1,
index 231b670c0dbf7201022fadfc5d1eae3dfdfdc08a..25cc86ed86ccfe5640f7530531998c7dd9e2d462 100644 (file)
@@ -43,6 +43,7 @@ typedef struct config {
   uint32_t tvhtime_tolerance;
   char *cors_origin;
   uint32_t cookie_expires;
+  int dscp;
 } config_t;
 
 extern const idclass_t config_class;
index d216ee7c5847233f9322ed77a617a53c480758d0..dc524fe5b2262ad13af607b49eb5313600f55e61 100644 (file)
 #include <signal.h>
 #include <ctype.h>
 #include "tvheadend.h"
+#include "config.h"
 #include "input.h"
 #include "streaming.h"
 #include "satip/server.h"
+#include <netinet/ip.h>
 #if ENABLE_ANDROID
 #include <sys/socket.h>
 #endif
@@ -275,6 +277,14 @@ void satip_rtp_queue(void *id, th_subscription_t *subs,
   rtp->source = source;
   pthread_mutex_init(&rtp->lock, NULL);
 
+  if (config.dscp >= 0) {
+    socket_set_dscp(rtp->fd_rtp, config.dscp, NULL, 0);
+    socket_set_dscp(rtp->fd_rtcp, config.dscp, NULL, 0);
+  } else {
+    socket_set_dscp(rtp->fd_rtp, IPTOS_DSCP_EF, NULL, 0);
+    socket_set_dscp(rtp->fd_rtcp, IPTOS_DSCP_EF, NULL, 0);
+  }
+
   pthread_mutex_lock(&satip_rtp_lock);
   TAILQ_INSERT_TAIL(&satip_rtp_sessions, rtp, link);
   tvhthread_create(&rtp->tid, NULL, satip_rtp_thread, rtp);
index 48e95b614cd8e7049dbc51a169cbc78f916cd0b6..d41b523a8859f80a6b5c79e08406748b50d4fb93 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
+#include <netinet/ip.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
@@ -49,6 +50,24 @@ int tcp_preferred_address_family = AF_INET;
 int tcp_server_running;
 th_pipe_t tcp_server_pipe;
 
+/**
+ *
+ */
+int
+socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize)
+{
+  int r, v;
+
+  v = dscp & IPTOS_DSCP_MASK;
+  r = setsockopt(sockfd, IPPROTO_IP, IP_TOS, &v, sizeof(v));
+  if (r < 0) {
+    if (errbuf && errbufsize)
+      snprintf(errbuf, errbufsize, "IP_TOS failed: %s", strerror(errno));
+    return -1;
+  }
+  return 0;
+}
+
 /**
  *
  */
index fdd17706320a196fdfe9776951313cf9a4395f21..91eb2c005171cd5a52ca371f0dc0c96b4a54e0e2 100644 (file)
--- a/src/tcp.h
+++ b/src/tcp.h
@@ -56,6 +56,8 @@ void tcp_server_preinit(int opt_ipv6);
 void tcp_server_init(void);
 void tcp_server_done(void);
 
+int socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize);
+
 int tcp_connect(const char *hostname, int port, const char *bindaddr,
                 char *errbuf, size_t errbufsize, int timeout);
 
index 38b54515f2fcc836742f57ff4f970c98071f3664..5ba708660b2ffb2bb972f3bd434eec185bf8bab5 100644 (file)
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 
 #include "tvheadend.h"
+#include "config.h"
 #include "http.h"
 #include "tcp.h"
 #include "webui.h"
@@ -317,6 +318,8 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch,
   tp.tv_sec  = 5;
   tp.tv_usec = 0;
   setsockopt(hc->hc_fd, SOL_SOCKET, SO_SNDTIMEO, &tp, sizeof(tp));
+  if (config.dscp >= 0)
+    socket_set_dscp(hc->hc_fd, config.dscp, NULL, 0);
 
   lastpkt = dispatch_clock;
   ptimeout = prch->prch_pro ? prch->prch_pro->pro_timeout : 5;