From 95c81c5d77398517c5d84c4eb2704732a3fb9a41 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 4 Sep 2014 23:54:24 +0200 Subject: Support dynamic binds with extra options (interface binds, specific addresses...) --- src/fastd.c | 30 +++++++++++++++++++++++++----- src/socket.c | 16 ++++++++++++++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/fastd.c b/src/fastd.c index 83d360b..da4268e 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -146,6 +146,21 @@ static inline void close_log(void) { } +/** Return's an address's port (in network byte order) */ +static inline uint16_t get_bind_port(const fastd_bind_address_t *addr) { + switch (addr->addr.sa.sa_family) { + case AF_UNSPEC: + case AF_INET: + return addr->addr.in.sin_port; + + case AF_INET6: + return addr->addr.in6.sin6_port; + + default: + exit_bug("unsupported address family"); + } +} + /** Initializes the configured sockets */ static void init_sockets(void) { ctx.socks = fastd_new_array(conf.n_bind_addrs, fastd_socket_t); @@ -153,13 +168,18 @@ static void init_sockets(void) { size_t i; fastd_bind_address_t *addr = conf.bind_addrs; for (i = 0; i < conf.n_bind_addrs; i++) { - ctx.socks[i] = (fastd_socket_t){ .fd = -2, .addr = addr }; + if (get_bind_port(addr)) { + ctx.socks[i] = (fastd_socket_t){ .fd = -2, .addr = addr }; - if (addr == conf.bind_addr_default_v4) - ctx.sock_default_v4 = &ctx.socks[i]; + if (addr == conf.bind_addr_default_v4) + ctx.sock_default_v4 = &ctx.socks[i]; - if (addr == conf.bind_addr_default_v6) - ctx.sock_default_v6 = &ctx.socks[i]; + if (addr == conf.bind_addr_default_v6) + ctx.sock_default_v6 = &ctx.socks[i]; + } + else { + ctx.socks[i] = (fastd_socket_t){ .fd = -1, .addr = NULL }; + } addr = addr->next; } diff --git a/src/socket.c b/src/socket.c index 7d78b7f..e72ec94 100644 --- a/src/socket.c +++ b/src/socket.c @@ -199,6 +199,9 @@ bool fastd_socket_handle_binds(void) { if (ctx.socks[i].fd >= 0) continue; + if (!ctx.socks[i].addr) + continue; + ctx.socks[i].fd = bind_socket(ctx.socks[i].addr, ctx.socks[i].fd < -1); if (ctx.socks[i].fd >= 0) { @@ -226,11 +229,20 @@ bool fastd_socket_handle_binds(void) { return true; } -/** Opens a single unbound socket for the given address family */ +/** Opens a single socket bound to a random port for the given address family */ fastd_socket_t * fastd_socket_open(fastd_peer_t *peer, int af) { const fastd_bind_address_t any_address = { .addr.sa.sa_family = af }; - int fd = bind_socket(&any_address, true); + const fastd_bind_address_t *bind_address; + + if (af == AF_INET && conf.bind_addr_default_v4) + bind_address = conf.bind_addr_default_v4; + else if (af == AF_INET6 && conf.bind_addr_default_v6) + bind_address = conf.bind_addr_default_v6; + else + bind_address = &any_address; + + int fd = bind_socket(bind_address, true); if (fd < 0) return NULL; -- cgit v1.2.3