]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
sockaddr: improve compatibility with sockaddr_t
authorDaniel Salzman <daniel.salzman@nic.cz>
Tue, 10 Jan 2023 09:38:28 +0000 (10:38 +0100)
committerDaniel Salzman <daniel.salzman@nic.cz>
Fri, 13 Jan 2023 09:29:28 +0000 (10:29 +0100)
src/contrib/sockaddr.c
src/contrib/sockaddr.h

index f91c374d92aadaefa741c5ba7a4e995c4ad5fc56..fc5768bb47a1835545a7de29fe30da04d1435a73 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <netdb.h>
@@ -37,7 +38,8 @@ int sockaddr_len(const struct sockaddr_storage *ss)
        case AF_INET6:
                return sizeof(struct sockaddr_in6);
        case AF_UNIX:
-               return sizeof(struct sockaddr_un);
+               ; const struct sockaddr_un *un = (const struct sockaddr_un *)ss;
+               return offsetof(struct sockaddr_un, sun_path) + strlen(un->sun_path) + 1;
        default:
                return 0;
        }
@@ -157,7 +159,8 @@ void *sockaddr_raw(const struct sockaddr_storage *ss, size_t *addr_size)
                return &ipv6->sin6_addr;
        } else if (ss->ss_family == AF_UNIX) {
                struct sockaddr_un *un = (struct sockaddr_un *)ss;
-               *addr_size = sizeof(un->sun_path);
+               *addr_size = offsetof(struct sockaddr_un, sun_path) +
+                            strlen(un->sun_path) + 1;
                return un->sun_path;
        } else {
                return NULL;
@@ -178,7 +181,7 @@ int sockaddr_set_raw(struct sockaddr_storage *ss, int family,
        void *ss_data = sockaddr_raw(ss, &ss_size);
        if (ss_data == NULL ||
            (family != AF_UNIX && ss_size != raw_addr_size) ||
-           (family == AF_UNIX && ss_size <= raw_addr_size)) {
+           (family == AF_UNIX && raw_addr_size >= sizeof((struct sockaddr_un *)ss)->sun_path)) {
                return KNOT_EINVAL;
        }
 
@@ -331,22 +334,28 @@ bool sockaddr_net_match(const struct sockaddr_storage *ss1,
                return false;
        }
 
-       size_t raw_len = 0;
-       const uint8_t *raw_1 = sockaddr_raw(ss1, &raw_len);
-       const uint8_t *raw_2 = sockaddr_raw(ss2, &raw_len);
+       if (ss1->ss_family == AF_UNIX) {
+               const struct sockaddr_un *un1 = (const struct sockaddr_un *)ss1;
+               const struct sockaddr_un *un2 = (const struct sockaddr_un *)ss2;
+               return strcmp(un1->sun_path, un2->sun_path) == 0;
+       } else {
+               size_t raw_len = 0;
+               const uint8_t *raw_1 = sockaddr_raw(ss1, &raw_len);
+               const uint8_t *raw_2 = sockaddr_raw(ss2, &raw_len);
 
-       prefix = MIN(prefix, raw_len * 8);
-       unsigned bytes = prefix / 8;
-       unsigned bits = prefix % 8;
+               prefix = MIN(prefix, raw_len * 8);
+               unsigned bytes = prefix / 8;
+               unsigned bits = prefix % 8;
 
-       /* Compare full bytes. */
-       if (memcmp(raw_1, raw_2, bytes) != 0) {
-               return false;
-       }
+               /* Compare full bytes. */
+               if (memcmp(raw_1, raw_2, bytes) != 0) {
+                       return false;
+               }
 
-       /* Compare last partial byte. */
-       return bits == 0 ||
-              (raw_1[bytes] >> (8 - bits) == raw_2[bytes] >> (8 - bits));
+               /* Compare last partial byte. */
+               return bits == 0 ||
+                      (raw_1[bytes] >> (8 - bits) == raw_2[bytes] >> (8 - bits));
+       }
 }
 
 bool sockaddr_range_match(const struct sockaddr_storage *ss,
@@ -358,7 +367,8 @@ bool sockaddr_range_match(const struct sockaddr_storage *ss,
        }
 
        if (ss_min->ss_family != ss_max->ss_family ||
-           ss_min->ss_family != ss->ss_family) {
+           ss_min->ss_family != ss->ss_family ||
+           ss->ss_family == AF_UNIX) {
                return false;
        }
 
index e6f4d2fb51fdb5c887100c7c81eb3ca075882109..a6975b401f46add452e347ae5495093e301ed3a6 100644 (file)
@@ -57,7 +57,7 @@ typedef union __attribute__ ((aligned (8))) {
 /*!
  * \brief Calculate current structure length based on address family.
  *
- * \param ss  Socket address.
+ * \param ss  Socket address (can be sockaddr_t).
  *
  * \return Number of bytes or error code.
  */
@@ -66,8 +66,8 @@ int sockaddr_len(const struct sockaddr_storage *ss);
 /*!
  * \brief Compare addresses.
  *
- * \param a            First address.
- * \param b            Second address.
+ * \param a            First address (can be sockaddr_t).
+ * \param b            Second address (can be sockaddr_t).
  * \param ignore_port  Ignore port indication.
  *
  * \return like memcmp(3)
@@ -78,7 +78,7 @@ int sockaddr_cmp(const struct sockaddr_storage *a, const struct sockaddr_storage
 /*!
  * \brief Set address and port.
  *
- * \param ss       Socket address.
+ * \param ss       Socket address (CANNOT be sockaddr_t!).
  * \param family   Address family.
  * \param straddr  IP address in string format.
  * \param port     Port.
@@ -90,7 +90,7 @@ int sockaddr_set(struct sockaddr_storage *ss, int family, const char *straddr, i
 /*!
  * \brief Return raw network address in network byte order.
  *
- * \param[in]  ss        Socket address.
+ * \param[in]  ss        Socket address (can be sockaddr_t).
  * \param[out] addr_size Address length.
  *
  * \return Pointer to binary buffer of size addr_size.
@@ -100,7 +100,7 @@ void *sockaddr_raw(const struct sockaddr_storage *ss, size_t *addr_size);
 /*!
  * \brief Set raw address.
  *
- * \param ss             Socket address.
+ * \param ss             Socket address (CANNOT be sockaddr_t!).
  * \param family         Address family.
  * \param raw_addr       IP address in binary format.
  * \param raw_addr_size  Size of the binary address.
@@ -117,7 +117,7 @@ int sockaddr_set_raw(struct sockaddr_storage *ss, int family,
  *
  * \param buf     Destination for string representation.
  * \param maxlen  Maximum number of written bytes.
- * \param ss      Socket address.
+ * \param ss      Socket address (can be sockaddr_t).
  *
  * \return Number of bytes written on success, error code on failure.
  */
@@ -150,15 +150,15 @@ char *sockaddr_hostname(void);
 /*!
  * \brief Check if address is ANY address.
  *
- * \param ss  Socket address.
+ * \param ss  Socket address (can be sockaddr_t).
  */
 bool sockaddr_is_any(const struct sockaddr_storage *ss);
 
 /*!
  * \brief Check if two addresses match the given network prefix.
  *
- * \param ss1     First address.
- * \param ss2     Second address.
+ * \param ss1     First address (can be sockaddr_t).
+ * \param ss2     Second address (can be sockaddr_t).
  * \param prefix  Prefix length.
  *
  * \return True on match.
@@ -170,9 +170,9 @@ bool sockaddr_net_match(const struct sockaddr_storage *ss1,
 /*!
  * \brief Check if the address is within the given address range (inclusive).
  *
- * \param ss      Address to check.
- * \param ss_min  Minimum address.
- * \param ss_max  Maximum address.
+ * \param ss      Address to check (can be sockaddr_t).
+ * \param ss_min  Minimum address (can be sockaddr_t).
+ * \param ss_max  Maximum address (can be sockaddr_t).
  *
  * \return True on match.
  */