From: Guus Sliepen <guus@tinc-vpn.org>
Date: Sun, 10 Apr 2016 15:22:41 +0000 (+0200)
Subject: Support ToS/DiffServ for IPv6 meta and UDP connections.
X-Git-Tag: release-1.1pre12~51
X-Git-Url: http://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=c544e5e8fe22250b230a46f0340483db5403a6c1;p=tinc

Support ToS/DiffServ for IPv6 meta and UDP connections.

Also remember ToS/DiffServ priority for each socket individually. This
is a port of commits c72e237 and 042a6c1.
---

diff --git a/src/net.h b/src/net.h
index 0c3d64c3..c3c82de3 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1,7 +1,7 @@
 /*
     net.h -- header for net.c
     Copyright (C) 1998-2005 Ivo Timmermans
-                  2000-2014 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -115,6 +115,7 @@ typedef struct listen_socket_t {
 	io_t udp;
 	sockaddr_t sa;
 	bool bindto;
+	int priority;
 } listen_socket_t;
 
 #include "conf.h"
diff --git a/src/net_packet.c b/src/net_packet.c
index f6c19b7a..f8c6ac9b 100644
--- a/src/net_packet.c
+++ b/src/net_packet.c
@@ -1,7 +1,7 @@
 /*
     net_packet.c -- Handles in- and outgoing VPN packets
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2014 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
                   2010      Timothy Redaelli <timothy@redaelli.eu>
                   2010      Brandon Black <blblack@gmail.com>
 
@@ -621,10 +621,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
 	vpn_packet_t *outpkt;
 	int origlen = origpkt->len;
 	size_t outlen;
-#if defined(SOL_IP) && defined(IP_TOS)
-	static int priority = 0;
 	int origpriority = origpkt->priority;
-#endif
 
 	pkt1.offset = DEFAULT_PACKET_OFFSET;
 	pkt2.offset = DEFAULT_PACKET_OFFSET;
@@ -719,15 +716,27 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
 	if(!sa)
 		choose_udp_address(n, &sa, &sock);
 
+	if(priorityinheritance && origpriority != listen_socket[sock].priority) {
+		listen_socket[sock].priority = origpriority;
+		switch(sa->sa.sa_family) {
 #if defined(SOL_IP) && defined(IP_TOS)
-	if(priorityinheritance && origpriority != priority
-	   && listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
-		priority = origpriority;
-		logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
-		if(setsockopt(listen_socket[n->sock].udp.fd, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
-			logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno));
-	}
+		case AF_INET:
+			logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority);
+			if(setsockopt(listen_socket[sock].udp.fd, SOL_IP, IP_TOS, &origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */
+				logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno));
+			break;
+#endif
+#if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS)
+		case AF_INET6:
+			logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority);
+			if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, &origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */
+				logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno));
+			break;
 #endif
+		default:
+			break;
+		}
+	}
 
 	if(sendto(listen_socket[sock].udp.fd, SEQNO(inpkt), inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
 		if(sockmsgsize(sockerrno)) {
diff --git a/src/net_setup.c b/src/net_setup.c
index 38fed521..0c074719 100644
--- a/src/net_setup.c
+++ b/src/net_setup.c
@@ -1,7 +1,7 @@
 /*
     net_setup.c -- Setup.
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2015 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
                   2006      Scott Lamb <slamb@slamb.org>
                   2010      Brandon Black <blblack@gmail.com>
 
@@ -593,7 +593,12 @@ bool setup_myself_reloadable(void) {
 
 #if !defined(SOL_IP) || !defined(IP_TOS)
 	if(priorityinheritance)
-		logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "PriorityInheritance");
+		logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv4 connections", "PriorityInheritance");
+#endif
+
+#if !defined(IPPROTO_IPV6) || !defined(IPV6_TCLASS)
+	if(priorityinheritance)
+		logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform for IPv6 connections", "PriorityInheritance");
 #endif
 
 	if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
diff --git a/src/net_socket.c b/src/net_socket.c
index 767e91e9..fab11d67 100644
--- a/src/net_socket.c
+++ b/src/net_socket.c
@@ -1,7 +1,7 @@
 /*
     net_socket.c -- Handle various kinds of sockets.
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2014 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2016 Guus Sliepen <guus@tinc-vpn.org>
                   2006      Scott Lamb <slamb@slamb.org>
                   2009      Florian Forster <octo@verplant.org>
 
@@ -82,6 +82,11 @@ static void configure_tcp(connection_t *c) {
 	option = IPTOS_LOWDELAY;
 	setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option);
 #endif
+
+#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY)
+	option = IPTOS_LOWDELAY;
+	setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof option);
+#endif
 }
 
 static bool bind_to_interface(int sd) {