On Fri, Jun 23, 2017 at 01:52:52PM +0300, Kapetanakis Giannis wrote:
> 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?

the check_tcp hunk looks good and is OK florian@

> I've removed the IP_IPDEFTTL check. Was this ok?

Nope, relayd reuses the raw socket between config reloads (I think),
if the ttl gets removed from the config we need to reset to the
default. Don't think there is a getsockopt for v6, you can take a look
at the sysctl(3) song and dance in traceroute(8) how to do this
somewhat AF independet.

Also please make sure to not exceed 80 cols

> 
> 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) {
> 

-- 
I'm not entirely sure you are real.

Reply via email to