~donmcc/ood

49bbe0425f27aef911472765b0a3cbc78d0cc694 — Don McCaughey 1 year, 10 months ago fbeee83
Re-order function declarations and add comments.

Group different sets of "alloc" functions together and add comments
between different function groups in the header.

Rename `sa_alloc_from_path()` to `sa_alloc_from_unix_path()`.

Reorder function definitions and tests to match declaration order.
3 files changed, 113 insertions(+), 102 deletions(-)

M src/sa/sa.c
M src/sa/sa.h
M src/sa/sa_tests.c
M src/sa/sa.c => src/sa/sa.c +28 -29
@@ 19,6 19,32 @@ sa_alloc_from_ipv4_address_and_port(in_addr_t in_addr, in_port_t in_port)


union sa_address *
sa_alloc_from_ipv6_address_and_port(struct in6_addr in6_addr, in_port_t in_port)
{
    struct sockaddr_in6 inet6 = {
            .sin6_family=AF_INET6,
            .sin6_addr=in6_addr,
            .sin6_port=htons(in_port),
    };
    return sa_alloc_from_sockaddr_in6(&inet6);
}


union sa_address *
sa_alloc_from_unix_path(char const *path)
{
    if (!path) return NULL;
    if (strlen(path) >= UNIX_PATH_MAX) return NULL;

    struct sockaddr_un local_address = {
            .sun_family = AF_UNIX,
    };
    strcpy(local_address.sun_path, path);
    return sa_alloc_from_sockaddr_un(&local_address);
}


union sa_address *
sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address)
{
    union sa_address *address = calloc(1, sizeof(union sa_address));


@@ 35,7 61,7 @@ sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address)

    return address;

fail:
    fail:
    free(address);
    return NULL;



@@ 43,18 69,6 @@ fail:


union sa_address *
sa_alloc_from_ipv6_address_and_port(struct in6_addr in6_addr, in_port_t in_port)
{
    struct sockaddr_in6 inet6 = {
            .sin6_family=AF_INET6,
            .sin6_addr=in6_addr,
            .sin6_port=htons(in_port),
    };
    return sa_alloc_from_sockaddr_in6(&inet6);
}


union sa_address *
sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address)
{
    union sa_address *address = calloc(1, sizeof(union sa_address));


@@ 72,27 86,13 @@ sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address)

    return address;

fail:
    fail:
    free(address);
    return NULL;
}


union sa_address *
sa_alloc_from_path(char const *path)
{
    if (!path) return NULL;
    if (strlen(path) >= UNIX_PATH_MAX) return NULL;

    struct sockaddr_un local_address = {
            .sun_family = AF_UNIX,
    };
    strcpy(local_address.sun_path, path);
    return sa_alloc_from_sockaddr_un(&local_address);
}


union sa_address *
sa_alloc_from_sockaddr_un(struct sockaddr_un const *local_address)
{
    union sa_address *address = calloc(1, sizeof(union sa_address));


@@ 114,7 114,6 @@ sa_len(union sa_address const *address)
        case AF_INET6: return sizeof(struct sockaddr_in6);
        default: return sizeof(struct sockaddr_storage);
    }
    return 0;
}



M src/sa/sa.h => src/sa/sa.h +24 -11
@@ 8,13 8,12 @@


/* Size of fixed string buffers for IPv4 and IPv6 string representations,
 * including port.  Note that `SA_PORT_STR_LEN` and `SA_COLON_STR_LEN` _do not_
 * include space for a nul terminator, but `INET_ADDRSTRLEN` and
 * `INET6_ADDRSTRLEN`, defined by
 * [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html)
 * _do_ include space for a nul terminator and thus so do `SA_IPV4_STR_SIZE`
 * and `SA_IPV6_STR_SIZE`.
 */
   including port.  Note that `SA_PORT_STR_LEN` and `SA_COLON_STR_LEN` _do not_
   include space for a nul terminator, but `INET_ADDRSTRLEN` and
   `INET6_ADDRSTRLEN`, defined by
   [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html)
   _do_ include space for a nul terminator and thus so do `SA_IPV4_STR_SIZE`
   and `SA_IPV6_STR_SIZE`. */
#define SA_PORT_STR_LEN 5
#define SA_COLON_STR_LEN 1
#define SA_IPV4_STR_SIZE (INET_ADDRSTRLEN + SA_COLON_STR_LEN + SA_PORT_STR_LEN)


@@ 25,6 24,10 @@
#endif


/* The `sa_address` union holds storage for each of the `sockaddr`
   [type puns](https://en.wikipedia.org/wiki/Type_punning) along with space for
   a string representation.  For the `sockaddr_un` address type, the `sun_path`
   field is used as the string representation. */
union sa_address {
    struct sockaddr generic;
    struct {


@@ 40,24 43,32 @@ union sa_address {
};


// # Allocate socket address from components

union sa_address *
sa_alloc_from_ipv4_address_and_port(in_addr_t in_addr, in_port_t in_port);

union sa_address *
sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address);
sa_alloc_from_ipv6_address_and_port(struct in6_addr in6_addr, in_port_t in_port);

union sa_address *
sa_alloc_from_ipv6_address_and_port(struct in6_addr in6_addr, in_port_t in_port);
sa_alloc_from_unix_path(char const *path);


// # Allocate socket address from a `sockaddr`-type struct.

union sa_address *
sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address);
sa_alloc_from_sockaddr_in(struct sockaddr_in const *ipv4_address);

union sa_address *
sa_alloc_from_path(char const *path);
sa_alloc_from_sockaddr_in6(struct sockaddr_in6 const *ipv6_address);

union sa_address *
sa_alloc_from_sockaddr_un(struct sockaddr_un const *local_address);


// # Get info about a socket address

socklen_t
sa_len(union sa_address const *address);



@@ 65,6 76,8 @@ char const *
sa_str(union sa_address const *address);


// # Wrap socket functions that use `sockaddr` structs

inline int
sa_bind(int socket, union sa_address const *address)
{

M src/sa/sa_tests.c => src/sa/sa_tests.c +61 -62
@@ 28,33 28,6 @@ test_sa_alloc_from_ipv4_address_and_port(void)


static void
test_sa_alloc_from_sockaddr_in(void)
{
    struct sockaddr_in ipv4 = {
            .sin_family=AF_INET,
            .sin_addr=(struct in_addr){
                    .s_addr=htonl(INADDR_LOOPBACK)
            },
            .sin_port=htons(8080),
    };

    union sa_address *address = sa_alloc_from_sockaddr_in(&ipv4);

    assert(address);
    assert(AF_INET == address->generic.sa_family);
    assert(AF_INET == address->ipv4.sin_family);
    assert(AF_INET == address->ipv6.sin6_family);
    assert(AF_INET == address->local.sun_family);
    assert(AF_INET == address->storage.ss_family);
    assert(htonl(INADDR_LOOPBACK) == address->ipv4.sin_addr.s_addr);
    assert(htons(8080) == address->ipv4.sin_port);
    assert(STR_EQ("127.0.0.1:8080", sa_str(address)));

    free(address);
}


static void
test_sa_alloc_from_ipv6_address_and_port(void)
{
    union sa_address *address = sa_alloc_from_ipv6_address_and_port(in6addr_loopback, 8080);


@@ 74,34 47,9 @@ test_sa_alloc_from_ipv6_address_and_port(void)


static void
test_sa_alloc_from_sockaddr_in6(void)
{
    struct sockaddr_in6 ipv6 = {
            .sin6_family=AF_INET6,
            .sin6_addr=in6addr_loopback,
            .sin6_port=htons(8080),
    };

    union sa_address *address = sa_alloc_from_sockaddr_in6(&ipv6);

    assert(address);
    assert(AF_INET6 == address->generic.sa_family);
    assert(AF_INET6 == address->ipv4.sin_family);
    assert(AF_INET6 == address->ipv6.sin6_family);
    assert(AF_INET6 == address->local.sun_family);
    assert(AF_INET6 == address->storage.ss_family);
    assert(IN6_ADDR_EQ(&in6addr_loopback, &address->ipv6.sin6_addr));
    assert(htons(8080) == address->ipv6.sin6_port);
    assert(STR_EQ("::1:8080", sa_str(address)));

    free(address);
}


static void
test_sa_alloc_from_path(void)
test_sa_alloc_from_unix_path(void)
{
    union sa_address *address = sa_alloc_from_path("/var/dood/http");
    union sa_address *address = sa_alloc_from_unix_path("/var/dood/http");

    assert(address);
    assert(AF_UNIX == address->generic.sa_family);


@@ 119,7 67,7 @@ test_sa_alloc_from_path(void)
static void
test_sa_alloc_from_path_when_null(void)
{
    union sa_address *address = sa_alloc_from_path(NULL);
    union sa_address *address = sa_alloc_from_unix_path(NULL);

    assert(!address);
}


@@ 131,13 79,65 @@ test_sa_alloc_from_path_when_too_long(void)
    char const *too_long = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
    assert(strlen(too_long) > UNIX_PATH_MAX);

    union sa_address *address = sa_alloc_from_path(too_long);
    union sa_address *address = sa_alloc_from_unix_path(too_long);

    assert(!address);
}


static void
test_sa_alloc_from_sockaddr_in(void)
{
    struct sockaddr_in ipv4 = {
            .sin_family=AF_INET,
            .sin_addr=(struct in_addr){
                    .s_addr=htonl(INADDR_LOOPBACK)
            },
            .sin_port=htons(8080),
    };

    union sa_address *address = sa_alloc_from_sockaddr_in(&ipv4);

    assert(address);
    assert(AF_INET == address->generic.sa_family);
    assert(AF_INET == address->ipv4.sin_family);
    assert(AF_INET == address->ipv6.sin6_family);
    assert(AF_INET == address->local.sun_family);
    assert(AF_INET == address->storage.ss_family);
    assert(htonl(INADDR_LOOPBACK) == address->ipv4.sin_addr.s_addr);
    assert(htons(8080) == address->ipv4.sin_port);
    assert(STR_EQ("127.0.0.1:8080", sa_str(address)));

    free(address);
}


static void
test_sa_alloc_from_sockaddr_in6(void)
{
    struct sockaddr_in6 ipv6 = {
            .sin6_family=AF_INET6,
            .sin6_addr=in6addr_loopback,
            .sin6_port=htons(8080),
    };

    union sa_address *address = sa_alloc_from_sockaddr_in6(&ipv6);

    assert(address);
    assert(AF_INET6 == address->generic.sa_family);
    assert(AF_INET6 == address->ipv4.sin_family);
    assert(AF_INET6 == address->ipv6.sin6_family);
    assert(AF_INET6 == address->local.sun_family);
    assert(AF_INET6 == address->storage.ss_family);
    assert(IN6_ADDR_EQ(&in6addr_loopback, &address->ipv6.sin6_addr));
    assert(htons(8080) == address->ipv6.sin6_port);
    assert(STR_EQ("::1:8080", sa_str(address)));

    free(address);
}


static void
test_sa_alloc_from_sockaddr_un(void)
{
    struct sockaddr_un local = {


@@ 198,7 198,7 @@ test_sa_len_for_ipv6(void)
static void
test_sa_len_for_unix(void)
{
    union sa_address *address = sa_alloc_from_path("/var/dood/http");
    union sa_address *address = sa_alloc_from_unix_path("/var/dood/http");

    assert(sizeof(struct sockaddr_un) == sa_len(address));



@@ 249,14 249,13 @@ int
main(int argc, char *argv[])
{
    test_sa_alloc_from_ipv4_address_and_port();
    test_sa_alloc_from_sockaddr_in();

    test_sa_alloc_from_ipv6_address_and_port();
    test_sa_alloc_from_sockaddr_in6();

    test_sa_alloc_from_path();
    test_sa_alloc_from_unix_path();
    test_sa_alloc_from_path_when_null();
    test_sa_alloc_from_path_when_too_long();

    test_sa_alloc_from_sockaddr_in();
    test_sa_alloc_from_sockaddr_in6();
    test_sa_alloc_from_sockaddr_un();

    test_sa_len_for_unspecified();