From e3d8b6098f1935053360d7036414b0fe3936aaeb Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 27 Apr 2017 14:59:39 +0200 Subject: [PATCH] netty: do UDP and TCP tests This commit replaces echo_udp with the netty_udp test. TCP can be tested via netty_tcp. --- repos/libports/run/echo_udp.run | 124 -------- repos/libports/run/{netty.run => netty.inc} | 77 +---- repos/libports/run/netty_tcp.run | 72 +++++ repos/libports/run/netty_udp.run | 45 +++ repos/libports/src/test/echo_udp/main.cc | 141 --------- repos/libports/src/test/echo_udp/target.mk | 3 - repos/libports/src/test/netty/main.cc | 311 -------------------- repos/libports/src/test/netty/netty.cc | 140 +++++++++ repos/libports/src/test/netty/netty.h | 93 ++++++ repos/libports/src/test/netty/target.mk | 3 - repos/libports/src/test/netty/tcp/main.cc | 141 +++++++++ repos/libports/src/test/netty/tcp/target.mk | 7 + repos/libports/src/test/netty/udp/main.cc | 110 +++++++ repos/libports/src/test/netty/udp/target.mk | 7 + 14 files changed, 620 insertions(+), 654 deletions(-) delete mode 100644 repos/libports/run/echo_udp.run rename repos/libports/run/{netty.run => netty.inc} (50%) create mode 100644 repos/libports/run/netty_tcp.run create mode 100644 repos/libports/run/netty_udp.run delete mode 100644 repos/libports/src/test/echo_udp/main.cc delete mode 100644 repos/libports/src/test/echo_udp/target.mk delete mode 100644 repos/libports/src/test/netty/main.cc create mode 100644 repos/libports/src/test/netty/netty.cc create mode 100644 repos/libports/src/test/netty/netty.h delete mode 100644 repos/libports/src/test/netty/target.mk create mode 100644 repos/libports/src/test/netty/tcp/main.cc create mode 100644 repos/libports/src/test/netty/tcp/target.mk create mode 100644 repos/libports/src/test/netty/udp/main.cc create mode 100644 repos/libports/src/test/netty/udp/target.mk diff --git a/repos/libports/run/echo_udp.run b/repos/libports/run/echo_udp.run deleted file mode 100644 index 8d566d761..000000000 --- a/repos/libports/run/echo_udp.run +++ /dev/null @@ -1,124 +0,0 @@ -assert_spec x86 - -set build_components { - core init - drivers/timer drivers/nic lib/vfs/lxip - server/vfs server/dynamic_rom - test/echo_udp -} - -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - -build $build_components - -create_boot_directory - -append config { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -} - -append_platform_drv_config - -append config { - -} - -install_config $config - -append boot_modules { - core init timer } [nic_drv_binary] { vfs dynamic_rom - ld.lib.so libc.lib.so libm.lib.so - libc_resolv.lib.so - vfs_lxip.lib.so lxip.lib.so - test-echo_udp -} - -append_platform_drv_boot_modules - -build_boot_image $boot_modules - -puts "####################################################################" -puts "## run 'netcat --udp 7' to connect to the echo server ##" -puts "####################################################################" -sleep 1 - -append qemu_args " -nographic -net nic,model=e1000 -net tap,ifname=tap0,downscript=no,script=no " - -run_genode_until forever - -# vi: set ft=tcl : diff --git a/repos/libports/run/netty.run b/repos/libports/run/netty.inc similarity index 50% rename from repos/libports/run/netty.run rename to repos/libports/run/netty.inc index d9321b476..723e601fc 100644 --- a/repos/libports/run/netty.run +++ b/repos/libports/run/netty.inc @@ -3,17 +3,12 @@ assert_spec x86 set build_components { core init drivers/timer drivers/nic server/ram_fs server/vfs - test/netty lib/vfs/lxip } source ${genode_dir}/repos/base/run/platform_drv.inc append_platform_drv_build_components -build $build_components - -create_boot_directory - append config { @@ -36,6 +31,11 @@ append config { +} + +append_platform_drv_config + +append config { @@ -56,84 +56,17 @@ append config { - - - - - - - - - - - - - - - - } -append_platform_drv_config - -append config { - -} - -install_config $config - append boot_modules { core init timer } [nic_drv_binary] { ram_fs vfs ld.lib.so libc.lib.so libm.lib.so libc_resolv.lib.so stdcxx.lib.so libc_pipe.lib.so vfs_lxip.lib.so lxip.lib.so - test-netty } append_platform_drv_boot_modules -build_boot_image $boot_modules - append qemu_args " -nographic -net nic,model=e1000 -net tap,ifname=tap0,downscript=no,script=no " -run_genode_until forever - # vi: set ft=tcl : diff --git a/repos/libports/run/netty_tcp.run b/repos/libports/run/netty_tcp.run new file mode 100644 index 000000000..26bb2f334 --- /dev/null +++ b/repos/libports/run/netty_tcp.run @@ -0,0 +1,72 @@ +source ${genode_dir}/repos/libports/run/netty.inc + +append build_components { test/netty/tcp } + +build $build_components + +create_boot_directory + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +append boot_modules { test-netty_tcp } + +build_boot_image $boot_modules + +run_genode_until forever + +# vi: set ft=tcl : diff --git a/repos/libports/run/netty_udp.run b/repos/libports/run/netty_udp.run new file mode 100644 index 000000000..a3360a06c --- /dev/null +++ b/repos/libports/run/netty_udp.run @@ -0,0 +1,45 @@ +source ${genode_dir}/repos/libports/run/netty.inc + +append build_components { test/netty/udp } + +build $build_components + +create_boot_directory + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +append boot_modules { test-netty_udp } + +build_boot_image $boot_modules + +run_genode_until forever + +# vi: set ft=tcl : diff --git a/repos/libports/src/test/echo_udp/main.cc b/repos/libports/src/test/echo_udp/main.cc deleted file mode 100644 index b017a7317..000000000 --- a/repos/libports/src/test/echo_udp/main.cc +++ /dev/null @@ -1,141 +0,0 @@ -/* - * \brief RFC862 echo server - * \author Emery Hemingway - * \date 2016-10-17 - */ - -/* - * Copyright (C) 2016-2017 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. - */ - -/* Genode includes */ -#include - -/* libc includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ECHO_PORT 7 -#define MAXBUFLEN 0xFFFF -#define RECV_FLAGS 0 -#define SEND_FLAGS 0 - -static void print(Genode::Output &output, sockaddr_in const &addr) -{ - print(output, (ntohl(addr.sin_addr.s_addr) >> 24) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 16) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 8) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 0) & 0xff); - output.out_string(":"); - print(output, ntohs(addr.sin_port)); -} - -int main(void) -{ - int udp_sock; - int rv = 0; - int err = 0; - ssize_t numbytes; - struct sockaddr_in their_addr; - char buf[MAXBUFLEN]; - socklen_t addr_len; - struct sockaddr_in const addr = { 0, AF_INET, htons(ECHO_PORT), { INADDR_ANY } }; - - Genode::log("Create, bind, and close test..."); - unsigned i = 0; - for (; i < 10000; i++) { - - udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (udp_sock < 0) { - Genode::log("create failed with error ", udp_sock); - return errno; - } - err = bind(udp_sock, (struct sockaddr*)&addr, sizeof(addr)); - if (err) { - Genode::log("bind failed with error ", err); - return errno; - } - err = close(udp_sock); - if (err) { - Genode::log("close failed with error ", err); - return errno; - } - } - Genode::log("Create, bind, and close test succeeded"); - Genode::log("UDP echo test..."); - - udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (udp_sock < 0) { - Genode::log("create failed with error ", udp_sock); - return errno; - } - err = bind(udp_sock, (struct sockaddr*)&addr, sizeof(addr)); - if (err) { - Genode::log("bind failed with error ", err); - return errno; - } - - for (;;) { - fd_set read_fds; - - FD_ZERO(&read_fds); - FD_SET(udp_sock, &read_fds); - - timeval tv { 10, 0 }; - - int num_ready = select(udp_sock + 1, &read_fds, nullptr, nullptr, &tv); - if (num_ready == -1) { - perror("select failed"); - break; - } - if (!num_ready) { - Genode::log("timeout"); - continue; - } - if (!FD_ISSET(udp_sock, &read_fds)) { - Genode::log("spurious wakeup"); - continue; - } - Genode::log("num_ready=", num_ready); - - addr_len = sizeof their_addr; - numbytes = recvfrom(udp_sock, buf, sizeof(buf), RECV_FLAGS, - (struct sockaddr *)&their_addr, &addr_len); - if (numbytes == -1) { - rv = errno; - perror("recvfrom failed"); - break; - } - - Genode::log("received ", numbytes, " bytes from ", their_addr); - - numbytes = sendto(udp_sock, buf, numbytes, SEND_FLAGS, - (struct sockaddr *)&their_addr, addr_len); - if (numbytes == -1) { - rv = errno; - perror("sendto failed"); - break; - } - - Genode::log("sent ", numbytes, " bytes to ", their_addr); - } - - close(udp_sock); - return rv; -} diff --git a/repos/libports/src/test/echo_udp/target.mk b/repos/libports/src/test/echo_udp/target.mk deleted file mode 100644 index 4ab3155c8..000000000 --- a/repos/libports/src/test/echo_udp/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -TARGET = test-echo_udp -LIBS = posix libc_resolv -SRC_CC = main.cc diff --git a/repos/libports/src/test/netty/main.cc b/repos/libports/src/test/netty/main.cc deleted file mode 100644 index 6e4f72424..000000000 --- a/repos/libports/src/test/netty/main.cc +++ /dev/null @@ -1,311 +0,0 @@ -/* - * \brief Network TCP echo test - * \author Christian Helmuth - * \date 2015-09-21 - */ - -/* - * Copyright (C) 2015-2017 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. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include - -/* Libc includes */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -typedef Genode::String<32> String; - - -#define DIE(step) \ - do { \ - Genode::error("dying..."); \ - perror(step); \ - exit(1); \ - } while (0) - - -static void print(Genode::Output &output, sockaddr_in const &addr) -{ - print(output, (ntohl(addr.sin_addr.s_addr) >> 24) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 16) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 8) & 0xff); - output.out_string("."); - print(output, (ntohl(addr.sin_addr.s_addr) >> 0) & 0xff); - output.out_string(":"); - print(output, ntohs(addr.sin_port)); -} - - -static size_t test_nonblocking(int cd, bool const use_read_write) -{ - Genode::log("test in non-blocking mode"); - - int ret = 0; - - { - ret = fcntl(cd, F_GETFL); - if (ret == -1) DIE("fcntl"); - Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")"); - - ret = fcntl(cd, F_SETFL, ret | O_NONBLOCK); - if (ret == -1) DIE("fcntl"); - - ret = fcntl(cd, F_GETFL); - if (ret == -1) DIE("fcntl"); - Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")"); - } - - size_t count = 0; - static char data[64*1024]; - - while (true) { - ret = use_read_write - ? read(cd, data, sizeof(data)) - : recv(cd, data, sizeof(data), 0); - - if (ret == 0) { - Genode::log("experienced EOF"); - return count; - } - - if (ret > 0) { - /* echo received data */ - ret = use_read_write - ? write(cd, data, ret) - : send(cd, data, ret, 0); - if (ret == -1) DIE(use_read_write ? "write" : "send"); - - count += ret; - continue; - } - - if (errno != EAGAIN) DIE(use_read_write ? "read" : "recv"); - - Genode::log("block in select because of EAGAIN"); - fd_set read_fds; FD_ZERO(&read_fds); FD_SET(cd, &read_fds); - int ret = select(cd + 1, &read_fds, nullptr, nullptr, nullptr); - if (ret == -1) DIE("select"); - } -} - - -static size_t test_blocking(int cd, bool const use_read_write) -{ - Genode::log("test in blocking mode"); - - size_t count = 0; - int ret = 0; - static char data[64*1024]; - - while (true) { - if (use_read_write) { - ret = read(cd, data, sizeof(data)); - if (ret == -1) DIE("read"); - } else { - ret = recv(cd, data, sizeof(data), 0); - if (ret == -1) DIE("recv"); - } - - /* EOF */ - if (ret == 0) { - Genode::log("experienced EOF"); - return count; - } - - if (use_read_write) { - ret = write(cd, data, ret); - if (ret == -1) DIE("write"); - } else { - ret = send(cd, data, ret, 0); - if (ret == -1) DIE("send"); - } - - count += ret; - } -} - - -static void test_getnames(int sd) -{ - int err = 0; - - sockaddr_in addr; - socklen_t addr_len; - - memset(&addr, 0, sizeof(addr)); - addr_len = sizeof(addr); - - err = getsockname(sd, (sockaddr *)&addr, &addr_len); - if (err == -1) DIE("getsockname"); - - Genode::log("sock ", addr); - - memset(&addr, 0, sizeof(addr)); - addr_len = sizeof(addr); - - err = getpeername(sd, (sockaddr *)&addr, &addr_len); - if (err == -1) DIE("getpeername"); - - Genode::log("peer ", addr); -} - - -static void server(Genode::Env &env, Genode::Xml_node const config) -{ - int ret = 0; - - Genode::log("Let's serve"); - - int sd = socket(AF_INET, SOCK_STREAM, 0); - - Genode::log("sd=", sd); - if (sd == -1) DIE("socket"); - - unsigned const port = config.attribute_value("port", 8080U); - bool const use_read_write = config.attribute_value("read_write", false); - bool const nonblock = config.attribute_value("nonblock", false); - - Genode::log("config: port=", port, " read_write=", use_read_write, - " nonblock=", nonblock); - - sockaddr_in const addr { 0, AF_INET, htons(port), { INADDR_ANY } }; - sockaddr const *paddr = reinterpret_cast(&addr); - - if (1) { - int const on = 1; - ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - } - - ret = bind(sd, paddr, sizeof(addr)); - if (ret == -1) DIE("bind"); - - ret = listen(sd, SOMAXCONN); - if (ret == -1) DIE("listen"); - - bool const loop = true; - do { - Genode::log("accepting connections on ", port); - - sockaddr_in caddr; - socklen_t scaddr = sizeof(caddr); - sockaddr *pcaddr = reinterpret_cast(&caddr); - int cd = accept(sd, pcaddr, &scaddr); - Genode::log("cd=", cd); - if (cd == -1) DIE("accept"); - - test_getnames(cd); - - size_t const count = nonblock - ? test_nonblocking(cd, use_read_write) - : test_blocking(cd, use_read_write); - Genode::log("echoed ", count, " bytes"); - - ret = shutdown(cd, SHUT_RDWR); - if (ret == -1) DIE("shutdown"); - - ret = close(cd); - if (ret == -1) DIE("close"); - - } while (loop); -} - - -static void client(Genode::Xml_node const config) -{ - int ret = 0; - - Genode::log("Let's connect"); - - int sd = socket(AF_INET, SOCK_STREAM, 0); - - Genode::log("sd=", sd); - if (sd == -1) DIE("socket"); - - String const ip(config.attribute_value("ip", String("10.0.2.1"))); - unsigned const port(config.attribute_value("port", 8080U)); - - Genode::log("Connecting to %s:%u", ip.string(), port); - - sockaddr_in const addr { 0, AF_INET, htons(port), { inet_addr(ip.string()) } }; - sockaddr const *paddr = reinterpret_cast(&addr); - - ret = connect(sd, paddr, sizeof(addr)); - if (ret == -1) DIE("connect"); - - Genode::log("connected"); - - static char data[1*1024*1024]; - memset(data, 'X', sizeof(data)); - - /* wait for go */ - char go; - ret = recv(sd, &go, sizeof(go), 0); - if (ret == -1) DIE("recv"); - - /* EOF */ - if (ret == 0) DIE("EOF"); - - ret = send(sd, data, sizeof(data), 0); - if (ret == -1) DIE("send"); - - ret = shutdown(sd, SHUT_RDWR); - if (ret == -1) DIE("shutdown"); - - ret = close(sd); - if (ret == -1) DIE("close"); -} - - -struct Main -{ - String mode { "server" }; - - Main(Genode::Env &env) - { - Libc::with_libc([&] () { - Genode::Xml_node config { "" }; - - /* parse mode configuration */ - try { - static Genode::Attached_rom_dataspace rom(env, "config"); - - config = rom.xml(); - } catch (Genode::Rom_connection::Rom_connection_failed) { } - - mode = config.attribute_value("mode", mode); - - if (mode == "server") { - server(env, config); - } else if (mode == "client") { - client(config); - } else { - Genode::error("unknown mode '", mode.string(), "'"); - exit(__LINE__); - } - }); - } -}; - - -void Libc::Component::construct(Libc::Env &env) { static Main inst(env); } diff --git a/repos/libports/src/test/netty/netty.cc b/repos/libports/src/test/netty/netty.cc new file mode 100644 index 000000000..e3e2389a3 --- /dev/null +++ b/repos/libports/src/test/netty/netty.cc @@ -0,0 +1,140 @@ +/* + * \brief Network echo test + * \author Christian Helmuth + * \date 2017-04-24 + */ + +/* + * Copyright (C) 2017 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. + */ + +/* Local includes */ +#include + + +void Netty::Test::nonblocking(int fd) +{ + int ret = 0; + + ret = fcntl(fd, F_GETFL); + if (ret == -1) DIE("fcntl"); + Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")"); + + ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK); + if (ret == -1) DIE("fcntl"); + + ret = fcntl(fd, F_GETFL); + if (ret == -1) DIE("fcntl"); + Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")"); +} + + +void Netty::Test::_server() +{ + int ret = 0; + + Genode::log("initialize server"); + + int const sd = socket(); + + Genode::log("sd=", sd); + if (sd == -1) DIE("socket"); + + unsigned const port = _config.attribute_value("port", 8080U); + bool const read_write = _config.attribute_value("read_write", false); + bool const nonblock = _config.attribute_value("nonblock", false); + + Genode::log("config: port=", port, " read_write=", read_write, + " nonblock=", nonblock); + + sockaddr_in const addr { 0, AF_INET, htons(port), { INADDR_ANY } }; + sockaddr const *paddr = reinterpret_cast(&addr); + + if (1) { + int const on = 1; + ret = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + } + + ret = bind(sd, paddr, sizeof(addr)); + if (ret == -1) DIE("bind"); + + server(sd, nonblock, read_write); + + close(sd); + if (ret == -1) DIE("close"); +} + + +void Netty::Test::_client() +{ + int ret = 0; + + Genode::log("initialize client"); + + int const sd = socket(); + + Genode::log("sd=", sd); + if (sd == -1) DIE("socket"); + + String const ip(_config.attribute_value("ip", String("10.0.2.1"))); + unsigned const port = _config.attribute_value("port", 8080U); + bool const read_write = _config.attribute_value("read_write", false); + bool const nonblock = _config.attribute_value("nonblock", false); + + Genode::log("config: ip=", ip.string(), " port=", port, + " read_write=", read_write, " nonblock=", nonblock); + + sockaddr_in const addr { 0, AF_INET, htons(port), { inet_addr(ip.string()) } }; + + client(sd, addr, nonblock, read_write); + + ret = close(sd); + if (ret == -1) DIE("close"); + + Genode::log("client test finished"); +} + + +void Netty::Test::getnames(int const sd) +{ + int err = 0; + + sockaddr_in addr; + socklen_t addr_len; + + memset(&addr, 0, sizeof(addr)); + addr_len = sizeof(addr); + + err = getsockname(sd, (sockaddr *)&addr, &addr_len); + if (err == -1) perror("getsockname"); + + Genode::log("sock ", addr); + + memset(&addr, 0, sizeof(addr)); + addr_len = sizeof(addr); + + err = getpeername(sd, (sockaddr *)&addr, &addr_len); + if (err == -1) perror("getpeername"); + + Genode::log("peer ", addr); +} + + +void Netty::Test::run() +{ + String mode { _config.attribute_value("mode", String("server")) }; + + Libc::with_libc([&] () { + if (mode == "server") { + _server(); + } else if (mode == "client") { + _client(); + } else { + Genode::error("unknown mode '", mode.string(), "'"); + exit(__LINE__); + } + }); +} diff --git a/repos/libports/src/test/netty/netty.h b/repos/libports/src/test/netty/netty.h new file mode 100644 index 000000000..0086087ec --- /dev/null +++ b/repos/libports/src/test/netty/netty.h @@ -0,0 +1,93 @@ +/* + * \brief Network echo test utilities + * \author Christian Helmuth + * \date 2017-04-11 + */ + +/* + * Copyright (C) 2017 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. + */ + +#ifndef _NETTY_H_ +#define _NETTY_H_ + +/* Genode includes */ +#include +#include +#include +#include + +/* Libc includes */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#define DIE(step) \ + do { \ + Genode::error("dying..."); \ + perror(step); \ + exit(1); \ + } while (0) + + +static inline void print(Genode::Output &output, sockaddr_in const &addr) +{ + Genode::print(output, (ntohl(addr.sin_addr.s_addr) >> 24) & 0xff); + output.out_string("."); + Genode::print(output, (ntohl(addr.sin_addr.s_addr) >> 16) & 0xff); + output.out_string("."); + Genode::print(output, (ntohl(addr.sin_addr.s_addr) >> 8) & 0xff); + output.out_string("."); + Genode::print(output, (ntohl(addr.sin_addr.s_addr) >> 0) & 0xff); + output.out_string(":"); + Genode::print(output, ntohs(addr.sin_port)); +} + + +namespace Netty { + + typedef Genode::String<32> String; + + struct Test; +} + + +struct Netty::Test +{ + private: + + Libc::Env &_env; + Genode::Attached_rom_dataspace _config_rom { _env, "config" }; + Genode::Xml_node _config { _config_rom.xml() }; + + void _server(); + void _client(); + + public: + + Test(Libc::Env &env) : _env(env) { } + + virtual ~Test() { } + + void run(); + void getnames(int const sd); + void nonblocking(int fd); + + /* hooks for the test */ + virtual int socket() = 0; + virtual void server(int sd, bool nonblock, bool read_write) = 0; + virtual void client(int sd, sockaddr_in addr, bool nonblock, bool read_write) = 0; +}; + +#endif /* _NETTY_H_ */ diff --git a/repos/libports/src/test/netty/target.mk b/repos/libports/src/test/netty/target.mk deleted file mode 100644 index 32f949039..000000000 --- a/repos/libports/src/test/netty/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -TARGET = test-netty -SRC_CC = main.cc -LIBS = stdcxx libc_pipe libc_resolv diff --git a/repos/libports/src/test/netty/tcp/main.cc b/repos/libports/src/test/netty/tcp/main.cc new file mode 100644 index 000000000..4c15a07a5 --- /dev/null +++ b/repos/libports/src/test/netty/tcp/main.cc @@ -0,0 +1,141 @@ +/* + * \brief Network TCP echo test + * \author Christian Helmuth + * \date 2017-04-11 + */ + +/* + * Copyright (C) 2017 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. + */ + +/* Local includes */ +#include + + +namespace Netty { struct Tcp; } + + +struct Netty::Tcp : Netty::Test +{ + Tcp(Libc::Env &env) : Test(env) { run(); } + + int socket() override; + void server(int, bool, bool) override; + void client(int, sockaddr_in, bool, bool) override; +}; + + +int Netty::Tcp::socket() { return ::socket(AF_INET, SOCK_STREAM, 0); } + + +void Netty::Tcp::server(int const sd, bool const nonblock, bool const read_write) +{ + int ret = 0; + + ret = listen(sd, SOMAXCONN); + if (ret == -1) DIE("listen"); + + while (true) { + sockaddr_in caddr; + socklen_t scaddr = sizeof(caddr); + sockaddr *pcaddr = reinterpret_cast(&caddr); + + if (nonblock) { + nonblocking(sd); + + Genode::log("I want EAGAIN"); + int test = accept(sd, pcaddr, &scaddr); + if (test == -1 && errno == EAGAIN) + Genode::log("I got EAGAIN"); + else + Genode::error("Did not get EAGAIN but test=", test, " errno=", errno); + + fd_set read_fds; FD_ZERO(&read_fds); FD_SET(sd, &read_fds); + ret = select(sd + 1, &read_fds, nullptr, nullptr, nullptr); + if (ret == -1) DIE("select"); + Genode::log("okay, accept will not block"); + } + + Genode::log("test in ", nonblock ? "non-blocking" : "blocking", " mode"); + + int const cd = accept(sd, pcaddr, &scaddr); + Genode::log("cd=", cd); + if (cd == -1) DIE("accept"); + + getnames(cd); + + size_t count = 0; + static char data[64*1024]; + + if (nonblock) nonblocking(cd); + + while (true) { + int ret = read_write + ? read(cd, data, sizeof(data)) + : recv(cd, data, sizeof(data), 0); + + if (ret == 0) { + Genode::log("experienced EOF"); + break; + } + + if (ret > 0) { + /* echo received data */ + ret = read_write + ? write(cd, data, ret) + : send(cd, data, ret, 0); + if (ret == -1) DIE(read_write ? "write" : "send"); + + count += ret; + continue; + } + + if (!nonblock || errno != EAGAIN) + DIE(read_write ? "read" : "recv"); + + Genode::log("block in select because of EAGAIN"); + fd_set read_fds; FD_ZERO(&read_fds); FD_SET(cd, &read_fds); + ret = select(cd + 1, &read_fds, nullptr, nullptr, nullptr); + if (ret == -1) DIE("select"); + } + + Genode::log("echoed ", count, " bytes"); + + ret = shutdown(cd, SHUT_RDWR); + if (ret == -1) DIE("shutdown"); + + ret = close(cd); + if (ret == -1) DIE("close"); + } +} + + +void Netty::Tcp::client(int const sd, sockaddr_in const addr, + bool const nonblock, bool const read_write) +{ + /* TODO nonblock, read_write */ + + sockaddr const *paddr = reinterpret_cast(&addr); + + int ret = 0; + + ret = connect(sd, paddr, sizeof(addr)); + if (ret == -1) DIE("connect"); + + Genode::log("connected"); + + static char data[16*1024]; + memset(data, 'X', sizeof(data)); + + ret = send(sd, data, sizeof(data), 0); + if (ret == -1) DIE("send"); + + ret = shutdown(sd, SHUT_RDWR); + if (ret == -1) DIE("shutdown"); +} + + +void Libc::Component::construct(Libc::Env &env) { static Netty::Tcp inst(env); } diff --git a/repos/libports/src/test/netty/tcp/target.mk b/repos/libports/src/test/netty/tcp/target.mk new file mode 100644 index 000000000..c90784e9e --- /dev/null +++ b/repos/libports/src/test/netty/tcp/target.mk @@ -0,0 +1,7 @@ +TARGET = test-netty_tcp +SRC_CC = main.cc netty.cc +LIBS = libc libc_resolv + +INC_DIR += $(PRG_DIR)/.. + +vpath netty.cc $(PRG_DIR)/.. diff --git a/repos/libports/src/test/netty/udp/main.cc b/repos/libports/src/test/netty/udp/main.cc new file mode 100644 index 000000000..65257e7ec --- /dev/null +++ b/repos/libports/src/test/netty/udp/main.cc @@ -0,0 +1,110 @@ +/* + * \brief Network UDP echo test + * \author Christian Helmuth + * \date 2017-04-25 + */ + +/* + * Copyright (C) 2017 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. + */ + +/* Local includes */ +#include + + +namespace Netty { struct Udp; } + + +struct Netty::Udp : Netty::Test +{ + Udp(Libc::Env &env) : Test(env) { run(); } + + int socket() override; + void server(int, bool, bool) override; + void client(int, sockaddr_in, bool, bool) override; +}; + + +int Netty::Udp::socket() { return ::socket(AF_INET, SOCK_DGRAM, 0); } + + +void Netty::Udp::server(int const sd, bool const nonblock, bool const read_write) +{ + if (read_write) + Genode::warning("ignoring read_write attribute for UDP tests"); + + int ret = 0; + + while (true) { + sockaddr_in caddr; + socklen_t scaddr = sizeof(caddr); + sockaddr *pcaddr = reinterpret_cast(&caddr); + + static char data[64*1024]; + + if (nonblock) { + nonblocking(sd); + + Genode::log("I want EAGAIN"); + ssize_t test = recvfrom(sd, data, sizeof(data), 0, pcaddr, &scaddr); + if (test == -1 && errno == EAGAIN) + Genode::log("I got EAGAIN"); + else + Genode::error("Did not get EAGAIN but test=", test, " errno=", errno); + + fd_set read_fds; FD_ZERO(&read_fds); FD_SET(sd, &read_fds); + ret = select(sd + 1, &read_fds, nullptr, nullptr, nullptr); + if (ret == -1) DIE("select"); + Genode::log("okay, recvfrom will not block"); + } + + Genode::log("test in ", nonblock ? "non-blocking" : "blocking", " mode"); + + ssize_t count = recvfrom(sd, data, sizeof(data), 0, pcaddr, &scaddr); + if (count == -1) DIE("recvfrom"); + + { + sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + getsockname(sd, (sockaddr *)&addr, &addr_len); + Genode::log("sock ", addr); + Genode::log("peer ", caddr); + } + + count = sendto(sd, data, count, 0, pcaddr, scaddr); + + Genode::log("echoed ", count, " bytes"); + } +} + + +void Netty::Udp::client(int const sd, sockaddr_in const addr, + bool const nonblock, bool const read_write) +{ + /* TODO nonblock, read_write */ + + sockaddr const *paddr = reinterpret_cast(&addr); + + int ret = 0; + + ret = connect(sd, paddr, sizeof(addr)); + if (ret == -1) DIE("connect"); + + Genode::log("connected"); + + static char data[16*1024]; + memset(data, 'X', sizeof(data)); + + ret = send(sd, data, sizeof(data), 0); + if (ret == -1) DIE("send"); + + ret = shutdown(sd, SHUT_RDWR); + if (ret == -1) DIE("shutdown"); +} + + +void Libc::Component::construct(Libc::Env &env) { static Netty::Udp inst(env); } diff --git a/repos/libports/src/test/netty/udp/target.mk b/repos/libports/src/test/netty/udp/target.mk new file mode 100644 index 000000000..aa4c29c5e --- /dev/null +++ b/repos/libports/src/test/netty/udp/target.mk @@ -0,0 +1,7 @@ +TARGET = test-netty_udp +SRC_CC = main.cc netty.cc +LIBS = libc libc_resolv + +INC_DIR += $(PRG_DIR)/.. + +vpath netty.cc $(PRG_DIR)/..