From 8e3f4f0bc1c676d68821f818060ad6d5d9e90904 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 31 Jan 2025 11:38:55 -0400 Subject: [PATCH] MT#62053 refactor interface parsing code Split up the function into one part that parses out the string, and another part that handles the individual pieces of information. Switch to bool types and const arguments where appropriate. Change-Id: If3ec8a048dbe1141dfc0b1150b69eb445216aad1 --- daemon/main.c | 125 +++++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 58 deletions(-) diff --git a/daemon/main.c b/daemon/main.c index ca55440ef..53567b674 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -188,7 +188,7 @@ static void signals(void) { -static void __find_if_name(char *s, struct ifaddrs *ifas, GQueue *addrs) { +static void __find_if_name(const char *s, struct ifaddrs *ifas, GQueue *addrs) { sockaddr_t *addr; for (struct ifaddrs *ifa = ifas; ifa; ifa = ifa->ifa_next) { @@ -232,7 +232,7 @@ static void __find_if_name(char *s, struct ifaddrs *ifas, GQueue *addrs) { } } -static void __resolve_ifname(char *s, GQueue *addrs) { +static void __resolve_ifname(const char *s, GQueue *addrs) { struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, @@ -273,87 +273,66 @@ static void __resolve_ifname(char *s, GQueue *addrs) { freeaddrinfo(res); } -static int if_addr_parse(intf_config_q *q, char *s, struct ifaddrs *ifas) { - str name; - char *c; - sockaddr_t *addr, adv; - GQueue addrs = G_QUEUE_INIT; - struct intf_config *ifa; - - while (*s == ' ') - s++; - - /* name */ - c = strpbrk(s, "/="); - if (c) { - char cc = *c; - *c++ = 0; - name = STR(s); - s = c; - if (cc == '=') { - // foo=bar - ifa = g_slice_alloc0(sizeof(*ifa)); - ifa->name = str_dup_str(&name); - ifa->alias = STR_DUP(s); - t_queue_push_tail(q, ifa); - return 0; - } - } - else - name = STR("default"); +static void if_add_alias(intf_config_q *q, const str *name, const char *alias) { + struct intf_config *ifa = g_slice_alloc0(sizeof(*ifa)); + ifa->name = str_dup_str(name); + ifa->alias = STR_DUP(alias); + t_queue_push_tail(q, ifa); +} - /* advertised address */ - c = strchr(s, '!'); - if (c) - *c++ = 0; +static bool if_add(intf_config_q *q, struct ifaddrs *ifas, const str *name, + const char *address, const char *adv_addr, + unsigned int port_min, unsigned int port_max) +{ + GQueue addrs = G_QUEUE_INIT; /* address */ - addr = g_slice_alloc(sizeof(*addr)); - if (!sockaddr_parse_any(addr, s)) { + sockaddr_t *addr = g_slice_alloc(sizeof(*addr)); + if (!sockaddr_parse_any(addr, address)) { if (is_addr_unspecified(addr)) - return -1; + return false; g_queue_push_tail(&addrs, addr); } else { g_slice_free1(sizeof(*addr), addr); // could be an interface name? ilog(LOG_DEBUG, "Could not parse '%s' as network address, checking to see if " - "it's an interface", s); - __find_if_name(s, ifas, &addrs); + "it's an interface", address); + __find_if_name(address, ifas, &addrs); if (!addrs.length) { - ilog(LOG_DEBUG, "'%s' is not an interface, attempting to resolve it as DNS host name", s); - __resolve_ifname(s, &addrs); + ilog(LOG_DEBUG, "'%s' is not an interface, attempting to resolve it as DNS host name", address); + __resolve_ifname(address, &addrs); } } if (!addrs.length) // nothing found - return -1; - - ZERO(adv); - if (c) { - if (sockaddr_parse_any(&adv, c)) { - ilog(LOG_DEBUG, "Could not parse '%s' as an address, attempting DNS lookup", c); - if (sockaddr_getaddrinfo(&adv, c)) { - ilog(LOG_WARN, "DNS lookup for '%s' failed", c); - return -1; + return false; + + sockaddr_t adv = {0}; + if (adv_addr) { + if (sockaddr_parse_any(&adv, adv_addr)) { + ilog(LOG_DEBUG, "Could not parse '%s' as an address, attempting DNS lookup", adv_addr); + if (sockaddr_getaddrinfo(&adv, adv_addr)) { + ilog(LOG_WARN, "DNS lookup for '%s' failed", adv_addr); + return false; } } if (is_addr_unspecified(&adv)) - return -1; + return false; } while ((addr = g_queue_pop_head(&addrs))) { - ifa = g_slice_alloc0(sizeof(*ifa)); - ifa->name = str_dup_str(&name); + struct intf_config *ifa = g_slice_alloc0(sizeof(*ifa)); + ifa->name = str_dup_str(name); ifa->local_address.addr = *addr; ifa->local_address.type = socktype_udp; ifa->advertised_address.addr = adv; if (is_addr_unspecified(&ifa->advertised_address.addr)) ifa->advertised_address.addr = *addr; ifa->advertised_address.type = ifa->local_address.type; - ifa->port_min = rtpe_config.port_min; - ifa->port_max = rtpe_config.port_max; + ifa->port_min = port_min; + ifa->port_max = port_max; // handle "base:suffix" separation for round-robin selection ifa->name_rr_spec = ifa->name; @@ -364,7 +343,38 @@ static int if_addr_parse(intf_config_q *q, char *s, struct ifaddrs *ifas) { g_slice_free1(sizeof(*addr), addr); } - return 0; + return true; +} + +static bool if_addr_parse(intf_config_q *q, char *s, struct ifaddrs *ifas) { + str name; + char *c; + + while (*s == ' ') + s++; + + /* name */ + c = strpbrk(s, "/="); + if (c) { + char cc = *c; + *c++ = 0; + name = STR(s); + s = c; + if (cc == '=') { + // foo=bar + if_add_alias(q, &name, s); + return true; + } + } + else + name = STR("default"); + + /* advertised address */ + c = strchr(s, '!'); + if (c) + *c++ = 0; + + return if_add(q, ifas, &name, s, c, rtpe_config.port_min, rtpe_config.port_max); } @@ -815,8 +825,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { ilog(LOG_WARN, "Failed to retrieve list of network interfaces: %s", strerror(errno)); } for (iter = if_a; *iter; iter++) { - int ret = if_addr_parse(&rtpe_config.interfaces, *iter, ifas); - if (ret) + if (!if_addr_parse(&rtpe_config.interfaces, *iter, ifas)) die("Invalid interface specification: '%s'", *iter); } if (ifas)