summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-28 16:54:06 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-28 16:54:06 +0200
commit318acb0f6cb77a32aad5d7f79e06f3c5065ac702 (patch)
tree4dba6f78145f0fcb65c228bbc7e3ad1559e4a6a3 /sysdep
parent0ed3129f6b0a80afea877340d940e45f1a5d3000 (diff)
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).
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/sysio.h5
-rw-r--r--sysdep/cf/README1
-rw-r--r--sysdep/unix/io.c8
3 files changed, 13 insertions, 1 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h
index 68296e65..a5d161ba 100644
--- a/sysdep/bsd/sysio.h
+++ b/sysdep/bsd/sysio.h
@@ -12,6 +12,11 @@
#include <sys/param.h>
+#ifdef __FreeBSD__
+/* Should be defined in sysdep/cf/bsd.h, but it is flavor-specific */
+#define CONFIG_DONTROUTE_UNICAST
+#endif
+
#ifdef __NetBSD__
#ifndef IP_RECVTTL
diff --git a/sysdep/cf/README b/sysdep/cf/README
index e62c3481..9a7a4afa 100644
--- a/sysdep/cf/README
+++ b/sysdep/cf/README
@@ -11,6 +11,7 @@ CONFIG_MC_PROPER_SRC Multicast packets have source address according to socket s
CONFIG_SKIP_MC_BIND Don't call bind on multicast socket (def for *BSD)
CONFIG_NO_IFACE_BIND Bind to iface is not available, use workarounds (def for *BSD)
CONFIG_UNIX_DONTROUTE Use setsockopts DONTROUTE (undef for *BSD)
+CONFIG_DONTROUTE_UNICAST Use MSG_DONTROUTE flag for unicast packets (def for FreeBSD)
CONFIG_USE_HDRINCL Use IP_HDRINCL instead of control messages for source address on raw IP sockets.
CONFIG_RESTRICTED_PRIVILEGES Implements restricted privileges using drop_uid()
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