libc: 'connect()' test

Fixes #3114
This commit is contained in:
Christian Prochaska 2019-01-10 17:47:16 +01:00 committed by Norman Feske
parent ed65267bc5
commit 12c10dbcd1
27 changed files with 777 additions and 2 deletions

View File

@ -606,6 +606,10 @@ set default_test_pkgs {
test-init_loop
test-ldso
test-libc
test-libc_connect_lwip
test-libc_connect_lxip
test-libc_connect_vfs_server_lwip
test-libc_connect_vfs_server_lxip
test-libc_counter
test-libc_getenv
test-libc_pipe

View File

@ -0,0 +1 @@
Libc connect test using the Lightweight-IP VFS plugin.

View File

@ -0,0 +1,8 @@
_/src/init
_/src/libc
_/src/nic_router
_/src/posix
_/src/test-libc_connect
_/src/test-netty
_/src/vfs
_/src/vfs_lwip

View File

@ -0,0 +1 @@
2019-01-03-j 7b0742a041cd92d00bf0c0426b5d3a77b7363a0a

View File

@ -0,0 +1,77 @@
<runtime ram="100M" caps="1000" binary="init">
<requires> <timer/> </requires>
<events>
<timeout meaning="failed" sec="80" />
<log meaning="succeeded">child "test-libc_connect" exited with exit value 0</log>
</events>
<content>
<rom label="ld.lib.so"/>
<rom label="libc.lib.so"/>
<rom label="libm.lib.so"/>
<rom label="posix.lib.so"/>
<rom label="vfs.lib.so"/>
<rom label="vfs_lwip.lib.so"/>
<rom label="nic_router"/>
<rom label="test-netty_tcp"/>
<rom label="test-libc_connect"/>
</content>
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="256"/>
<start name="nic_router">
<resource name="RAM" quantum="10M"/>
<provides><service name="Nic"/></provides>
<config>
<domain name="default" interface="10.0.1.1/24"/>
<default-policy domain="default"/>
</config>
</start>
<start name="server">
<binary name="test-netty_tcp"/>
<resource name="RAM" quantum="4M"/>
<config port="80" read_write="yes" nonblock="false">
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket">
<lwip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1"/>
</dir>
<dir name="tmp"> <ram/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
</config>
</start>
<start name="test-libc_connect" caps="200">
<resource name="RAM" quantum="48M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket">
<lwip ip_addr="10.0.1.3" netmask="255.255.255.0" gateway="10.0.1.1"/>
</dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket" />
</config>
</start>
</config>
</runtime>

View File

@ -0,0 +1 @@
Libc connect test using the lxip VFS plugin.

View File

@ -0,0 +1,8 @@
_/src/init
_/src/libc
_/src/nic_router
_/src/posix
_/src/test-libc_connect
_/src/test-netty
_/src/vfs
_/src/vfs_lxip

View File

@ -0,0 +1 @@
2019-01-03-l 91d14e0ae5eb9425ff76c74c5c62ebad59ce18e5

View File

@ -0,0 +1,78 @@
<runtime ram="100M" caps="1000" binary="init">
<requires> <timer/> </requires>
<events>
<timeout meaning="failed" sec="80" />
<log meaning="succeeded">child "test-libc_connect" exited with exit value 0</log>
</events>
<content>
<rom label="ld.lib.so"/>
<rom label="libc.lib.so"/>
<rom label="libm.lib.so"/>
<rom label="posix.lib.so"/>
<rom label="vfs.lib.so"/>
<rom label="vfs_lxip.lib.so"/>
<rom label="lxip.lib.so"/>
<rom label="nic_router"/>
<rom label="test-netty_tcp"/>
<rom label="test-libc_connect"/>
</content>
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="256"/>
<start name="nic_router">
<resource name="RAM" quantum="10M"/>
<provides><service name="Nic"/></provides>
<config>
<domain name="default" interface="10.0.1.1/24"/>
<default-policy domain="default"/>
</config>
</start>
<start name="server">
<binary name="test-netty_tcp"/>
<resource name="RAM" quantum="32M"/>
<config port="80" read_write="yes" nonblock="false">
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket">
<lxip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1"/>
</dir>
<dir name="tmp"> <ram/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
</config>
</start>
<start name="test-libc_connect" caps="200">
<resource name="RAM" quantum="48M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket">
<lxip ip_addr="10.0.1.3" netmask="255.255.255.0" gateway="10.0.1.1"/>
</dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket" />
</config>
</start>
</config>
</runtime>

View File

@ -0,0 +1 @@
Libc connect test using the Lightweight-IP VFS plugin in a VFS server.

View File

@ -0,0 +1,8 @@
_/src/init
_/src/libc
_/src/nic_router
_/src/posix
_/src/test-libc_connect
_/src/test-netty
_/src/vfs
_/src/vfs_lwip

View File

@ -0,0 +1 @@
2019-01-04-c 97323faccecf3daaaf002dc027a49b7fa6595532

View File

@ -0,0 +1,102 @@
<runtime ram="128M" caps="1000" binary="init">
<requires> <timer/> </requires>
<events>
<timeout meaning="failed" sec="100" />
<log meaning="succeeded">child "test-libc_connect" exited with exit value 0</log>
</events>
<content>
<rom label="ld.lib.so"/>
<rom label="libc.lib.so"/>
<rom label="libm.lib.so"/>
<rom label="posix.lib.so"/>
<rom label="vfs.lib.so"/>
<rom label="vfs_lwip.lib.so"/>
<rom label="nic_router"/>
<rom label="vfs"/>
<rom label="test-netty_tcp"/>
<rom label="test-libc_connect"/>
</content>
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="150"/>
<start name="nic_router">
<resource name="RAM" quantum="10M"/>
<provides><service name="Nic"/></provides>
<config>
<domain name="default" interface="10.0.1.1/24"/>
<default-policy domain="default"/>
</config>
</start>
<start name="socket_fs_server">
<binary name="vfs"/>
<resource name="RAM" quantum="32M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <lwip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1"/> </vfs>
<policy label_prefix="server" root="/" writeable="yes"/>
</config>
</start>
<start name="socket_fs_client">
<binary name="vfs"/>
<resource name="RAM" quantum="32M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <lwip ip_addr="10.0.1.3" netmask="255.255.255.0" gateway="10.0.1.1"/> </vfs>
<policy label_prefix="test-libc_connect" root="/" writeable="yes"/>
</config>
</start>
<start name="server">
<binary name="test-netty_tcp"/>
<resource name="RAM" quantum="4M"/>
<config port="80" read_write="yes" nonblock="false">
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <fs/> </dir>
<dir name="tmp"> <ram/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
</config>
<route>
<service name="File_system"> <child name="socket_fs_server"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="test-libc_connect">
<resource name="RAM" quantum="4M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <fs/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket" />
</config>
<route>
<service name="File_system"> <child name="socket_fs_client"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>
</runtime>

View File

@ -0,0 +1 @@
Libc connect test using the lxip VFS plugin in a VFS server.

View File

@ -0,0 +1,8 @@
_/src/init
_/src/libc
_/src/nic_router
_/src/posix
_/src/test-libc_connect
_/src/test-netty
_/src/vfs
_/src/vfs_lxip

View File

@ -0,0 +1 @@
2019-01-04-d 1d09162ce289af49e5561cfa4a946ce66d7e3013

View File

@ -0,0 +1,103 @@
<runtime ram="128M" caps="1000" binary="init">
<requires> <timer/> </requires>
<events>
<timeout meaning="failed" sec="100" />
<log meaning="succeeded">child "test-libc_connect" exited with exit value 0</log>
</events>
<content>
<rom label="ld.lib.so"/>
<rom label="libc.lib.so"/>
<rom label="libm.lib.so"/>
<rom label="posix.lib.so"/>
<rom label="vfs.lib.so"/>
<rom label="vfs_lxip.lib.so"/>
<rom label="lxip.lib.so"/>
<rom label="nic_router"/>
<rom label="vfs"/>
<rom label="test-netty_tcp"/>
<rom label="test-libc_connect"/>
</content>
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="Timer"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="150"/>
<start name="nic_router">
<resource name="RAM" quantum="10M"/>
<provides><service name="Nic"/></provides>
<config>
<domain name="default" interface="10.0.1.1/24"/>
<default-policy domain="default"/>
</config>
</start>
<start name="socket_fs_server" caps="200">
<binary name="vfs"/>
<resource name="RAM" quantum="32M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <lxip ip_addr="10.0.1.2" netmask="255.255.255.0" gateway="10.0.1.1"/> </vfs>
<policy label_prefix="server" root="/" writeable="yes"/>
</config>
</start>
<start name="socket_fs_client" caps="200">
<binary name="vfs"/>
<resource name="RAM" quantum="32M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs> <lxip ip_addr="10.0.1.3" netmask="255.255.255.0" gateway="10.0.1.1"/> </vfs>
<policy label_prefix="test-libc_connect" root="/" writeable="yes"/>
</config>
</start>
<start name="server">
<binary name="test-netty_tcp"/>
<resource name="RAM" quantum="4M"/>
<config port="80" read_write="yes" nonblock="false">
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <fs/> </dir>
<dir name="tmp"> <ram/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
</config>
<route>
<service name="File_system"> <child name="socket_fs_server"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="test-libc_connect">
<resource name="RAM" quantum="4M"/>
<config>
<vfs>
<dir name="dev"> <log/> </dir>
<dir name="socket"> <fs/> </dir>
</vfs>
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket" />
</config>
<route>
<service name="File_system"> <child name="socket_fs_client"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>
</runtime>

View File

@ -0,0 +1,3 @@
SRC_DIR = src/test/libc_connect
include $(GENODE_DIR)/repos/base/recipes/src/content.inc

View File

@ -0,0 +1 @@
2019-01-03 a4edcc467817e5dbfda56cd46c85af6a39a883ce

View File

@ -0,0 +1,3 @@
base
posix
libc

View File

@ -0,0 +1,3 @@
SRC_DIR = src/test/netty
include $(GENODE_DIR)/repos/base/recipes/src/content.inc

View File

@ -0,0 +1 @@
2019-01-03-e e3582a89a5ad6632168209c3f50eced5546c0457

View File

@ -0,0 +1,5 @@
base
posix
libc
os
timer_session

View File

@ -0,0 +1,350 @@
/*
* \brief libc 'connect()' test
* \author Christian Prochaska
* \date 2019-01-11
*/
/*
* Copyright (C) 2019 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.
*/
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
static char const *server_connected = "10.0.1.2";
static char const *server_connection_refused = "10.0.1.2";
static char const *server_timeout = "10.0.1.4";
static int const port_connected = 80;
static int const port_connection_refused = 81;
static int const port_timeout = 80;
static void test_blocking_connect_connected()
{
printf("Testing blocking connect (connected)\n");
/*
* This is the first test and it can happen that the server is not ready
* yet, so this test retries until success.
*/
for (;;) {
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_connected);
addr.sin_addr.s_addr = inet_addr(server_connected);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (res == 0) {
/* keep the netty server alive */
char send_buf = 'x';
char receive_buf = 0;
write(s, &send_buf, sizeof(send_buf));
read(s, &receive_buf, sizeof(receive_buf));
if (receive_buf != send_buf) {
printf("Error: '%s' failed\n", __func__);
exit (-1);
}
close(s);
break;
}
if (errno != ECONNREFUSED) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
close(s);
printf("Warning: got 'connection refused'. "
"Server might not be ready yet, retrying...\n");
}
}
static void test_blocking_connect_connection_refused()
{
printf("Testing blocking connect (connection refused)\n");
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_connection_refused);
addr.sin_addr.s_addr = inet_addr(server_connection_refused);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == ECONNREFUSED))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
close(s);
}
static void test_blocking_connect_timeout()
{
printf("Testing blocking connect (timeout)\n");
int s = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_timeout);
addr.sin_addr.s_addr = inet_addr(server_timeout);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == ETIMEDOUT))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
close(s);
}
static void test_nonblocking_connect_connected()
{
printf("Testing nonblocking connect (connected)\n");
int s = socket(AF_INET, SOCK_STREAM, 0);
fcntl(s, F_SETFL, O_NONBLOCK);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_connected);
addr.sin_addr.s_addr = inet_addr(server_connected);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == EINPROGRESS))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
/* wait until socket is ready for writing */
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
struct timeval timeout {10, 0};
res = select(s + 1, NULL, &writefds, NULL, &timeout);
if (res != 1) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
int so_error = 0;
socklen_t opt_len = sizeof(so_error);
res = getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &opt_len);
if (!((res == 0) && (so_error == 0))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
res = getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &opt_len);
if (!((res == 0) && (so_error == 0))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
res = connect(s, paddr, sizeof(addr));
if (!((res == 0) || ((res == -1) && (errno == EISCONN)))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == EISCONN))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
/* keep the netty server alive */
char send_buf = 'x';
char receive_buf = 0;
write(s, &send_buf, sizeof(send_buf));
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(s, &readfds);
res = select(s + 1, &readfds, NULL, NULL, &timeout);
if (res != 1) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
read(s, &receive_buf, sizeof(receive_buf));
if (receive_buf != send_buf) {
printf("Error: '%s' failed\n", __func__);
exit (-1);
}
close(s);
}
static void test_nonblocking_connect_connection_refused()
{
printf("Testing nonblocking connect (connection refused)\n");
int s = socket(AF_INET, SOCK_STREAM, 0);
fcntl(s, F_SETFL, O_NONBLOCK);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_connection_refused);
addr.sin_addr.s_addr = inet_addr(server_connection_refused);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == EINPROGRESS))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
/* wait until socket is ready for writing */
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
struct timeval timeout {10, 0};
res = select(s + 1, NULL, &writefds, NULL, &timeout);
if (res != 1) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
int so_error = 0;
socklen_t opt_len = sizeof(so_error);
res = getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &opt_len);
if (!((res == 0) && (so_error == ECONNREFUSED))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
res = getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &opt_len);
if (!((res == 0) && (so_error == 0))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == ECONNABORTED))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
close(s);
}
static void test_nonblocking_connect_timeout()
{
printf("Testing nonblocking connect (timeout)\n");
int s = socket(AF_INET, SOCK_STREAM, 0);
fcntl(s, F_SETFL, O_NONBLOCK);
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port_timeout);
addr.sin_addr.s_addr = inet_addr(server_timeout);
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
int res = connect(s, paddr, sizeof(addr));
if (!((res == -1) && (errno == EINPROGRESS))) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
/* wait until socket is ready for writing */
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
struct timeval timeout {10, 0};
res = select(s + 1, NULL, &writefds, NULL, &timeout);
if (res != 0) {
printf("Error: '%s' failed\n", __func__);
exit(-1);
}
close(s);
}
int main(int argc, char *argv[])
{
test_blocking_connect_connected();
test_blocking_connect_connection_refused();
test_blocking_connect_timeout();
test_nonblocking_connect_connected();
test_nonblocking_connect_connection_refused();
test_nonblocking_connect_timeout();
return 0;
}

View File

@ -0,0 +1,5 @@
TARGET = test-libc_connect
SRC_CC = main.cc
LIBS = base libc posix
CC_CXX_WARN_STRICT =

View File

@ -1,6 +1,6 @@
TARGET = test-netty_tcp
SRC_CC = main.cc netty.cc
LIBS = libc
LIBS = base libc
INC_DIR += $(PRG_DIR)/..

View File

@ -1,6 +1,6 @@
TARGET = test-netty_udp
SRC_CC = main.cc netty.cc
LIBS = libc
LIBS = base libc
INC_DIR += $(PRG_DIR)/..