diff --git a/repos/gems/run/depot_autopilot.run b/repos/gems/run/depot_autopilot.run
index 9b8bd6c61d..cae1622bfd 100644
--- a/repos/gems/run/depot_autopilot.run
+++ b/repos/gems/run/depot_autopilot.run
@@ -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
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/README b/repos/libports/recipes/pkg/test-libc_connect_lwip/README
new file mode 100644
index 0000000000..10cea71381
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/README
@@ -0,0 +1 @@
+Libc connect test using the Lightweight-IP VFS plugin.
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/archives b/repos/libports/recipes/pkg/test-libc_connect_lwip/archives
new file mode 100644
index 0000000000..a4391f8532
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/archives
@@ -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
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/hash b/repos/libports/recipes/pkg/test-libc_connect_lwip/hash
new file mode 100644
index 0000000000..3c420a40f8
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/hash
@@ -0,0 +1 @@
+2019-01-03-j 7b0742a041cd92d00bf0c0426b5d3a77b7363a0a
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime b/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime
new file mode 100644
index 0000000000..a7a19de918
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lwip/runtime
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+ child "test-libc_connect" exited with exit value 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/README b/repos/libports/recipes/pkg/test-libc_connect_lxip/README
new file mode 100644
index 0000000000..27b59ae757
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/README
@@ -0,0 +1 @@
+Libc connect test using the lxip VFS plugin.
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/archives b/repos/libports/recipes/pkg/test-libc_connect_lxip/archives
new file mode 100644
index 0000000000..77fda2b83c
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/archives
@@ -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
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/hash b/repos/libports/recipes/pkg/test-libc_connect_lxip/hash
new file mode 100644
index 0000000000..1a5b485415
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/hash
@@ -0,0 +1 @@
+2019-01-03-l 91d14e0ae5eb9425ff76c74c5c62ebad59ce18e5
diff --git a/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime b/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime
new file mode 100644
index 0000000000..61b47c11a8
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_lxip/runtime
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ child "test-libc_connect" exited with exit value 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/README b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/README
new file mode 100644
index 0000000000..6da98d3b0f
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/README
@@ -0,0 +1 @@
+Libc connect test using the Lightweight-IP VFS plugin in a VFS server.
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/archives b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/archives
new file mode 100644
index 0000000000..a4391f8532
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/archives
@@ -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
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash
new file mode 100644
index 0000000000..9e1107cdff
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/hash
@@ -0,0 +1 @@
+2019-01-04-c 97323faccecf3daaaf002dc027a49b7fa6595532
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime
new file mode 100644
index 0000000000..f4fd088db5
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lwip/runtime
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+ child "test-libc_connect" exited with exit value 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/README b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/README
new file mode 100644
index 0000000000..0f31ef230a
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/README
@@ -0,0 +1 @@
+Libc connect test using the lxip VFS plugin in a VFS server.
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/archives b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/archives
new file mode 100644
index 0000000000..77fda2b83c
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/archives
@@ -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
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash
new file mode 100644
index 0000000000..55eb055d73
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/hash
@@ -0,0 +1 @@
+2019-01-04-d 1d09162ce289af49e5561cfa4a946ce66d7e3013
diff --git a/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime
new file mode 100644
index 0000000000..5827a3b988
--- /dev/null
+++ b/repos/libports/recipes/pkg/test-libc_connect_vfs_server_lxip/runtime
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+ child "test-libc_connect" exited with exit value 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/repos/libports/recipes/src/test-libc_connect/content.mk b/repos/libports/recipes/src/test-libc_connect/content.mk
new file mode 100644
index 0000000000..664dc73bdc
--- /dev/null
+++ b/repos/libports/recipes/src/test-libc_connect/content.mk
@@ -0,0 +1,3 @@
+SRC_DIR = src/test/libc_connect
+
+include $(GENODE_DIR)/repos/base/recipes/src/content.inc
diff --git a/repos/libports/recipes/src/test-libc_connect/hash b/repos/libports/recipes/src/test-libc_connect/hash
new file mode 100644
index 0000000000..47ed2d6f7d
--- /dev/null
+++ b/repos/libports/recipes/src/test-libc_connect/hash
@@ -0,0 +1 @@
+2019-01-03 a4edcc467817e5dbfda56cd46c85af6a39a883ce
diff --git a/repos/libports/recipes/src/test-libc_connect/used_apis b/repos/libports/recipes/src/test-libc_connect/used_apis
new file mode 100644
index 0000000000..ce85f15de1
--- /dev/null
+++ b/repos/libports/recipes/src/test-libc_connect/used_apis
@@ -0,0 +1,3 @@
+base
+posix
+libc
diff --git a/repos/libports/recipes/src/test-netty/content.mk b/repos/libports/recipes/src/test-netty/content.mk
new file mode 100644
index 0000000000..612b854d72
--- /dev/null
+++ b/repos/libports/recipes/src/test-netty/content.mk
@@ -0,0 +1,3 @@
+SRC_DIR = src/test/netty
+
+include $(GENODE_DIR)/repos/base/recipes/src/content.inc
diff --git a/repos/libports/recipes/src/test-netty/hash b/repos/libports/recipes/src/test-netty/hash
new file mode 100644
index 0000000000..e4e3298864
--- /dev/null
+++ b/repos/libports/recipes/src/test-netty/hash
@@ -0,0 +1 @@
+2019-01-03-e e3582a89a5ad6632168209c3f50eced5546c0457
diff --git a/repos/libports/recipes/src/test-netty/used_apis b/repos/libports/recipes/src/test-netty/used_apis
new file mode 100644
index 0000000000..82f5b2f32d
--- /dev/null
+++ b/repos/libports/recipes/src/test-netty/used_apis
@@ -0,0 +1,5 @@
+base
+posix
+libc
+os
+timer_session
diff --git a/repos/libports/src/test/libc_connect/main.cc b/repos/libports/src/test/libc_connect/main.cc
new file mode 100644
index 0000000000..cff544faf6
--- /dev/null
+++ b/repos/libports/src/test/libc_connect/main.cc
@@ -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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+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(&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(&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(&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(&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(&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(&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;
+}
diff --git a/repos/libports/src/test/libc_connect/target.mk b/repos/libports/src/test/libc_connect/target.mk
new file mode 100644
index 0000000000..74d7cd1919
--- /dev/null
+++ b/repos/libports/src/test/libc_connect/target.mk
@@ -0,0 +1,5 @@
+TARGET = test-libc_connect
+SRC_CC = main.cc
+LIBS = base libc posix
+
+CC_CXX_WARN_STRICT =
diff --git a/repos/libports/src/test/netty/tcp/target.mk b/repos/libports/src/test/netty/tcp/target.mk
index 4fe2ddc45a..14113d8715 100644
--- a/repos/libports/src/test/netty/tcp/target.mk
+++ b/repos/libports/src/test/netty/tcp/target.mk
@@ -1,6 +1,6 @@
TARGET = test-netty_tcp
SRC_CC = main.cc netty.cc
-LIBS = libc
+LIBS = base libc
INC_DIR += $(PRG_DIR)/..
diff --git a/repos/libports/src/test/netty/udp/target.mk b/repos/libports/src/test/netty/udp/target.mk
index d08c866265..b36d570300 100644
--- a/repos/libports/src/test/netty/udp/target.mk
+++ b/repos/libports/src/test/netty/udp/target.mk
@@ -1,6 +1,6 @@
TARGET = test-netty_udp
SRC_CC = main.cc netty.cc
-LIBS = libc
+LIBS = base libc
INC_DIR += $(PRG_DIR)/..