summaryrefslogtreecommitdiff
path: root/debian/patches/tac_connect_set_dscp.patch
blob: 3eea978b197c635ae486aeb908e8c9adfd34eb02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
--- a/libtac/include/libtac.h
+++ b/libtac/include/libtac.h
@@ -130,6 +130,7 @@ extern int tac_readtimeout_enable;
 /* connect.c */
 extern int tac_timeout;
 
+void tac_set_dscp(uint8_t val);
 int tac_connect(struct addrinfo **, char **, int);
 int tac_connect_single(struct addrinfo *, const char *, struct addrinfo *, int);
 char *tac_ntop(const struct sockaddr *);
--- a/libtac/lib/connect.c
+++ b/libtac/lib/connect.c
@@ -34,6 +34,13 @@
 /* Pointer to TACACS+ connection timeout */
 int tac_timeout = 5;
 
+unsigned int tac_dscp = 0;
+
+void tac_set_dscp(uint8_t val) {
+    /* Value should already be left shifted by 2 bits (those are used for ECN) */
+    tac_dscp = val;
+}
+
 /* Returns file descriptor of open connection
    to the first available server from list passed
    in server table.
@@ -91,6 +98,24 @@ int tac_connect_single(struct addrinfo *
         return LIBTAC_STATUS_CONN_ERR;
     }
 
+    switch (server->ai_family) {
+        case AF_INET:
+            rc = setsockopt(fd, IPPROTO_IP, IP_TOS, &tac_dscp, sizeof tac_dscp);
+            break;
+        case AF_INET6:
+            rc = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tac_dscp, sizeof tac_dscp);
+            break;
+        default:
+            rc = 0;
+    }
+    if (rc < 0) {
+        TACSYSLOG((LOG_ERR,"%s: setsockopt(%s) error: %s", __FUNCTION__,
+            server->ai_family == AF_INET ? "IP_TOS" : "IPV6_TCLASS",
+            strerror(errno)))
+        close(fd);
+        return LIBTAC_STATUS_CONN_ERR;
+    }
+
     /* get flags for restoration later */
     flags = fcntl(fd, F_GETFL, 0);