~donmcc/ood

62b2303d00dc873fe8b016fdbe6d4df45eabdf83 — Don McCaughey 1 year, 6 months ago cbf60d3 main
Check address family in init functions.

Add tests for `sa_from_sockaddr_in()`, `sa_from_sockaddr_in6()` and
`sa_from_sockaddr_un()` to verify that they fail if the respective
`sockaddr` struct variant doesn't contain the expected address family
discriminant.
3 files changed, 58 insertions(+), 1 deletions(-)

M TODO.md
M src/sa/sa.c
M src/sa/sa_tests.c
M TODO.md => TODO.md +0 -1
@@ 1,6 1,5 @@
# TODO

- check address family in `sa_from_sockaddr_in()` and friends
- check if `bind()` works with sizeof struct sockaddr_storage 
- test listening on unix and ipv6 sockets
- handle linux "unnamed" and "abstract" unix sockets

M src/sa/sa.c => src/sa/sa.c +3 -0
@@ 127,6 127,7 @@ bool
sa_from_sockaddr_in(union sa *address, struct sockaddr_in const *ipv4_address)
{
    if (!ipv4_address) return false;
    if (AF_INET != ipv4_address->sin_family) return false;

    if (!sa_unspec(address)) return false;



@@ 142,6 143,7 @@ bool
sa_from_sockaddr_in6(union sa *address, struct sockaddr_in6 const *ipv6_address)
{
    if (!ipv6_address) return false;
    if (AF_INET6 != ipv6_address->sin6_family) return false;

    if (!sa_unspec(address)) return false;



@@ 157,6 159,7 @@ bool
sa_from_sockaddr_un(union sa *address, struct sockaddr_un const *local_address)
{
    if (!local_address) return false;
    if (AF_UNIX != local_address->sun_family) return false;

    if (!sa_unspec(address)) return false;


M src/sa/sa_tests.c => src/sa/sa_tests.c +55 -0
@@ 426,6 426,25 @@ test_sa_from_sockaddr_in_when_null(void)


static void
test_sa_from_sockaddr_in_when_wrong_family(void)
{
    struct sockaddr_in ipv4 = {
            .sin_family=AF_UNIX,
            .sin_addr=(struct in_addr){
                    .s_addr=htonl(INADDR_LOOPBACK)
            },
            .sin_port=htons(8080),
    };
    union sa address;
    memset(&address, 0xff, sizeof address);

    bool success = sa_from_sockaddr_in(&address, &ipv4);

    assert(!success);
}


static void
test_sa_from_sockaddr_in6(void)
{
    struct sockaddr_in6 ipv6 = {


@@ 472,6 491,23 @@ test_sa_from_sockaddr_in6_when_null(void)


static void
test_sa_from_sockaddr_in6_when_wrong_family(void)
{
    struct sockaddr_in6 ipv6 = {
            .sin6_family=AF_UNIX,
            .sin6_addr=in6addr_loopback,
            .sin6_port=htons(8080),
    };
    union sa address;
    memset(&address, 0xff, sizeof address);

    bool success = sa_from_sockaddr_in6(&address, &ipv6);

    assert(!success);
}


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


@@ 515,6 551,22 @@ test_sa_from_sockaddr_un_when_null(void)


static void
test_sa_from_sockaddr_un_when_wrong_family(void)
{
    struct sockaddr_un local = {
            .sun_family = AF_INET6,
            .sun_path = "/var/dood/http",
    };
    union sa address;
    memset(&address, 0xff, sizeof address);

    bool success = sa_from_sockaddr_un(&address, &local);

    assert(!success);
}


static void
test_sa_prepare(void)
{
    union sa address;


@@ 834,12 886,15 @@ main(int argc, char *argv[])

    test_sa_from_sockaddr_in();
    test_sa_from_sockaddr_in_when_null();
    test_sa_from_sockaddr_in_when_wrong_family();

    test_sa_from_sockaddr_in6();
    test_sa_from_sockaddr_in6_when_null();
    test_sa_from_sockaddr_in6_when_wrong_family();

    test_sa_from_sockaddr_un();
    test_sa_from_sockaddr_un_when_null();
    test_sa_from_sockaddr_un_when_wrong_family();

    test_sa_prepare();
    test_sa_prepare_for_null();