summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2024-10-01 10:42:36 +0200
committerVladimír Čunát <vladimir.cunat@nic.cz>2024-10-01 12:33:36 +0200
commit77e1a4c07f388db38230fabe2b8250d0cb1c1da5 (patch)
tree4c3fcb5d0a5584af4c952475d66178ccea0dee29 /lib
parentMerge branch 'master' into rrl-wip (diff)
downloadknot-resolver-77e1a4c07f388db38230fabe2b8250d0cb1c1da5.tar.xz
knot-resolver-77e1a4c07f388db38230fabe2b8250d0cb1c1da5.zip
lib/utils: deduplicate kr_straddr_socket* + describe
Diffstat (limited to 'lib')
-rw-r--r--lib/utils.c71
-rw-r--r--lib/utils.h1
2 files changed, 22 insertions, 50 deletions
diff --git a/lib/utils.c b/lib/utils.c
index 3af2fd04..fb297788 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -562,73 +562,44 @@ int kr_family_len(int family)
}
}
-struct sockaddr * kr_straddr_socket(const char *addr, int port, knot_mm_t *pool)
+/// Construct *sa from family + *addr + port.
+static int straddr_socket(struct sockaddr *sa, int family, const char *addr, int port)
{
- switch (kr_straddr_family(addr)) {
+ switch (family) {
case AF_INET: {
- struct sockaddr_in *res = mm_alloc(pool, sizeof(*res));
- if (uv_ip4_addr(addr, port, res) >= 0) {
- return (struct sockaddr *)res;
- } else {
- mm_free(pool, res);
- return NULL;
- }
+ return uv_ip4_addr(addr, port, (struct sockaddr_in *)sa);
}
case AF_INET6: {
- struct sockaddr_in6 *res = mm_alloc(pool, sizeof(*res));
- if (uv_ip6_addr(addr, port, res) >= 0) {
- return (struct sockaddr *)res;
- } else {
- mm_free(pool, res);
- return NULL;
- }
+ return uv_ip6_addr(addr, port, (struct sockaddr_in6 *)sa);
}
case AF_UNIX: {
- struct sockaddr_un *res;
+ struct sockaddr_un *res = (struct sockaddr_un *)sa;
const size_t alen = strlen(addr) + 1;
if (alen > sizeof(res->sun_path)) {
- return NULL;
+ return kr_error(ENAMETOOLONG);
}
- res = mm_alloc(pool, sizeof(*res));
res->sun_family = AF_UNIX;
memcpy(res->sun_path, addr, alen);
- return (struct sockaddr *)res;
+ return kr_ok();
}
default:
- return NULL;
+ return kr_error(EINVAL);
}
}
-
struct sockaddr * kr_straddr_socket_set(struct sockaddr *sa, const char *addr, int port)
{
- switch (kr_straddr_family(addr)) {
- case AF_INET: {
- struct sockaddr_in *res = (struct sockaddr_in *) sa;
- if (uv_ip4_addr(addr, port, res) >= 0) {
- return sa;
- } else {
- return NULL;
- }
- }
- case AF_INET6: {
- struct sockaddr_in6 *res = (struct sockaddr_in6 *) sa;
- if (uv_ip6_addr(addr, port, res) >= 0) {
- return sa;
- } else {
- return NULL;
- }
- }
- case AF_UNIX: {
- struct sockaddr_un *res = (struct sockaddr_un *) sa;
- const size_t alen = strlen(addr) + 1;
- if (alen > sizeof(res->sun_path)) {
- return NULL;
- }
- res->sun_family = AF_UNIX;
- memcpy(res->sun_path, addr, alen);
- return sa;
- }
- default:
+ return straddr_socket(sa, kr_straddr_family(addr), addr, port) >= 0 ? sa : NULL;
+}
+struct sockaddr * kr_straddr_socket(const char *addr, int port, knot_mm_t *pool)
+{
+ int family = kr_straddr_family(addr);
+ if (family < 0) return NULL;
+ struct sockaddr sa = { .sa_family = family };
+ struct sockaddr *res = mm_alloc(pool, kr_sockaddr_len(&sa));
+ if (straddr_socket(res, family, addr, port) >= 0) {
+ return res;
+ } else {
+ mm_free(pool, res);
return NULL;
}
}
diff --git a/lib/utils.h b/lib/utils.h
index 8c1ef8c1..b6b350c8 100644
--- a/lib/utils.h
+++ b/lib/utils.h
@@ -353,6 +353,7 @@ int kr_family_len(int family);
* Also accepts IPv6 link-local and AF_UNIX starting with "/" (ignoring port) */
KR_EXPORT
struct sockaddr * kr_straddr_socket(const char *addr, int port, knot_mm_t *pool);
+/** Like kr_straddr_socket() but use `sa` instead of allocating. */
KR_EXPORT
struct sockaddr * kr_straddr_socket_set(struct sockaddr *sa, const char *addr, int port);