From: Daniel Salzman Date: Tue, 10 Jan 2023 09:38:28 +0000 (+0100) Subject: sockaddr: improve compatibility with sockaddr_t X-Git-Tag: v3.4.dev~258^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf2e95438d7c8e739d390cea4e26549f1e8bd0da;p=thirdparty%2Fknot-dns.git sockaddr: improve compatibility with sockaddr_t --- diff --git a/src/contrib/sockaddr.c b/src/contrib/sockaddr.c index f91c374d92..fc5768bb47 100644 --- a/src/contrib/sockaddr.c +++ b/src/contrib/sockaddr.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -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; } diff --git a/src/contrib/sockaddr.h b/src/contrib/sockaddr.h index e6f4d2fb51..a6975b401f 100644 --- a/src/contrib/sockaddr.h +++ b/src/contrib/sockaddr.h @@ -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. */