On Tue, Jan 15 2019, Brad Smith <[email protected]> wrote:
> Hi,
>
> Looking for some testing of dnsmasq 2.80. If I'm not mistaken
> the issue with IP_SENDSRCADDR was resolved.

I just used dnsmasq -d, and nope, the issue that plagued dnsmasq is
still here.  The kernel problem fixed earlier in 2018 was an edge case
not directly related to dnsmasq.

I had a diff to unbreak dnsmasq using IP_SENDSRCADDR that I have already
shown, not sure if I got any feedback about it.  Updated version below.

The root cause is that sendmsg(2) fails with EINVAL because of
assumptions about the cmsg API that our kernel rejects.  The surrounding
dnsmasq code ignores this error because of an edge case on Linux.


Index: Makefile
===================================================================
RCS file: /cvs/ports/net/dnsmasq/Makefile,v
retrieving revision 1.51
diff -u -p -r1.51 Makefile
--- Makefile    29 Mar 2018 19:42:51 -0000      1.51
+++ Makefile    16 Jan 2019 00:22:16 -0000
@@ -2,7 +2,7 @@
 
 COMMENT=       lightweight caching DNS forwarder, DHCP and TFTP server
 
-DISTNAME=      dnsmasq-2.79
+DISTNAME=      dnsmasq-2.80
 CATEGORIES=    net
 MASTER_SITES=  http://www.thekelleys.org.uk/dnsmasq/
 EXTRACT_SUFX=  .tar.xz
Index: distinfo
===================================================================
RCS file: /cvs/ports/net/dnsmasq/distinfo,v
retrieving revision 1.34
diff -u -p -r1.34 distinfo
--- distinfo    29 Mar 2018 19:42:51 -0000      1.34
+++ distinfo    16 Jan 2019 00:22:16 -0000
@@ -1,2 +1,2 @@
-SHA256 (dnsmasq-2.79.tar.xz) = eK109coU/YWousk/dkzZ1gsnV56Q6r02h8p7Aw5nhh8=
-SIZE (dnsmasq-2.79.tar.xz) = 493036
+SHA256 (dnsmasq-2.80.tar.xz) = zauieF6SZlzwkGRsum+UgSdgudfYyNDPsHrIGTd6Y7s=
+SIZE (dnsmasq-2.80.tar.xz) = 501072
Index: patches/patch-man_dnsmasq_8
===================================================================
RCS file: /cvs/ports/net/dnsmasq/patches/patch-man_dnsmasq_8,v
retrieving revision 1.24
diff -u -p -r1.24 patch-man_dnsmasq_8
--- patches/patch-man_dnsmasq_8 29 Mar 2018 19:42:51 -0000      1.24
+++ patches/patch-man_dnsmasq_8 16 Jan 2019 00:22:16 -0000
@@ -2,7 +2,7 @@ $OpenBSD: patch-man_dnsmasq_8,v 1.24 201
 Index: man/dnsmasq.8
 --- man/dnsmasq.8.orig
 +++ man/dnsmasq.8
-@@ -151,13 +151,12 @@ Specify an alternate path for dnsmasq to record its pr
+@@ -151,7 +151,7 @@ Specify an alternate path for dnsmasq to record its pr
  .TP
  .B \-u, --user=<username>
  Specify the userid to which dnsmasq will change after startup. Dnsmasq must 
normally be started as root, but it will drop root 
@@ -11,14 +11,7 @@ Index: man/dnsmasq.8
  can be over-ridden with this switch.
  .TP
  .B \-g, --group=<groupname> 
- Specify the group which dnsmasq will run
--as. The defaults to "dip", if available, to facilitate access to
--/etc/ppp/resolv.conf which is not normally world readable.
-+as. This defaults to "_dnsmasq".
- .TP
- .B \-v, --version
- Print the version number.
-@@ -1914,7 +1913,7 @@ in the configuration file included. Secondly, the file
+@@ -1944,7 +1944,7 @@ in the configuration file included. Secondly, the file
  therein is updated when dnsmasq receives SIGHUP.
  .SH CONFIG FILE
  At startup, dnsmasq reads
@@ -27,7 +20,7 @@ Index: man/dnsmasq.8
  if it exists. (On
  FreeBSD, the file is 
  .I /usr/local/etc/dnsmasq.conf
-@@ -2367,7 +2366,7 @@ dnsmasq has no direct way of determining the charset i
+@@ -2397,7 +2397,7 @@ dnsmasq has no direct way of determining the charset i
  assume that it is the system default. 
   
  .SH FILES
Index: patches/patch-src_config_h
===================================================================
RCS file: /cvs/ports/net/dnsmasq/patches/patch-src_config_h,v
retrieving revision 1.20
diff -u -p -r1.20 patch-src_config_h
--- patches/patch-src_config_h  29 Mar 2018 19:42:51 -0000      1.20
+++ patches/patch-src_config_h  16 Jan 2019 00:22:16 -0000
@@ -13,7 +13,7 @@ Index: src/config.h
  #define TFTP_MAX_CONNECTIONS 50 /* max simultaneous connections */
  #define LOG_MAX 5 /* log-queue length */
  #define RANDFILE "/dev/urandom"
-@@ -198,7 +198,7 @@ RESOLVFILE
+@@ -206,7 +206,7 @@ RESOLVFILE
  #   if defined(__FreeBSD__)
  #      define CONFFILE "/usr/local/etc/dnsmasq.conf"
  #   else
Index: patches/patch-src_dnsmasq_c
===================================================================
RCS file: patches/patch-src_dnsmasq_c
diff -N patches/patch-src_dnsmasq_c
--- patches/patch-src_dnsmasq_c 29 Mar 2018 19:42:51 -0000      1.5
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,16 +0,0 @@
-$OpenBSD: patch-src_dnsmasq_c,v 1.5 2018/03/29 19:42:51 ajacoutot Exp $
-
-Fails. Currently disabled pending investigation.
-
-Index: src/dnsmasq.c
---- src/dnsmasq.c.orig
-+++ src/dnsmasq.c
-@@ -149,7 +149,7 @@ int main (int argc, char **argv)
-       open("/dev/null", O_RDWR); 
- 
- #ifndef HAVE_LINUX_NETWORK
--#  if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && 
defined(IP_SENDSRCADDR))
-+#  if defined(__OpenBSD__) || !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) 
&& defined(IP_SENDSRCADDR))
-   if (!option_bool(OPT_NOWILD))
-     {
-       bind_fallback = 1;
Index: patches/patch-src_forward_c
===================================================================
RCS file: /cvs/ports/net/dnsmasq/patches/patch-src_forward_c,v
retrieving revision 1.1
diff -u -p -r1.1 patch-src_forward_c
--- patches/patch-src_forward_c 16 Apr 2017 10:40:07 -0000      1.1
+++ patches/patch-src_forward_c 16 Jan 2019 00:22:16 -0000
@@ -1,24 +1,52 @@
-$OpenBSD: patch-src_forward_c,v 1.1 2017/04/16 10:40:07 sthen Exp $
+$OpenBSD$
 
-Fails. Currently disabled pending investigation.
+Don't mix up msg_controllen and cmsg_len.
+Don't ignore EINVAL unless on Linux.
 
---- src/forward.c.orig Sat Apr 15 22:36:04 2017
-+++ src/forward.c      Sat Apr 15 22:46:09 2017
-@@ -35,7 +35,7 @@ int send_from(int fd, int nowild, char *packet, size_t
-     struct cmsghdr align; /* this ensures alignment */
- #if defined(HAVE_LINUX_NETWORK)
-     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
--#elif defined(IP_SENDSRCADDR)
-+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR)
-     char control[CMSG_SPACE(sizeof(struct in_addr))];
- #endif
- #ifdef HAVE_IPV6
-@@ -71,7 +71,7 @@ int send_from(int fd, int nowild, char *packet, size_t
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_pktinfo));
+Index: src/forward.c
+--- src/forward.c.orig
++++ src/forward.c
+@@ -68,12 +68,14 @@ int send_from(int fd, int nowild, char *packet, size_t
+         p.ipi_ifindex = 0;
+         p.ipi_spec_dst = source->addr.addr4;
+         memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_pktinfo));
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
          cmptr->cmsg_level = IPPROTO_IP;
          cmptr->cmsg_type = IP_PKTINFO;
--#elif defined(IP_SENDSRCADDR)
-+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR)
+ #elif defined(IP_SENDSRCADDR)
          memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), 
sizeof(source->addr.addr4));
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_addr));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_addr));
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
          cmptr->cmsg_level = IPPROTO_IP;
+         cmptr->cmsg_type = IP_SENDSRCADDR;
+ #endif
+@@ -85,7 +87,8 @@ int send_from(int fd, int nowild, char *packet, size_t
+         p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local 
addrs */
+         p.ipi6_addr = source->addr.addr6;
+         memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in6_pktinfo));
++        msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+         cmptr->cmsg_type = daemon->v6pktinfo;
+         cmptr->cmsg_level = IPPROTO_IPV6;
+       }
+@@ -96,10 +99,13 @@ int send_from(int fd, int nowild, char *packet, size_t
+   
+   while (retry_send(sendmsg(fd, &msg, 0)));
+ 
+-  /* If interface is still in DAD, EINVAL results - ignore that. */
+-  if (errno != 0 && errno != EINVAL)
++  if (errno != 0)
+     {
+-      my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
++#ifdef __linux__
++      /* If interface is still in DAD, EINVAL results - ignore that. */
++      if (errno != EINVAL)
++#endif
++        my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
+       return 0;
+     }
+   


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to