<commit_before>/* vi: set ts=4 expandtab shiftwidth=4: */
/**
 * @file
 * @copyright Copyright 2010-2021 Digital Aggregates Corporation, Colorado, USA.
 * @note Licensed under the terms in LICENSE.txt.
 * @brief This is a unit test of the IPC feature for IPv4.
 * @author <NAME> <mailto:<EMAIL>>
 * @see Diminuto <https://github.com/coverclock/com-diag-diminuto>
 * @details
 * This is a unit test of the IPC feature for IPv4.
 */

#include "com/diag/diminuto/diminuto_unittest.h"
#include "com/diag/diminuto/diminuto_log.h"
#include "com/diag/diminuto/diminuto_ipc4.h"
#include "com/diag/diminuto/diminuto_time.h"
#include "com/diag/diminuto/diminuto_timer.h"
#include "com/diag/diminuto/diminuto_delay.h"
#include "com/diag/diminuto/diminuto_alarm.h"
#include "com/diag/diminuto/diminuto_frequency.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

static const size_t LIMIT = 256;
static const size_t TOTAL = 1024 * 1024 * 100;

int main(int argc, char * argv[])
{
    diminuto_ticks_t hertz;
    const char * Address = 0;
    const char * Interface = 0;
    const char * Port = 0;
    extern char * optarg;
    extern int optind;
    extern int opterr;
    extern int optopt;
    int opt;

    SETLOGMASK();

    while ((opt = getopt(argc, argv, "a:i:p:")) >= 0) {
        switch (opt) {
        case 'a':
            /* e.g. "fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b" */
            Address = optarg;
            break;
        case 'i':
            /* e.g. "eth0" */
            Interface = optarg;
            break;
        case 'p':
            /* e.g. "5555" */
            Port = optarg;
            break;
        default:
            break;
        }
    }

    hertz = diminuto_frequency();

    {
        const char name[] = "0.0.0.0";
        diminuto_ipv4_t address = 0xffffffffUL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT(address == DIMINUTO_IPC4_UNSPECIFIED);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        const char name[] = "127.0.0.1";
        diminuto_ipv4_t address = 0x00000000UL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_LOOPBACK);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        const char name[] = "127.0.0.2";
        diminuto_ipv4_t address = 0x00000000UL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_LOOPBACK2);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK2);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        diminuto_ipv4_t address;

        TEST();

        address = diminuto_ipc4_address("localhost");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "localhost", (long unsigned int)address, (long unsigned int)DIMINUTO_IPC4_LOOPBACK);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK);

        address = diminuto_ipc4_address("www.diag.com");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "www.diag.com", (long unsigned int)address, 0UL);
        EXPECT(address != 0UL);

        address = diminuto_ipc4_address("invalid.domain");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "invalid.domain", (long unsigned int)address, 0UL);

        /*
         * Damned internet service providers map invalid domains to a "help"
         * page. "invalid.domain" becomes 0xd0448f32 a.k.a. 192.168.127.12
         * a.k.a. "search5.comcast.com". That's not helpful!
         */
        ADVISE(address == 0UL);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("localhost");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "localhost", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii > 0);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("google.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "google.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        /*
         * "nslookup google.com" used to resolve as multiple addresses. But
         * today it doesn't. So I added the "amazon.com" test below. So far
         * Amazon.com still resolves as multiple addresses.
         */
        EXPECT(ii > 0);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("amazon.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "amazon.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii > 1);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("www.diag.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "www.diag.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii == 1);

        free(addresses);

        STATUS();
    }

    {
        diminuto_port_t port;

        TEST();

        port = diminuto_ipc4_port("80", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "(null)", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("80", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "tcp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("80", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "udp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("http", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "http", "(null)", port, 80);
        EXPECT(port == 80);    

        port = diminuto_ipc4_port("http", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "http", "tcp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("tftp", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "tftp", "udp", port, 69);
        EXPECT(port == 69);

        port = diminuto_ipc4_port("login", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "(null)", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("login", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "tcp", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("login", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "udp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("who", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "(null)", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("who", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "tcp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("who", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "udp", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("unknown", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "(null)", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("unknown", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "tcp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("unknown", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "udp", port, 0);
        EXPECT(port == 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        NOTIFY("If the connection request times out, try it again.\n");
        EXPECT((fd = diminuto_ipc4_stream_consumer(diminuto_ipc4_address("www.diag.com"), diminuto_ipc4_port("http", NULL))) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        EXPECT((fd = diminuto_ipc4_stream_consumer(diminuto_ipc4_address("www.amazon.com"), diminuto_ipc4_port("http", NULL))) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_stream_provider(0)) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_stream_provider(0)) >= 0);

        EXPECT(diminuto_ipc_set_nonblocking(fd, !0) >= 0);
        EXPECT(diminuto_ipc_set_nonblocking(fd, 0) >= 0);

        EXPECT(diminuto_ipc_set_reuseaddress(fd, 0) >= 0);
        EXPECT(diminuto_ipc_set_reuseaddress(fd, !0) >= 0);

        EXPECT(diminuto_ipc_set_keepalive(fd, !0) >= 0);
        EXPECT(diminuto_ipc_set_keepalive(fd, 0) >= 0);

        if (geteuid() == 0) {
            EXPECT(diminuto_ipc_set_debug(fd, !0) >= 0);
            EXPECT(diminuto_ipc_set_debug(fd, 0) >= 0);
        }

        EXPECT(diminuto_ipc_set_linger(fd, hertz) >= 0);
        EXPECT(diminuto_ipc_set_linger(fd, 0) >= 0);

        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t address = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;

        TEST();

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd1, (diminuto_ipv4_t *)0, &port1) >= 0);
        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd2, (diminuto_ipv4_t *)0, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), diminuto_ipc4_address("localhost"), port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(address == diminuto_ipc4_address("localhost"));
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), diminuto_ipc4_address("localhost"), port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == diminuto_ipc4_address("localhost"));
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t binding = 0;
        diminuto_ipv4_t address = 0;
        diminuto_ipv4_t address1 = 0;
        diminuto_ipv4_t address2 = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;

        TEST();

        binding = diminuto_ipc4_address("localhost");
        COMMENT("0x%8.8x %d\n", binding, 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd1, &address1, &port1) >= 0);
        /* fd1 not bound to specific address, and port is ephemeral. */
        EXPECT(port1 != 0);

        EXPECT(binding == 0x7f000001);
        EXPECT((fd2 = diminuto_ipc4_datagram_peer_generic(binding, 0, (const char *)0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd2, &address2, &port2) >= 0);

        EXPECT(address2 == binding);

        /* This only works because the kernel buffers socket data. */
        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), binding, port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(strcmp(buffer, MSG1) == 0);
        EXPECT(port == port1);

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), binding, port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == binding);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t localhost = 0;
        diminuto_ipv4_t address = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;
        diminuto_sticks_t now = 0;
        diminuto_sticks_t timestamp1 = 0;
        diminuto_sticks_t timestamp2 = 0;
        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        diminuto_ticks_t ticks = 0;

        TEST();

        EXPECT((localhost = diminuto_ipc4_address("localhost")) != DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT((now = diminuto_time_clock()) > 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd1, 0) == fd1);
        EXPECT(diminuto_ipc4_nearend(fd1, (diminuto_ipv4_t *)0, &port1) >= 0);

        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd2, 0) == fd2);
        EXPECT(diminuto_ipc4_nearend(fd2, (diminuto_ipv4_t *)0, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), localhost, port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(address == localhost);
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        EXPECT((timestamp2 = diminuto_ipc_get_timestamp(fd2)) >= 0);
        CHECKPOINT("timestamp2=%lld\n", (diminuto_lld_t)timestamp2);
        EXPECT(diminuto_time_zulu(timestamp2, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp2=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), localhost, port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == localhost);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT((timestamp1 = diminuto_ipc_get_timestamp(fd1)) >= 0);
        CHECKPOINT("timestamp1=%lld\n", (diminuto_lld_t)timestamp1);
        EXPECT(diminuto_time_zulu(timestamp1, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp1=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT(timestamp1 > now);
        EXPECT(timestamp2 > now);
        EXPECT(timestamp1 > timestamp2);
        EXPECT((timestamp1 - timestamp2) <= diminuto_frequency());

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t localhost = 0;
        diminuto_ipv4_t address = 0;
        diminuto_ipv4_t address1 = 0;
        diminuto_ipv4_t address2 = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;
        struct sockaddr_in socketaddress;
        struct msghdr message;
        struct iovec vector;
        union { struct cmsghdr header; char data[CMSG_SPACE(sizeof(struct timeval))]; } control;
        struct cmsghdr * cp = (struct cmsghdr *)0;
        ssize_t length = -1;
        struct timeval timestamp;
        diminuto_sticks_t now = 0;
        diminuto_sticks_t timestamp1 = 0;
        diminuto_sticks_t timestamp2 = 0;
        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        diminuto_ticks_t ticks = 0;

        TEST();

        EXPECT((localhost = diminuto_ipc4_address("localhost")) != DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT((now = diminuto_time_clock()) > 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd1, !0) == fd1);
        EXPECT(diminuto_ipc4_nearend(fd1, &address1, &port1) >= 0);

        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd2, !0) == fd2);
        EXPECT(diminuto_ipc4_nearend(fd2, &address2, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        /* This is either really cool or really crazy, not sure. */

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        socketaddress.sin_family = AF_INET;
        port = htons(port2);
        socketaddress.sin_port = port;
        address = htonl(localhost);
        memcpy(&socketaddress.sin_addr.s_addr, &address, sizeof(address));

        vector.iov_base = (void *)MSG1;
        vector.iov_len = sizeof(MSG1);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = (void *)0;
        message.msg_controllen = 0;

        EXPECT((diminuto_ipc_message_send(fd1, &message)) == sizeof(MSG1));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        vector.iov_base = buffer;
        vector.iov_len = sizeof(buffer);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = &control;
        message.msg_controllen = sizeof(control);

        EXPECT((diminuto_ipc_message_receive(fd2, &message)) == sizeof(MSG1));

        memcpy(&address, &socketaddress.sin_addr.s_addr, sizeof(address));
        address = ntohl(address);
        EXPECT(address == localhost);
        port = socketaddress.sin_port;
        port = ntohs(port);
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        for (cp = CMSG_FIRSTHDR(&message); cp != (struct cmsghdr *)0; cp = CMSG_NXTHDR(&message, cp)) {
            CHECKPOINT("control2 level=%d type=%d len=%lu\n", cp->cmsg_level, cp->cmsg_type, cp->cmsg_len);
            if (cp->cmsg_level != SOL_SOCKET) { continue; }
            if (cp->cmsg_type != SO_TIMESTAMP) { continue; }
            if (cp->cmsg_len != CMSG_LEN(sizeof(timestamp))) { continue; }
            memcpy(&timestamp, CMSG_DATA(cp), sizeof(timestamp));
            timestamp2 = diminuto_frequency_seconds2ticks(timestamp.tv_sec, timestamp.tv_usec, 1000000LL);
            break;
        }
        ASSERT(cp != (struct cmsghdr *)0);

        CHECKPOINT("timestamp2=%lld\n", (diminuto_lld_t)timestamp2);
        EXPECT(diminuto_time_zulu(timestamp2, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp2=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        socketaddress.sin_family = AF_INET;
        port = htons(port1);
        socketaddress.sin_port = port;
        address = htonl(localhost);
        memcpy(&socketaddress.sin_addr.s_addr, &address, sizeof(address));

        vector.iov_base = (void *)MSG2;
        vector.iov_len = sizeof(MSG2);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = (void *)0;
        message.msg_controllen = 0;

        EXPECT((diminuto_ipc_message_send(fd2, &message)) == sizeof(MSG2));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        vector.iov_base = buffer;
        vector.iov_len = sizeof(buffer);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = &control;
        message.msg_controllen = sizeof(control);

        EXPECT((diminuto_ipc_message_receive(fd1, &message)) == sizeof(MSG2));

        memcpy(&address, &socketaddress.sin_addr.s_addr, sizeof(address));
        address = ntohl(address);
        EXPECT(address == localhost);
        port = socketaddress.sin_port;
        port = ntohs(port);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        for (cp = CMSG_FIRSTHDR(&message); cp != (struct cmsghdr *)0; cp = CMSG_NXTHDR(&message, cp)) {
            CHECKPOINT("control1 level=%d type=%d len=%lu\n", cp->cmsg_level, cp->cmsg_type, cp->cmsg_len);
            if (cp->cmsg_level != SOL_SOCKET) { continue; }
            if (cp->cmsg_type != SO_TIMESTAMP) { continue; }
            if (cp->cmsg_len != CMSG_LEN(sizeof(timestamp))) { continue; }
            memcpy(&timestamp, CMSG_DATA(cp), sizeof(timestamp));
            timestamp1 = diminuto_frequency_seconds2ticks(timestamp.tv_sec, timestamp.tv_usec, 1000000LL);
            break;
        }
        ASSERT(cp != (struct cmsghdr *)0);

        CHECKPOINT("timestamp1=%lld\n", (diminuto_lld_t)timestamp1);
        EXPECT(diminuto_time_zulu(timestamp1, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp1=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT(timestamp1 > now);
        EXPECT(timestamp2 > now);
        EXPECT(timestamp1 > timestamp2);
        EXPECT((timestamp1 - timestamp2) <= diminuto_frequency());

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {<commit_msg>[1] Minor tweak to ipc4 unit test in duration comparison. PASSED<commit_after>/* vi: set ts=4 expandtab shiftwidth=4: */
/**
 * @file
 * @copyright Copyright 2010-2021 Digital Aggregates Corporation, Colorado, USA.
 * @note Licensed under the terms in LICENSE.txt.
 * @brief This is a unit test of the IPC feature for IPv4.
 * @author <NAME> <mailto:<EMAIL>>
 * @see Diminuto <https://github.com/coverclock/com-diag-diminuto>
 * @details
 * This is a unit test of the IPC feature for IPv4.
 */

#include "com/diag/diminuto/diminuto_unittest.h"
#include "com/diag/diminuto/diminuto_log.h"
#include "com/diag/diminuto/diminuto_ipc4.h"
#include "com/diag/diminuto/diminuto_time.h"
#include "com/diag/diminuto/diminuto_timer.h"
#include "com/diag/diminuto/diminuto_delay.h"
#include "com/diag/diminuto/diminuto_alarm.h"
#include "com/diag/diminuto/diminuto_frequency.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

static const size_t LIMIT = 256;
static const size_t TOTAL = 1024 * 1024 * 100;

int main(int argc, char * argv[])
{
    diminuto_ticks_t hertz;
    const char * Address = 0;
    const char * Interface = 0;
    const char * Port = 0;
    extern char * optarg;
    extern int optind;
    extern int opterr;
    extern int optopt;
    int opt;

    SETLOGMASK();

    while ((opt = getopt(argc, argv, "a:i:p:")) >= 0) {
        switch (opt) {
        case 'a':
            /* e.g. "fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b" */
            Address = optarg;
            break;
        case 'i':
            /* e.g. "eth0" */
            Interface = optarg;
            break;
        case 'p':
            /* e.g. "5555" */
            Port = optarg;
            break;
        default:
            break;
        }
    }

    hertz = diminuto_frequency();

    {
        const char name[] = "0.0.0.0";
        diminuto_ipv4_t address = 0xffffffffUL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT(address == DIMINUTO_IPC4_UNSPECIFIED);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        const char name[] = "127.0.0.1";
        diminuto_ipv4_t address = 0x00000000UL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_LOOPBACK);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        const char name[] = "127.0.0.2";
        diminuto_ipv4_t address = 0x00000000UL;
        char buffer[sizeof("NNN.NNN.NNN.NNN")] = { 0 };

        TEST();

        address = diminuto_ipc4_address(name);
        COMMENT("\"%s\" 0x%8.8x 0x%8.8x\n", name, address, DIMINUTO_IPC4_LOOPBACK2);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK2);

        EXPECT(diminuto_ipc4_dotnotation(address, buffer, sizeof(buffer)) == buffer);
        COMMENT("\"%s\" \"%s\"\n", buffer, name);
        EXPECT(strcmp(buffer, name) == 0);

        STATUS();
    }

    {
        diminuto_ipv4_t address;

        TEST();

        address = diminuto_ipc4_address("localhost");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "localhost", (long unsigned int)address, (long unsigned int)DIMINUTO_IPC4_LOOPBACK);
        EXPECT(address == DIMINUTO_IPC4_LOOPBACK);

        address = diminuto_ipc4_address("www.diag.com");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "www.diag.com", (long unsigned int)address, 0UL);
        EXPECT(address != 0UL);

        address = diminuto_ipc4_address("invalid.domain");
        COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "invalid.domain", (long unsigned int)address, 0UL);

        /*
         * Damned internet service providers map invalid domains to a "help"
         * page. "invalid.domain" becomes 0xd0448f32 a.k.a. 192.168.127.12
         * a.k.a. "search5.comcast.com". That's not helpful!
         */
        ADVISE(address == 0UL);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("localhost");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "localhost", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii > 0);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("google.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "google.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        /*
         * "nslookup google.com" used to resolve as multiple addresses. But
         * today it doesn't. So I added the "amazon.com" test below. So far
         * Amazon.com still resolves as multiple addresses.
         */
        EXPECT(ii > 0);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("amazon.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "amazon.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii > 1);
        EXPECT(ii < LIMIT);

        free(addresses);

        STATUS();
    }

    {
        diminuto_ipv4_t * addresses;
        size_t ii;

        TEST();

        addresses = diminuto_ipc4_addresses("www.diag.com");
        ASSERT(addresses != (diminuto_ipv4_t *)0);

        for (ii = 0; ii < LIMIT; ++ii) {
            COMMENT("\"%s\" 0x%8.8lx 0x%8.8lx\n", "www.diag.com", (long unsigned int)addresses[ii], 0UL);
            if (addresses[ii] == 0UL) {
                break;
            }
        }
        EXPECT(ii == 1);

        free(addresses);

        STATUS();
    }

    {
        diminuto_port_t port;

        TEST();

        port = diminuto_ipc4_port("80", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "(null)", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("80", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "tcp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("80", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "80", "udp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("http", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "http", "(null)", port, 80);
        EXPECT(port == 80);    

        port = diminuto_ipc4_port("http", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "http", "tcp", port, 80);
        EXPECT(port == 80);

        port = diminuto_ipc4_port("tftp", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "tftp", "udp", port, 69);
        EXPECT(port == 69);

        port = diminuto_ipc4_port("login", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "(null)", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("login", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "tcp", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("login", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "login", "udp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("who", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "(null)", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("who", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "tcp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("who", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "who", "udp", port, 513);
        EXPECT(port == 513);

        port = diminuto_ipc4_port("unknown", NULL);
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "(null)", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("unknown", "tcp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "tcp", port, 0);
        EXPECT(port == 0);

        port = diminuto_ipc4_port("unknown", "udp");
        COMMENT("\"%s\" \"%s\" %d %d\n", "unknown", "udp", port, 0);
        EXPECT(port == 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        NOTIFY("If the connection request times out, try it again.\n");
        EXPECT((fd = diminuto_ipc4_stream_consumer(diminuto_ipc4_address("www.diag.com"), diminuto_ipc4_port("http", NULL))) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        EXPECT((fd = diminuto_ipc4_stream_consumer(diminuto_ipc4_address("www.amazon.com"), diminuto_ipc4_port("http", NULL))) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_stream_provider(0)) >= 0);
        EXPECT(diminuto_ipc_type(fd) == AF_INET);
        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd;

        TEST();

        EXPECT((fd = diminuto_ipc4_stream_provider(0)) >= 0);

        EXPECT(diminuto_ipc_set_nonblocking(fd, !0) >= 0);
        EXPECT(diminuto_ipc_set_nonblocking(fd, 0) >= 0);

        EXPECT(diminuto_ipc_set_reuseaddress(fd, 0) >= 0);
        EXPECT(diminuto_ipc_set_reuseaddress(fd, !0) >= 0);

        EXPECT(diminuto_ipc_set_keepalive(fd, !0) >= 0);
        EXPECT(diminuto_ipc_set_keepalive(fd, 0) >= 0);

        if (geteuid() == 0) {
            EXPECT(diminuto_ipc_set_debug(fd, !0) >= 0);
            EXPECT(diminuto_ipc_set_debug(fd, 0) >= 0);
        }

        EXPECT(diminuto_ipc_set_linger(fd, hertz) >= 0);
        EXPECT(diminuto_ipc_set_linger(fd, 0) >= 0);

        EXPECT(diminuto_ipc4_close(fd) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t address = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;

        TEST();

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd1, (diminuto_ipv4_t *)0, &port1) >= 0);
        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd2, (diminuto_ipv4_t *)0, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), diminuto_ipc4_address("localhost"), port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(address == diminuto_ipc4_address("localhost"));
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), diminuto_ipc4_address("localhost"), port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == diminuto_ipc4_address("localhost"));
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t binding = 0;
        diminuto_ipv4_t address = 0;
        diminuto_ipv4_t address1 = 0;
        diminuto_ipv4_t address2 = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;

        TEST();

        binding = diminuto_ipc4_address("localhost");
        COMMENT("0x%8.8x %d\n", binding, 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd1, &address1, &port1) >= 0);
        /* fd1 not bound to specific address, and port is ephemeral. */
        EXPECT(port1 != 0);

        EXPECT(binding == 0x7f000001);
        EXPECT((fd2 = diminuto_ipc4_datagram_peer_generic(binding, 0, (const char *)0)) >= 0);
        EXPECT(diminuto_ipc4_nearend(fd2, &address2, &port2) >= 0);

        EXPECT(address2 == binding);

        /* This only works because the kernel buffers socket data. */
        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), binding, port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(strcmp(buffer, MSG1) == 0);
        EXPECT(port == port1);

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), binding, port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == binding);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t localhost = 0;
        diminuto_ipv4_t address = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;
        diminuto_sticks_t now = 0;
        diminuto_sticks_t timestamp1 = 0;
        diminuto_sticks_t timestamp2 = 0;
        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        diminuto_ticks_t ticks = 0;

        TEST();

        EXPECT((localhost = diminuto_ipc4_address("localhost")) != DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT((now = diminuto_time_clock()) > 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd1, 0) == fd1);
        EXPECT(diminuto_ipc4_nearend(fd1, (diminuto_ipv4_t *)0, &port1) >= 0);

        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd2, 0) == fd2);
        EXPECT(diminuto_ipc4_nearend(fd2, (diminuto_ipv4_t *)0, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        EXPECT((diminuto_ipc4_datagram_send(fd1, MSG1, sizeof(MSG1), localhost, port2)) == sizeof(MSG1));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd2, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG1));
        EXPECT(address == localhost);
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        EXPECT((timestamp2 = diminuto_ipc_get_timestamp(fd2)) >= 0);
        CHECKPOINT("timestamp2=%lld\n", (diminuto_lld_t)timestamp2);
        EXPECT(diminuto_time_zulu(timestamp2, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp2=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT((diminuto_ipc4_datagram_send(fd2, MSG2, sizeof(MSG2), localhost, port1)) == sizeof(MSG2));
        EXPECT((diminuto_ipc4_datagram_receive_generic(fd1, buffer, sizeof(buffer), &address, &port, 0)) == sizeof(MSG2));
        EXPECT(address == localhost);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        EXPECT((timestamp1 = diminuto_ipc_get_timestamp(fd1)) >= 0);
        CHECKPOINT("timestamp1=%lld\n", (diminuto_lld_t)timestamp1);
        EXPECT(diminuto_time_zulu(timestamp1, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp1=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT(timestamp1 > now);
        EXPECT(timestamp2 > now);
        EXPECT(timestamp1 > timestamp2);
        EXPECT((timestamp1 - timestamp2) < diminuto_frequency());

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
        int fd1;
        int fd2;
        const char MSG1[] = "Chip Overclock";
        const char MSG2[] = "Digital Aggregates Corporation";
        char buffer[64];
        diminuto_ipv4_t localhost = 0;
        diminuto_ipv4_t address = 0;
        diminuto_ipv4_t address1 = 0;
        diminuto_ipv4_t address2 = 0;
        diminuto_port_t port = 0;
        diminuto_port_t port1 = 0;
        diminuto_port_t port2 = 0;
        struct sockaddr_in socketaddress;
        struct msghdr message;
        struct iovec vector;
        union { struct cmsghdr header; char data[CMSG_SPACE(sizeof(struct timeval))]; } control;
        struct cmsghdr * cp = (struct cmsghdr *)0;
        ssize_t length = -1;
        struct timeval timestamp;
        diminuto_sticks_t now = 0;
        diminuto_sticks_t timestamp1 = 0;
        diminuto_sticks_t timestamp2 = 0;
        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minute = 0;
        int second = 0;
        diminuto_ticks_t ticks = 0;

        TEST();

        EXPECT((localhost = diminuto_ipc4_address("localhost")) != DIMINUTO_IPC4_UNSPECIFIED);
        EXPECT((now = diminuto_time_clock()) > 0);

        EXPECT((fd1 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd1, !0) == fd1);
        EXPECT(diminuto_ipc4_nearend(fd1, &address1, &port1) >= 0);

        EXPECT((fd2 = diminuto_ipc4_datagram_peer(0)) >= 0);
        EXPECT(diminuto_ipc_set_timestamp(fd2, !0) == fd2);
        EXPECT(diminuto_ipc4_nearend(fd2, &address2, &port2) >= 0);

        /* This only works because the kernel buffers socket data. */

        /* This is either really cool or really crazy, not sure. */

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        socketaddress.sin_family = AF_INET;
        port = htons(port2);
        socketaddress.sin_port = port;
        address = htonl(localhost);
        memcpy(&socketaddress.sin_addr.s_addr, &address, sizeof(address));

        vector.iov_base = (void *)MSG1;
        vector.iov_len = sizeof(MSG1);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = (void *)0;
        message.msg_controllen = 0;

        EXPECT((diminuto_ipc_message_send(fd1, &message)) == sizeof(MSG1));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        vector.iov_base = buffer;
        vector.iov_len = sizeof(buffer);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = &control;
        message.msg_controllen = sizeof(control);

        EXPECT((diminuto_ipc_message_receive(fd2, &message)) == sizeof(MSG1));

        memcpy(&address, &socketaddress.sin_addr.s_addr, sizeof(address));
        address = ntohl(address);
        EXPECT(address == localhost);
        port = socketaddress.sin_port;
        port = ntohs(port);
        EXPECT(port == port1);
        EXPECT(strcmp(buffer, MSG1) == 0);

        for (cp = CMSG_FIRSTHDR(&message); cp != (struct cmsghdr *)0; cp = CMSG_NXTHDR(&message, cp)) {
            CHECKPOINT("control2 level=%d type=%d len=%lu\n", cp->cmsg_level, cp->cmsg_type, cp->cmsg_len);
            if (cp->cmsg_level != SOL_SOCKET) { continue; }
            if (cp->cmsg_type != SO_TIMESTAMP) { continue; }
            if (cp->cmsg_len != CMSG_LEN(sizeof(timestamp))) { continue; }
            memcpy(&timestamp, CMSG_DATA(cp), sizeof(timestamp));
            timestamp2 = diminuto_frequency_seconds2ticks(timestamp.tv_sec, timestamp.tv_usec, 1000000LL);
            break;
        }
        ASSERT(cp != (struct cmsghdr *)0);

        CHECKPOINT("timestamp2=%lld\n", (diminuto_lld_t)timestamp2);
        EXPECT(diminuto_time_zulu(timestamp2, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp2=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        socketaddress.sin_family = AF_INET;
        port = htons(port1);
        socketaddress.sin_port = port;
        address = htonl(localhost);
        memcpy(&socketaddress.sin_addr.s_addr, &address, sizeof(address));

        vector.iov_base = (void *)MSG2;
        vector.iov_len = sizeof(MSG2);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = (void *)0;
        message.msg_controllen = 0;

        EXPECT((diminuto_ipc_message_send(fd2, &message)) == sizeof(MSG2));

        memset(&message, 0, sizeof(message));
        memset(&socketaddress, 0, sizeof(socketaddress));
        memset(&vector, 0, sizeof(vector));
        memset(&control, 0, sizeof(control));

        vector.iov_base = buffer;
        vector.iov_len = sizeof(buffer);

        message.msg_name = &socketaddress;
        message.msg_namelen = sizeof(socketaddress);
        message.msg_iov = &vector;
        message.msg_iovlen = 1;
        message.msg_control = &control;
        message.msg_controllen = sizeof(control);

        EXPECT((diminuto_ipc_message_receive(fd1, &message)) == sizeof(MSG2));

        memcpy(&address, &socketaddress.sin_addr.s_addr, sizeof(address));
        address = ntohl(address);
        EXPECT(address == localhost);
        port = socketaddress.sin_port;
        port = ntohs(port);
        EXPECT(port == port2);
        EXPECT(strcmp(buffer, MSG2) == 0);

        for (cp = CMSG_FIRSTHDR(&message); cp != (struct cmsghdr *)0; cp = CMSG_NXTHDR(&message, cp)) {
            CHECKPOINT("control1 level=%d type=%d len=%lu\n", cp->cmsg_level, cp->cmsg_type, cp->cmsg_len);
            if (cp->cmsg_level != SOL_SOCKET) { continue; }
            if (cp->cmsg_type != SO_TIMESTAMP) { continue; }
            if (cp->cmsg_len != CMSG_LEN(sizeof(timestamp))) { continue; }
            memcpy(&timestamp, CMSG_DATA(cp), sizeof(timestamp));
            timestamp1 = diminuto_frequency_seconds2ticks(timestamp.tv_sec, timestamp.tv_usec, 1000000LL);
            break;
        }
        ASSERT(cp != (struct cmsghdr *)0);

        CHECKPOINT("timestamp1=%lld\n", (diminuto_lld_t)timestamp1);
        EXPECT(diminuto_time_zulu(timestamp1, &year, &month, &day, &hour, &minute, &second, &ticks) == 0);
        CHECKPOINT("timestamp1=%04d-%02d-%02dT%02d:%02d:%02d.%09lld\n", year, month, day, hour, minute, second, (diminuto_lld_t)diminuto_frequency_ticks2fractionalseconds(ticks, 1000000000LL));

        EXPECT(timestamp1 > now);
        EXPECT(timestamp2 > now);
        EXPECT(timestamp1 > timestamp2);
        EXPECT((timestamp1 - timestamp2) < diminuto_frequency());

        EXPECT(diminuto_ipc4_close(fd1) >= 0);
        EXPECT(diminuto_ipc4_close(fd2) >= 0);

        STATUS();
    }

    {
{'fraction_non_alphanumeric': 0.1523350852301113, 'fraction_numerical': 0.03545093023720549, 'mean_word_length': 2.5846704871060173, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 171, 'https://': 2, 'lorem ipsum': 0, 'www.': 12, 'xml': 0}, 'pii_count': 8, 'substrings_counts': 14, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5258263', 'n_tokens_mistral': 18633, 'n_tokens_neox': 17800, 'n_words': 3362}