nic_router: use LwIP- instead of LxIP UDP-tests

Currently, LxIP peers need a lot of RAM (the simple test-client/server for the
nic_router test need at least 28 MB per component). As the nic_router test
previously used 6 instances of such components and a lot of other components,
it had issues with insufficient RAM on some platforms. By using two new
LwIP-based UDP tests instead, we save more than 100 MB.

Ref #2543
This commit is contained in:
Martin Stein
2017-10-18 15:29:26 +02:00
committed by Christian Helmuth
parent f6dd1f9b9c
commit 657fa16f8c
5 changed files with 186 additions and 15 deletions

View File

@ -0,0 +1,87 @@
/*
* \brief Simple UDP test client
* \author Martin Stein
* \date 2017-10-18
*/
/*
* 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.
*/
/* Genode includes */
#include <timer_session/connection.h>
#include <base/attached_rom_dataspace.h>
#include <libc/component.h>
#include <nic/packet_allocator.h>
#include <util/string.h>
/* libc includes */
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
using namespace Genode;
using Ipv4_addr_str = Genode::String<16>;
struct Socket_failed : Genode::Exception { };
struct Send_failed : Genode::Exception { };
struct Receive_failed : Genode::Exception { };
struct Read_server_port_attr_failed : Exception { };
struct Read_server_ip_attr_failed : Exception { };
void Libc::Component::construct(Libc::Env &env)
{
/* wait a while for the server to come up */
Timer::Connection timer(env);
timer.msleep(3000);
/* create socket */
int s = socket(AF_INET, SOCK_DGRAM, 0 );
if (s < 0) {
throw Socket_failed();
}
/* try to send and receive a message multiple times */
for (int j = 0; j != 5; ++j) {
timer.msleep(1000);
/* read server IP address and port */
Ipv4_addr_str serv_addr;
unsigned port = 0;
Attached_rom_dataspace config(env, "config");
Xml_node config_node = config.xml();
try { config_node.attribute("server_ip").value(&serv_addr); }
catch (...) {
throw Read_server_port_attr_failed();
}
try { config_node.attribute("server_port").value(&port); }
catch (...) {
throw Read_server_port_attr_failed();
}
/* create server socket address */
struct sockaddr_in addr;
socklen_t addr_sz = sizeof(addr);
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(serv_addr.string());
/* send test message */
enum { BUF_SZ = 1024 };
char buf[BUF_SZ];
::snprintf(buf, BUF_SZ, "UDP server at %s:%u", serv_addr.string(), port);
if (sendto(s, buf, BUF_SZ, 0, (struct sockaddr*)&addr, addr_sz) != BUF_SZ) {
throw Send_failed();
}
/* receive and print what has been received */
if (recvfrom(s, buf, BUF_SZ, 0, (struct sockaddr*)&addr, &addr_sz) != BUF_SZ) {
throw Receive_failed();
}
log("Received \"", String<64>(buf), " ...\"");
}
log("Test done");
}

View File

@ -0,0 +1,5 @@
TARGET = test-lwip-udp-client
LIBS = posix libc_lwip_nic_dhcp libc_lwip lwip
SRC_CC = main.cc
INC_DIR += $(REP_DIR)/src/lib/lwip/include

View File

@ -0,0 +1,80 @@
/*
* \brief Simple UDP test server
* \author Martin Stein
* \date 2017-10-18
*/
/*
* 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.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <libc/component.h>
#include <nic/packet_allocator.h>
#include <util/string.h>
/* libc includes */
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
using namespace Genode;
using Ipv4_addr_str = Genode::String<16>;
struct Socket_failed : Genode::Exception { };
struct Send_failed : Genode::Exception { };
struct Receive_failed : Genode::Exception { };
struct Bind_failed : Genode::Exception { };
struct Read_port_attr_failed : Genode::Exception { };
void Libc::Component::construct(Libc::Env & env)
{
/* create socket */
int s = socket(AF_INET, SOCK_DGRAM, 0 );
if (s < 0) {
throw Socket_failed();
}
/* read server port */
unsigned port = 0;
Attached_rom_dataspace config(env, "config");
Xml_node config_node = config.xml();
try { config_node.attribute("port").value(&port); }
catch (...) {
throw Read_port_attr_failed();
}
/* create server socket address */
struct sockaddr_in in_addr;
in_addr.sin_family = AF_INET;
in_addr.sin_port = htons(port);
in_addr.sin_addr.s_addr = INADDR_ANY;
/* bind server socket address to socket */
if (bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
throw Bind_failed();
}
/* prepare client socket address */
struct sockaddr_in addr;
addr.sin_family = AF_INET;
socklen_t addr_sz = sizeof(addr);
while (true) {
/* receive and send back one message without any modifications */
char buf[4096];
::memset(buf, 0, sizeof(buf));
ssize_t rcv_sz = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addr_sz);
if (rcv_sz < 0) {
throw Receive_failed();
}
if (sendto(s, buf, rcv_sz, 0, (struct sockaddr*)&addr, addr_sz) != rcv_sz) {
throw Send_failed();
}
}
}

View File

@ -0,0 +1,5 @@
TARGET = test-lwip-udp-server
LIBS = posix libc_lwip_nic_dhcp libc_lwip lwip
SRC_CC = main.cc
INC_DIR += $(REP_DIR)/src/lib/lwip/include