From 318acb0f6cb77a32aad5d7f79e06f3c5065ac702 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Sat, 28 Jul 2018 16:54:06 +0200 Subject: BSD: Use MSG_DONTROUTE for unicast packets on FreeBSD BSD systems cannot use SO_DONTROUTE, because it does not work properly with multicast packets (perhaps it tries to find iface based on multicast group address). But we can use MSG_DONTROUTE sendmsg() flag for unicast packets. Works on FreeBSD, is ignored on OpenBSD and is broken on NetBSD (i guess due to integrated routing table and ARP table). --- sysdep/unix/io.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sysdep/unix') diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 11a0d6f1..a960b7f8 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1541,6 +1541,7 @@ sk_sendmsg(sock *s) struct iovec iov = {s->tbuf, s->tpos - s->tbuf}; byte cmsg_buf[CMSG_TX_SPACE]; sockaddr dst; + int flags = 0; sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport); @@ -1551,6 +1552,11 @@ sk_sendmsg(sock *s) .msg_iovlen = 1 }; +#ifdef CONFIG_DONTROUTE_UNICAST + if (ipa_is_ip4(s->daddr) && ip4_is_unicast(ipa_to_ip4(s->daddr))) + flags = MSG_DONTROUTE; +#endif + #ifdef CONFIG_USE_HDRINCL byte hdr[20]; struct iovec iov2[2] = { {hdr, 20}, iov }; @@ -1566,7 +1572,7 @@ sk_sendmsg(sock *s) if (s->flags & SKF_PKTINFO) sk_prepare_cmsgs(s, &msg, cmsg_buf, sizeof(cmsg_buf)); - return sendmsg(s->fd, &msg, 0); + return sendmsg(s->fd, &msg, flags); } static inline int -- cgit v1.2.3