Hi,

Using relayd's redirect/forward on ipv6 addresses I discovered problems 
relating to setting TTL.

There is no check for address family and setsockopt tries to apply IP_TTL 
always.

Without ip ttl on ipv6 table, check_icmp gives
send_icmp: getsockopt: Invalid argument

With ip ttl on ipv6 table, check_tcp gives
hce_notify_done: fdaa:10:1:9::11 (tcp socket option)

is the following diff valid?
I've removed the IP_IPDEFTTL check. Was this ok?

regards,

Giannis

Index: check_icmp.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/check_icmp.c,v
retrieving revision 1.45
diff -u -p -r1.45 check_icmp.c
--- check_icmp.c        28 May 2017 10:39:15 -0000      1.45
+++ check_icmp.c        23 Jun 2017 10:42:30 -0000
@@ -165,7 +165,7 @@ send_icmp(int s, short event, void *arg)
        struct icmp6_hdr        *icp6;
        ssize_t                  r;
        u_char                   packet[ICMP_BUF_SIZE];
-       socklen_t                slen, len;
+       socklen_t                slen;
        int                      i = 0, ttl;
        u_int32_t                id;
 
@@ -221,18 +221,18 @@ send_icmp(int s, short event, void *arg)
                        }
 
                        if ((ttl = host->conf.ttl) > 0)
-                               (void)setsockopt(s, IPPROTO_IP, IP_TTL,
-                                   &host->conf.ttl, sizeof(int));
-                       else {
-                               /* Revert to default TTL */
-                               len = sizeof(ttl);
-                               if (getsockopt(s, IPPROTO_IP, IP_IPDEFTTL,
-                                   &ttl, &len) == 0)
-                                       (void)setsockopt(s, IPPROTO_IP, IP_TTL,
-                                           &ttl, len);
-                               else
-                                   log_warn("%s: getsockopt",__func__);
-                       }
+                               switch(cie->af) {
+                               case AF_INET:
+                                       if (setsockopt(s, IPPROTO_IP, IP_TTL,
+                                           &host->conf.ttl, sizeof(int)) == -1)
+                                               log_warn("%s: 
setsockopt",__func__);
+                                       break;
+                               case AF_INET6:
+                                       if (setsockopt(s, IPPROTO_IPV6, 
IPV6_UNICAST_HOPS,
+                                           &host->conf.ttl, sizeof(int)) == -1)
+                                               log_warn("%s: 
setsockopt",__func__);
+                                       break;
+                               }
 
                        r = sendto(s, packet, sizeof(packet), 0, to, slen);
                        if (r == -1) {
Index: check_tcp.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/check_tcp.c,v
retrieving revision 1.54
diff -u -p -r1.54 check_tcp.c
--- check_tcp.c 28 May 2017 10:39:15 -0000      1.54
+++ check_tcp.c 23 Jun 2017 10:42:30 -0000
@@ -82,11 +82,19 @@ check_tcp(struct ctl_tcp_event *cte)
        if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
                goto bad;
 
-       if (cte->host->conf.ttl > 0) {
-               if (setsockopt(s, IPPROTO_IP, IP_TTL,
-                   &cte->host->conf.ttl, sizeof(int)) == -1)
-                       goto bad;
-       }
+       if (cte->host->conf.ttl > 0)
+               switch (cte->host->conf.ss.ss_family) {
+               case AF_INET:
+                       if (setsockopt(s, IPPROTO_IP, IP_TTL,
+                           &cte->host->conf.ttl, sizeof(int)) == -1)
+                               goto bad;
+                       break;
+               case AF_INET6:
+                       if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
+                           &cte->host->conf.ttl, sizeof(int)) == -1)
+                               goto bad;
+                       break;
+               }
 
        bcopy(&cte->table->conf.timeout, &tv, sizeof(tv));
        if (connect(s, (struct sockaddr *)&cte->host->conf.ss, len) == -1) {

Reply via email to