summaryrefslogtreecommitdiff
path: root/llmnr.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2017-01-10 15:54:52 +0100
committerTobias Klauser <tklauser@distanz.ch>2017-01-10 15:54:52 +0100
commite9cd5a6826f198029ee466ae63d56dca4dfa4ad7 (patch)
treecb259a1fc5cbb2b8bef965ea0f968b056fefbd5d /llmnr.c
parent6281d3c3633fb1de98ff6010212325e45c226f3c (diff)
llmnrd: merge rtnl interface event loop into main select() loops
Instead of spawming a thread for the sole purpose of watching the rtnl for (presumably) seldom events, just merge the select() for all sockets together in one single main loop. This reduces unnecessary complexity and makes llmnrd no longer require any locking. It also allows us to handle signals in a thread-safe manner (as there aren't any ;) and thus the race condition on exit reported in #20 Closes #20 Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'llmnr.c')
-rw-r--r--llmnr.c89
1 files changed, 6 insertions, 83 deletions
diff --git a/llmnr.c b/llmnr.c
index 17926a7..73f5168 100644
--- a/llmnr.c
+++ b/llmnr.c
@@ -37,52 +37,17 @@
#include "llmnr-packet.h"
#include "llmnr.h"
-static int llmnr_sock_ipv4 = -1;
-static int llmnr_sock_ipv6 = -1;
-static bool llmnr_running = true;
-/*
- * Host name in DNS name format (length octet + name + 0 byte)
- */
+static bool llmnr_ipv6 = false;
+/* Host name in DNS name format (length octet + name + 0 byte) */
static char llmnr_hostname[LLMNR_LABEL_MAX_SIZE + 2];
-static void llmnr_iface_event_handle(enum iface_event_type type, unsigned char af,
- unsigned int ifindex)
-{
- switch (af) {
- case AF_INET:
- socket_mcast_group_ipv4(llmnr_sock_ipv4, ifindex, type == IFACE_ADD);
- break;
- case AF_INET6:
- socket_mcast_group_ipv6(llmnr_sock_ipv6, ifindex, type == IFACE_ADD);
- break;
- default:
- /* ignore */
- break;
- }
-}
-
-int llmnr_init(const char *hostname, uint16_t port, bool ipv6, const char *iface)
+void llmnr_init(const char *hostname, bool ipv6)
{
llmnr_hostname[0] = strlen(hostname);
strncpy(&llmnr_hostname[1], hostname, LLMNR_LABEL_MAX_SIZE);
llmnr_hostname[LLMNR_LABEL_MAX_SIZE + 1] = '\0';
- log_info("Starting llmnrd on port %u, hostname %s\n", port, hostname);
- if (iface)
- log_info("Binding to interface %s\n", iface);
-
- llmnr_sock_ipv4 = socket_open_ipv4(port, iface);
- if (llmnr_sock_ipv4 < 0)
- return -1;
-
- if (ipv6) {
- llmnr_sock_ipv6 = socket_open_ipv6(port, iface);
- if (llmnr_sock_ipv6 < 0)
- return -1;
- }
-
- iface_register_event_handler(&llmnr_iface_event_handle);
- return 0;
+ llmnr_ipv6 = ipv6;
}
static bool llmnr_name_matches(const uint8_t *query)
@@ -134,7 +99,7 @@ static void llmnr_respond(unsigned int ifindex, const struct llmnr_hdr *hdr,
return;
/* No AAAA responses if IPv6 is disabled */
- if (llmnr_sock_ipv6 < 0 && qtype == LLMNR_QTYPE_AAAA)
+ if (llmnr_ipv6 < 0 && qtype == LLMNR_QTYPE_AAAA)
return;
switch (qtype) {
@@ -254,7 +219,7 @@ static void llmnr_packet_process(unsigned int ifindex, const uint8_t *pktbuf, si
llmnr_respond(ifindex, hdr, query, query_len, sock, sst);
}
-static void llmnr_recv(int sock)
+void llmnr_recv(int sock)
{
uint8_t pktbuf[2048], aux[128];
struct msghdr msg;
@@ -297,45 +262,3 @@ static void llmnr_recv(int sock)
else
log_warn("Could not get interface of incoming packet\n");
}
-
-int llmnr_run(void)
-{
- int ret = -1;
-
- while (llmnr_running) {
- fd_set rfds;
- int nfds, ret;
-
- FD_ZERO(&rfds);
- FD_SET(llmnr_sock_ipv4, &rfds);
- if (llmnr_sock_ipv6 >= 0) {
- FD_SET(llmnr_sock_ipv6, &rfds);
- nfds = max(llmnr_sock_ipv4, llmnr_sock_ipv6) + 1;
- } else
- nfds = llmnr_sock_ipv4 + 1;
-
- ret = select(nfds, &rfds, NULL, NULL, NULL);
- if (ret < 0) {
- if (errno != EINTR)
- log_err("Failed to select() on socket: %s\n", strerror(errno));
- goto out;
- } else if (ret) {
- if (FD_ISSET(llmnr_sock_ipv4, &rfds))
- llmnr_recv(llmnr_sock_ipv4);
- if (llmnr_sock_ipv6 >= 0 && FD_ISSET(llmnr_sock_ipv6, &rfds))
- llmnr_recv(llmnr_sock_ipv6);
- }
- }
-
- ret = 0;
-out:
- close(llmnr_sock_ipv4);
- if (llmnr_sock_ipv6 >= 0)
- close(llmnr_sock_ipv6);
- return ret;
-}
-
-void llmnr_stop(void)
-{
- llmnr_running = false;
-}