1.0.1 Handle different kind of sockaddr with a union

This commit is contained in:
seajee
2025-04-25 03:27:28 +02:00
parent 75b1a7d474
commit 98badd7033

38
sock.h
View File

@@ -24,7 +24,11 @@ typedef struct {
SockAddrType type; // Address type SockAddrType type; // Address type
int port; // Address port int port; // Address port
char str[SOCK_ADDR_STR_CAPACITY]; // String representation of the address char str[SOCK_ADDR_STR_CAPACITY]; // String representation of the address
struct sockaddr sockaddr; union {
struct sockaddr sockaddr;
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
};
socklen_t len; socklen_t len;
} SockAddr; } SockAddr;
@@ -82,16 +86,14 @@ SockAddr sock_addr(const char *addr, int port)
if (inet_pton(AF_INET, addr, &sa.sockaddr) == 1) { if (inet_pton(AF_INET, addr, &sa.sockaddr) == 1) {
sa.type = SOCK_IPV4; sa.type = SOCK_IPV4;
sa.len = sizeof(struct sockaddr_in); sa.len = sizeof(sa.ipv4);
struct sockaddr_in *in = (struct sockaddr_in*)&sa.sockaddr; sa.ipv4.sin_family = AF_INET;
in->sin_family = AF_INET; sa.ipv4.sin_port = htons(port);
in->sin_port = htons(port);
} else if (inet_pton(AF_INET6, addr, &sa.sockaddr) == 1) { } else if (inet_pton(AF_INET6, addr, &sa.sockaddr) == 1) {
sa.type = SOCK_IPV6; sa.type = SOCK_IPV6;
sa.len = sizeof(struct sockaddr_in6); sa.len = sizeof(sa.ipv6);
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&sa.sockaddr; sa.ipv6.sin6_family = AF_INET6;
in6->sin6_family = AF_INET6; sa.ipv6.sin6_port = htons(port);
in6->sin6_port = htons(port);
} else { } else {
sa.type = SOCK_ADDR_INVALID; sa.type = SOCK_ADDR_INVALID;
return sa; return sa;
@@ -215,22 +217,23 @@ ssize_t sock_recvfrom(Sock *sock, void *buf, size_t size, SockAddr *addr)
switch (addr->sockaddr.sa_family) { switch (addr->sockaddr.sa_family) {
case AF_INET: { case AF_INET: {
struct sockaddr_in *sa = (struct sockaddr_in*)&addr->sockaddr; struct sockaddr_in *ipv4 = &addr->ipv4;
addr->type = SOCK_IPV4; addr->type = SOCK_IPV4;
addr->port = ntohs(sa->sin_port); addr->port = ntohs(ipv4->sin_port);
addr->len = sizeof(*sa); addr->len = sizeof(*ipv4);
inet_ntop(AF_INET, &sa->sin_addr, addr->str, sizeof(addr->str)); inet_ntop(AF_INET, &ipv4->sin_addr, addr->str, sizeof(addr->str));
} break; } break;
case AF_INET6: { case AF_INET6: {
struct sockaddr_in6 *sa = (struct sockaddr_in6*)&addr->sockaddr; struct sockaddr_in6 *ipv6 = &addr->ipv6;
addr->type = SOCK_IPV6; addr->type = SOCK_IPV6;
addr->port = ntohs(sa->sin6_port); addr->port = ntohs(ipv6->sin6_port);
addr->len = sizeof(*sa); addr->len = sizeof(*ipv6);
inet_ntop(AF_INET6, &sa->sin6_addr, addr->str, sizeof(addr->str)); inet_ntop(AF_INET6, &ipv6->sin6_addr, addr->str, sizeof(addr->str));
} break; } break;
default: { default: {
// TODO: Sometimes this assertion hits because sa_family == 64
assert(false && "Unsupported address family"); assert(false && "Unsupported address family");
} break; } break;
} }
@@ -249,6 +252,7 @@ void sock_close(Sock *sock)
/* /*
Revision history: Revision history:
1.0.1 (2025-04-25) Handle different kind of sockaddr with a union
1.0.0 (2025-04-25) Initial release 1.0.0 (2025-04-25) Initial release
*/ */