From: Jaroslav Kysela Date: Mon, 21 Sep 2015 12:51:48 +0000 (+0200) Subject: config/streaming: add possibility to set DSCP IP value for streaming, fixes #2701 X-Git-Tag: v4.2.1~2085 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f63a8fda77f2c067b32cf000b60edd25cece2991;p=thirdparty%2Ftvheadend.git config/streaming: add possibility to set DSCP IP value for streaming, fixes #2701 --- diff --git a/src/config.c b/src/config.c index 7f75f313a..35c94e40e 100644 --- a/src/config.c +++ b/src/config.c @@ -33,6 +33,8 @@ #include "url.h" #include "satip/server.h" +#include + 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, diff --git a/src/config.h b/src/config.h index 231b670c0..25cc86ed8 100644 --- a/src/config.h +++ b/src/config.h @@ -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; diff --git a/src/satip/rtp.c b/src/satip/rtp.c index d216ee7c5..dc524fe5b 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -20,9 +20,11 @@ #include #include #include "tvheadend.h" +#include "config.h" #include "input.h" #include "streaming.h" #include "satip/server.h" +#include #if ENABLE_ANDROID #include #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); diff --git a/src/tcp.c b/src/tcp.c index 48e95b614..d41b523a8 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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; +} + /** * */ diff --git a/src/tcp.h b/src/tcp.h index fdd177063..91eb2c005 100644 --- 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); diff --git a/src/webui/webui.c b/src/webui/webui.c index 38b54515f..5ba708660 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -31,6 +31,7 @@ #include #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;