Extract common `from_ip_and_port_str()` function.
Add function `sa_find_port_in_str()`.
Rename parameters of `sa_from_ipv4_and_port_str()`.
A wrapper around the polymorphic sockaddr
family of structs and a
set of helper functions for common socket address chores.
The sa
union holds storage for each of the sockaddr
type puns along with
space for a string representation. For the sockaddr_un
address
type, the sun_path
field is used as the string representation.
The union contains fields .ipv4
, .ipv6
and .local
which correspond to
structs sockaddr_in
, sockaddr_in6
and sockaddr_un
respectively.
Additionally, .generic
corresponds to a sockaddr
struct and .storage
to
a sockaddr_storage
struct.
union sa {
struct sockaddr generic;
struct {
struct sockaddr_in ipv4;
char ipv4_str[SA_IPV4_STR_SIZE];
};
struct {
struct sockaddr_in6 ipv6;
char ipv6_str[SA_IPV6_STR_SIZE];
};
struct sockaddr_un local;
struct sockaddr_storage storage;
};
NB: Because the symbol unix
is #define
d in some Unix C compilers, sa
uses the name local
for Unix domain sockets (often referred to as "local"
sockets).
The inline function sa_family()
returns the discriminant value which tells
which field is currently active. In an initialized sa
union, the family will
be either AF_UNSPEC
, indicating a blank or zeroed-out sa
union, or one of
AF_INET
, AF_INET6
or AF_UNIX
.
Typical usage of sa
looks like this (sans error handling):
// initialize a socket address for use
union sa address;
sa_from_ipv4_str_and_port(&address, "127.0.0.1", 8080);
bind(fd, &address.generic, sa_len(&address));
// receive a socket address
union sa client_address;
socklen_t len;
sa_prepare(&client_address, &len);
int client_fd = accept(fd, &client_address.generic, &len);
sa_update(&client_address);
Socket addresses are frequently logged, so sa
creates a string representation
at initialization time. Use the sa_str()
function to get the correct string
representation.
union sa address;
sa_from_in_addr_and_port(&address, INADDR_LOOPBACK, 8080);
printf("%s", sa_str(&address));
// prints "127.0.0.1:8080"
SA is available under a BSD-style license. See the LICENSE file for details.
SA is tested on macOS, Linux, FreeBSD and OpenBSD. Building it requires a C toolchain and CMake 3.13 or later.
git clone https://git.sr.ht/~donmcc/sa
cd sa
cmake -S . -B tmp
cmake --build tmp --target all test
To build with the Address Sanitizer enabled, set the ADDRESS_SANITIZER
option to ON
.
cmake -S . -B tmp -DADDRESS_SANITIZER=ON
Mac users note that the clang
that ships with Xcode accepts the
-fsanitize=address
flag, but doesn't actually include the Address Sanitizer.
Set the COVERAGE
option to ON
to generate coverage files.
cmake -S . -B tmp -DCOVERAGE=ON
Set the WALL
option to ON
turns on additional warnings using the -Wall
compiler option and treats warnings as errors. WALL
is off by default but
should be turned on for development and integration builds.
cmake -S . -B tmp -DCOVERAGE=ON -DWALL=ON