So a while back Alexander Markert sent a bug report regarding sendmsg() behaviour with IP_SENDSRCADDR :
https://marc.info/?l=openbsd-tech&m=149276833923905&w=2 This impacts our dnsmasq port : https://marc.info/?l=openbsd-tech&m=149234052220818&w=2 Alexander Markert shows in the first thread the problematic code and conditions. To save you the trip back in time : sendfrom() returns EWOULDBLOCK (or blocks if using blocking IO) when len(cmsg) + len(data) > len(socket.buffer). The better behaviour would be to never block and return EMSGSIZE. The first diff fixes the kernel code ; The second diff reverts https://marc.info/?l=openbsd-ports-cvs&m=149233921320572&w=2 and fixes a bad cmsg setup. 1) Can you confirm this fixes dnsmasq ? or whatever you used to trigger the bug ? 2) Ok ? (apologies for the delay by the way :S ) -- 8< ---- 8< ---- 8< -- Index: sys/kern/uipc_socket.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_socket.c,v retrieving revision 1.224 diff -u -p -r1.224 uipc_socket.c --- sys/kern/uipc_socket.c 14 Jun 2018 08:46:09 -0000 1.224 +++ sys/kern/uipc_socket.c 26 Jun 2018 18:51:49 -0000 @@ -459,9 +459,10 @@ restart: space = sbspace(so, &so->so_snd); if (flags & MSG_OOB) space += 1024; - if ((atomic && resid > so->so_snd.sb_hiwat) || + if ((so->so_proto->pr_domain->dom_family == AF_UNIX && + atomic && resid > so->so_snd.sb_hiwat) || (so->so_proto->pr_domain->dom_family != AF_UNIX && - clen > so->so_snd.sb_hiwat)) + clen + (atomic ? resid : 0) > so->so_snd.sb_hiwat)) snderr(EMSGSIZE); if (space < clen || (space - clen < resid && -- 8< ---- 8< ---- 8< -- Index: net/dnsmasq/patches/patch-src_dnsmasq_c =================================================================== RCS file: net/dnsmasq/patches/patch-src_dnsmasq_c diff -N net/dnsmasq/patches/patch-src_dnsmasq_c --- net/dnsmasq/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: net/dnsmasq/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 --- net/dnsmasq/patches/patch-src_forward_c 16 Apr 2017 10:40:07 -0000 1.1 +++ net/dnsmasq/patches/patch-src_forward_c 26 Jun 2018 18:48:17 -0000 @@ -1,24 +1,17 @@ -$OpenBSD: patch-src_forward_c,v 1.1 2017/04/16 10:40:07 sthen Exp $ +$OpenBSD$ -Fails. Currently disabled pending investigation. +CMSG_SPACE() != CMSG_LEN() ---- 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)); - cmptr->cmsg_level = IPPROTO_IP; +Index: src/forward.c +--- src/forward.c.orig ++++ src/forward.c +@@ -73,7 +73,8 @@ int send_from(int fd, int nowild, char *packet, size_t 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 = sizeof(control_u.control); ++ cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); cmptr->cmsg_level = IPPROTO_IP; + cmptr->cmsg_type = IP_SENDSRCADDR; + #endif