diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/bsd/sysio.h | 6 | ||||
-rw-r--r-- | sysdep/linux/sysio.h | 19 | ||||
-rw-r--r-- | sysdep/unix/io.c | 4 |
3 files changed, 29 insertions, 0 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h index c757960a..f1887fb4 100644 --- a/sysdep/bsd/sysio.h +++ b/sysdep/bsd/sysio.h @@ -271,3 +271,9 @@ sk_set_priority(sock *s, int prio UNUSED) { ERR_MSG("Socket priority not supported"); } + +static inline int +sk_set_freebind(sock *s) +{ + ERR_MSG("Freebind is not supported"); +} diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index e21ff487..f13eda7c 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -10,6 +10,10 @@ #define IPV6_MINHOPCOUNT 73 #endif +#ifndef IPV6_FREEBIND +#define IPV6_FREEBIND 78 +#endif + #ifndef TCP_MD5SIG_EXT #define TCP_MD5SIG_EXT 32 #endif @@ -266,3 +270,18 @@ sk_set_priority(sock *s, int prio) return 0; } +static inline int +sk_set_freebind(sock *s) +{ + int y = 1; + + if (sk_is_ipv4(s)) + if (setsockopt(s->fd, SOL_IP, IP_FREEBIND, &y, sizeof(y)) < 0) + ERR("IP_FREEBIND"); + + if (sk_is_ipv6(s)) + if (setsockopt(s->fd, SOL_IPV6, IPV6_FREEBIND, &y, sizeof(y)) < 0) + ERR("IPV6_FREEBIND"); + + return 0; +} diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 3d67d0a7..4fd77453 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1436,6 +1436,10 @@ sk_open(sock *s) if (sk_set_high_port(s) < 0) log(L_WARN "Socket error: %s%#m", s->err); + if (s->flags & SKF_FREEBIND) + if (sk_set_freebind(s) < 0) + log(L_WARN "Socket error: %s%#m", s->err); + sockaddr_fill(&sa, s->af, bind_addr, s->iface, bind_port); if (bind(fd, &sa.sa, SA_LEN(sa)) < 0) ERR2("bind"); |