From c697fb6345f32740a5f590713515894e9b0116df Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 17 Sep 2018 17:45:22 +0200 Subject: [PATCH] Simple bulk TCP test Send 8 MiB from one socket to another, anticipating short writes and short reads from sockets. Fix #2989 --- repos/libports/run/tcp_bulk.inc | 112 +++++++++++++++++ repos/libports/run/tcp_bulk_lwip.run | 2 + repos/libports/run/tcp_bulk_lxip.run | 2 + repos/libports/src/test/tcp/main.c | 167 ++++++++++++++++++++++++++ repos/libports/src/test/tcp/target.mk | 5 + 5 files changed, 288 insertions(+) create mode 100644 repos/libports/run/tcp_bulk.inc create mode 100644 repos/libports/run/tcp_bulk_lwip.run create mode 100644 repos/libports/run/tcp_bulk_lxip.run create mode 100644 repos/libports/src/test/tcp/main.c create mode 100644 repos/libports/src/test/tcp/target.mk diff --git a/repos/libports/run/tcp_bulk.inc b/repos/libports/run/tcp_bulk.inc new file mode 100644 index 000000000..8e45d63b3 --- /dev/null +++ b/repos/libports/run/tcp_bulk.inc @@ -0,0 +1,112 @@ +create_boot_directory + +append build_components { + core init + drivers/timer + server/nic_bridge + server/nic_loopback + test/tcp +} + +append_socket_fs_build_components + +build $build_components + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <} [socket_fs_plugin] { ip_addr="192.168.1.1" netmask="255.255.255.0"/> + + + + + + + + + + + + + + + + + + + + <} [socket_fs_plugin] { ip_addr="192.168.1.2" netmask="255.255.255.0"/> + + + + + + + + + + +} + +install_config $config + +append boot_modules { + core ld.lib.so init timer + nic_bridge + nic_loopback + posix.lib.so libc.lib.so libm.lib.so vfs.lib.so vfs_lwip.lib.so + test-tcp +} + +append_socket_fs_boot_modules + +build_boot_image $boot_modules + +append qemu_args " -nographic" + +run_genode_until {child "recv" exited with exit value 0} 240 + +# vi: set ft=tcl : diff --git a/repos/libports/run/tcp_bulk_lwip.run b/repos/libports/run/tcp_bulk_lwip.run new file mode 100644 index 000000000..fe9f4f914 --- /dev/null +++ b/repos/libports/run/tcp_bulk_lwip.run @@ -0,0 +1,2 @@ +source ${genode_dir}/repos/libports/run/vfs_lwip.inc +source ${genode_dir}/repos/libports/run/tcp_bulk.inc diff --git a/repos/libports/run/tcp_bulk_lxip.run b/repos/libports/run/tcp_bulk_lxip.run new file mode 100644 index 000000000..3c5b33369 --- /dev/null +++ b/repos/libports/run/tcp_bulk_lxip.run @@ -0,0 +1,2 @@ +source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc +source ${genode_dir}/repos/libports/run/tcp_bulk.inc diff --git a/repos/libports/src/test/tcp/main.c b/repos/libports/src/test/tcp/main.c new file mode 100644 index 000000000..9e337e7c3 --- /dev/null +++ b/repos/libports/src/test/tcp/main.c @@ -0,0 +1,167 @@ +/* + * \brief Libc tcp send and recv test + * \author Emery Hemingway + * \date 2018-09-17 + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* Libc includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PCG includes */ +#include + +enum { NUM_TEST_INTS = 1<<20, BULK_ITERATIONS = 2 }; + +static uint32_t data[NUM_TEST_INTS]; + +int test_send(char const *host) +{ + usleep(1000000); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror("`socket` failed"); + return sock; + } + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(host); + addr.sin_port = htons(2); + + fprintf(stderr, "connect to %s\n", host); + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr))) { + perror("`connect` failed"); + return ~0; + } + } + + pcg32_random_t rng = PCG32_INITIALIZER; + for (int j = 0; j < BULK_ITERATIONS; ++j) { + for (size_t i = 0; i < NUM_TEST_INTS; ++i) + data[i] = pcg32_random_r(&rng); + + size_t total = sizeof(data); + size_t offset = 0; + + char *buf = (char *)data; + while (offset < total) { + ssize_t res = send(sock, buf+offset, total-offset, 0); + if (res < 1) { + perror("send failed"); + return -1; + } + offset += res; + } + } + + fprintf(stderr, "close server\n"); + shutdown(sock, SHUT_RDWR); + usleep(10000000); + + return 0; +} + +int test_recv() +{ + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror("`socket` failed"); + return sock; + } + + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(2); + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) { + perror("`bind` failed"); + return ~0; + } + } + + if (listen(sock, 1)) { + perror("listen broke"); + } + + for (;;) { + char string[INET_ADDRSTRLEN]; + struct sockaddr_in addr; + socklen_t super_socket_safety = sizeof(addr); + + int client = accept(sock, (struct sockaddr*)&addr, &super_socket_safety); + if (client < 0) { + perror("invalid socket from accept!"); + return ~0; + } + + inet_ntop(AF_INET, &(addr.sin_addr), string, super_socket_safety); + fprintf(stderr, "recv from %s\n", string); + + pcg32_random_t rng = PCG32_INITIALIZER; + for (int j = 0; j < BULK_ITERATIONS; ++j) { + + size_t total = sizeof(data); + size_t offset = 0; + char *buf = (char *)data; + while (offset < total) { + ssize_t res = recv(client, buf+offset, total-offset, 0); + if (res < 1) { + perror("recv failed"); + return ~0; + } + offset += res; + } + + for (size_t i = 0; i < NUM_TEST_INTS; ++i) { + if (data[i] != pcg32_random_r(&rng)) { + fprintf(stderr, "bad data at byte offset %ld\n", i<<2); + return ~0; + } + } + } + + fprintf(stderr, "close client\n"); + shutdown(client, SHUT_RDWR); + return 0; + } +} + +int main(int argc, char **argv) +{ + if (argc < 1) { + fprintf(stderr, "no test name passed thru argv\n"); + return ~0; + } + if (argc < 2) { + if (strcmp(argv[0], "recv") == 0) + return test_recv(); + } + if (argc < 3) { + if (strcmp(argv[0], "send") == 0) + return test_send(argv[1]); + } + + fprintf(stderr, "\"%s\" not a valid test\n", argv[0]); + return ~0; +} diff --git a/repos/libports/src/test/tcp/target.mk b/repos/libports/src/test/tcp/target.mk new file mode 100644 index 000000000..9d56b7e1d --- /dev/null +++ b/repos/libports/src/test/tcp/target.mk @@ -0,0 +1,5 @@ +TARGET = test-tcp +LIBS += posix libc libpcg_random +SRC_C += main.c + +CC_CXX_WARN_STRICT =