From 6299bdbf043354d7f66d9a0630b7d03fd7e2d85b Mon Sep 17 00:00:00 2001
From: Andrew Scott <git@andyscott.me>
Date: Sat, 26 Oct 2024 15:51:30 -0400
Subject: [PATCH 1/2] src/common: return -1 from get_addr on error

getaddrinfo will typically return negative values for errors, but this
is not the case for all systems. For example, glibc defines the errors
as negative, but the WSA equivalents are all positive. This commit
unifies the approach within iodine by always returning -1 in the event
getaddrinfo is unsuccessful.
---
 src/common.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/common.c b/src/common.c
index 8d2fec0..e7d49c3 100644
--- a/src/common.c
+++ b/src/common.c
@@ -142,6 +142,7 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora
 	struct addrinfo hints, *addr;
 	int res;
 	char portnum[8];
+	int addrlen;
 
 	memset(portnum, 0, sizeof(portnum));
 	snprintf(portnum, sizeof(portnum) - 1, "%d", port);
@@ -158,14 +159,15 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora
 	hints.ai_protocol = IPPROTO_UDP;
 
 	res = getaddrinfo(host, portnum, &hints, &addr);
-	if (res == 0) {
-		int addrlen = addr->ai_addrlen;
-		/* Grab first result */
-		memcpy(out, addr->ai_addr, addr->ai_addrlen);
-		freeaddrinfo(addr);
-		return addrlen;
+	if (res != 0) {
+		return -1;
 	}
-	return res;
+	
+	addrlen = addr->ai_addrlen;
+	/* Grab first result */
+	memcpy(out, addr->ai_addr, addr->ai_addrlen);
+	freeaddrinfo(addr);
+	return addrlen;
 }
 
 int

From ae43de2a8cfb3537596c5813d11b756d0c5533e3 Mon Sep 17 00:00:00 2001
From: Andrew Scott <git@andyscott.me>
Date: Sat, 26 Oct 2024 16:02:44 -0400
Subject: [PATCH 2/2] tests/common: add test for get_addr errors

---
 tests/common.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tests/common.c b/tests/common.c
index 87fe330..1405051 100644
--- a/tests/common.c
+++ b/tests/common.c
@@ -280,6 +280,28 @@ START_TEST(test_parse_format_ipv4_mapped_ipv6)
 }
 END_TEST
 
+START_TEST(test_get_addr_err)
+{
+	char *host = "192.168.2.10";
+	struct sockaddr_storage addr;
+	int addr_len;
+	int flags = AI_PASSIVE;
+
+	/* Invalid host */
+	addr_len = get_addr(NULL, -1, flags, 0, &addr);
+	ck_assert(addr_len == -1);
+	/* Invalid port */
+	addr_len = get_addr(host, -1, flags, 0, &addr);
+	ck_assert(addr_len == -1);
+	/* Invalid flag */
+	addr_len = get_addr(host, 53, flags | 0xFFF, 0, &addr);
+	ck_assert(addr_len == -1);
+	/* Invalid addr */
+	addr_len = get_addr(host, 53, flags, 0, (struct sockaddr_storage *)NULL);
+	ck_assert(addr_len == -1);
+}
+END_TEST
+
 TCase *
 test_common_create_tests(void)
 {
@@ -295,6 +317,7 @@ test_common_create_tests(void)
 	tcase_add_test(tc, test_query_datalen_wild);
 	tcase_add_test(tc, test_parse_format_ipv4);
 	tcase_add_test(tc, test_parse_format_ipv4_listen_all);
+	tcase_add_test(tc, test_get_addr_err);
 
 	/* Tests require IPv6 support */
 	sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);