mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-29 15:44:02 +00:00
test/lxip_raw: test using Genode socket C-API directly
The lxip_raw.run script will spawn a client/server scenario that tests Genode C-API calls. The scenario can be used standalone, meaning no actual network card is required. issue #5104
This commit is contained in:
parent
42d9640443
commit
27b1017fe9
84
repos/dde_linux/run/lxip_raw.run
Normal file
84
repos/dde_linux/run/lxip_raw.run
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
set build_components {
|
||||
lib/ld core init
|
||||
timer
|
||||
test/lxip_raw
|
||||
server/nic_router
|
||||
}
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
</provides>
|
||||
<config verbose_domain_state="yes" verbose_packets="no" verbose_packet_drop="yes">
|
||||
|
||||
<default-policy domain="default"/>
|
||||
<domain name="default" interface="10.0.2.1/24">
|
||||
|
||||
<dhcp-server ip_first="10.0.2.2" ip_last="10.0.2.2"/>
|
||||
<udp dst="0.0.0.0/0">
|
||||
<permit-any domain="default"/>
|
||||
</udp>
|
||||
<tcp dst="0.0.0.0/0">
|
||||
<permit-any domain="default"/>
|
||||
</tcp>
|
||||
|
||||
</domain>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="test-lxip_server" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config ld_verbose="yes" ip_addr="10.0.2.3" netmask="255.255.255.0" gateway="10.0.2.1" nameserver="8.8.8.8"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="test-lxip_client" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config ld_verbose="yes" server_ip="10.0.2.3" server_port="80"/>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_router"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
build_boot_image [build_artifacts]
|
||||
|
||||
append qemu_args " -nographic "
|
||||
|
||||
run_genode_until "test-lxip_server\] Success" 10
|
197
repos/dde_linux/src/test/lxip_raw/client/main.cc
Normal file
197
repos/dde_linux/src/test/lxip_raw/client/main.cc
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* \brief Genode socket-interface test client part
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-09-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023-2024 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 <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <net/ipv4.h>
|
||||
#include <util/endian.h>
|
||||
|
||||
#include <genode_c_api/socket_types.h>
|
||||
#include <genode_c_api/socket.h>
|
||||
|
||||
#include <data.h>
|
||||
|
||||
|
||||
namespace Test {
|
||||
struct Client;
|
||||
using namespace Net;
|
||||
}
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
#define ASSERT(string, cond) { if (!(cond)) {\
|
||||
log("[", ++counter, "] ", string, " [failed]"); \
|
||||
error("assertion failed at line ", __LINE__, ": ", #cond); \
|
||||
throw -1;\
|
||||
} else { log("[", ++counter, "] ", string, " [ok]"); } }
|
||||
|
||||
extern "C" void wait_for_continue(void);
|
||||
|
||||
|
||||
struct Test::Client
|
||||
{
|
||||
Env &env;
|
||||
|
||||
using Ipv4_string = String<16>;
|
||||
|
||||
Attached_rom_dataspace config { env, "config"};
|
||||
|
||||
uint16_t const port
|
||||
{ config.xml().attribute_value("server_port", (uint16_t)80) };
|
||||
|
||||
Ipv4_address ip_addr
|
||||
{ config.xml().attribute_value("server_ip", Ipv4_address()) };
|
||||
|
||||
unsigned long counter { 0 };
|
||||
|
||||
Data data { };
|
||||
char *recv_buf[Data::SIZE];
|
||||
|
||||
Client(Env &env) : env(env)
|
||||
{
|
||||
genode_socket_init(genode_env_ptr(env), nullptr);
|
||||
|
||||
genode_socket_config address_config = { .dhcp = true };
|
||||
genode_socket_config_address(&address_config);
|
||||
}
|
||||
|
||||
/* connect blocking version */
|
||||
bool connect(genode_socket_handle *handle, genode_sockaddr *addr)
|
||||
{
|
||||
enum Errno err;
|
||||
/* is non-blocking */
|
||||
err = genode_socket_connect(handle, addr);
|
||||
if (err == GENODE_ENONE) return true;
|
||||
if (err != GENODE_EINPROGRESS) return false;
|
||||
|
||||
/* proceed with protocol described in manpage */
|
||||
bool success = false;
|
||||
for (unsigned i = 0; i < 100; i++) {
|
||||
if(genode_socket_poll(handle) & genode_socket_pollout_set()) {
|
||||
success = true; break;
|
||||
}
|
||||
genode_socket_wait_for_progress();
|
||||
}
|
||||
|
||||
if (!success) return false;
|
||||
|
||||
enum Errno socket_err;
|
||||
unsigned size = sizeof(enum Errno);
|
||||
err = genode_socket_getsockopt(handle, GENODE_SOL_SOCKET, GENODE_SO_ERROR,
|
||||
&socket_err, &size);
|
||||
|
||||
if (err || socket_err) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
unsigned long receive(genode_socket_handle *handle, char *buf, unsigned long length)
|
||||
{
|
||||
Msg_header msg_recv { buf, length };
|
||||
unsigned long bytes = 0;
|
||||
Errno err;
|
||||
while (true) {
|
||||
err = genode_socket_recvmsg(handle, msg_recv.header(), &bytes, false);
|
||||
if (err == GENODE_EAGAIN)
|
||||
genode_socket_wait_for_progress();
|
||||
else break;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void run_tcp()
|
||||
{
|
||||
enum Errno err;
|
||||
genode_socket_handle *handle = nullptr;
|
||||
ASSERT("create new socket (TCP)...",
|
||||
(handle = genode_socket(AF_INET, SOCK_STREAM, 0, &err)) != nullptr);
|
||||
|
||||
genode_sockaddr addr;
|
||||
addr.family = AF_INET;
|
||||
addr.in.port = host_to_big_endian(port);
|
||||
addr.in.addr = ip_addr.to_uint32_big_endian();
|
||||
ASSERT("connect...", connect(handle, &addr) == true);
|
||||
|
||||
genode_sockaddr name;
|
||||
ASSERT("getsockname... ", genode_socket_getsockname(handle, &name) == GENODE_ENONE);
|
||||
|
||||
char expected_name[] = { 10, 0, 2, 2 };
|
||||
ASSERT("check expected sockname IP...",
|
||||
Ipv4_address::from_uint32_big_endian(name.in.addr) == Ipv4_address(expected_name));
|
||||
|
||||
ASSERT("getpeername... ", genode_socket_getpeername(handle, &name) == GENODE_ENONE);
|
||||
|
||||
char expected_peer[] = { 10, 0, 2, 3 };
|
||||
ASSERT("check expected peername IP...",
|
||||
Ipv4_address::from_uint32_big_endian(name.in.addr) == Ipv4_address(expected_peer));
|
||||
|
||||
/* send request */
|
||||
String<64> request { "GET / HTTP/1.0\r\nHost: localhost:80\r\n\r\n" };
|
||||
Msg_header msg { request.string(), request.length() };
|
||||
unsigned long bytes_send;
|
||||
ASSERT("send GET request...",
|
||||
genode_socket_sendmsg(handle, msg.header(), &bytes_send) == GENODE_ENONE
|
||||
&& bytes_send == request.length());
|
||||
|
||||
char buf[150];
|
||||
Http http {};
|
||||
|
||||
/* http header */
|
||||
ASSERT("receive HTTP header...", receive(handle, buf, 150) == http.header.length());
|
||||
ASSERT("check HTTP header...", !strcmp(http.header.string(), buf,http.header.length()));
|
||||
|
||||
/* html */
|
||||
ASSERT("receive HTML...", receive(handle, buf, 150) == http.html.length());
|
||||
ASSERT("check HTML...", !strcmp(http.html.string(), buf, http.html.length() == 0));
|
||||
|
||||
ASSERT("shutdown...", genode_socket_shutdown(handle, SHUT_RDWR) == GENODE_ENONE);
|
||||
ASSERT("release socket...", genode_socket_release(handle) == GENODE_ENONE);
|
||||
}
|
||||
|
||||
void run_udp()
|
||||
{
|
||||
enum Errno err;
|
||||
genode_socket_handle *handle = nullptr;
|
||||
ASSERT("create new socket (UDP)...",
|
||||
(handle = genode_socket(AF_INET, SOCK_DGRAM, 0, &err)) != nullptr);
|
||||
|
||||
genode_sockaddr addr;
|
||||
addr.family = AF_INET;
|
||||
addr.in.port = host_to_big_endian<genode_uint16_t>(port);
|
||||
addr.in.addr = ip_addr.to_uint32_big_endian();
|
||||
|
||||
for (unsigned i = 0; i < data.size(); i += MAX_UDP_LOAD) {
|
||||
Msg_header msg { addr, data.buffer() + i, MAX_UDP_LOAD};
|
||||
unsigned long bytes_send = 0;
|
||||
ASSERT("send bytes...",
|
||||
genode_socket_sendmsg(handle, msg.header(), &bytes_send) == GENODE_ENONE
|
||||
&& bytes_send == MAX_UDP_LOAD);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Test::Client client { env };
|
||||
|
||||
try {
|
||||
client.run_tcp();
|
||||
client.run_udp();
|
||||
log("Success");
|
||||
} catch (...) {
|
||||
log("Failure");
|
||||
}
|
||||
}
|
7
repos/dde_linux/src/test/lxip_raw/client/target.mk
Normal file
7
repos/dde_linux/src/test/lxip_raw/client/target.mk
Normal file
@ -0,0 +1,7 @@
|
||||
TARGET = test-lxip_client
|
||||
LIBS = lxip base net
|
||||
SRC_CC = main.cc
|
||||
|
||||
INC_DIR += $(PRG_DIR)/../include
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
75
repos/dde_linux/src/test/lxip_raw/include/data.h
Normal file
75
repos/dde_linux/src/test/lxip_raw/include/data.h
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* \brief Test data and helpers
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-09-21
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023-2024 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__DATA_H_
|
||||
#define _INCLUDE__DATA_H_
|
||||
|
||||
namespace Test {
|
||||
|
||||
enum { MAX_UDP_LOAD= 1472 };
|
||||
|
||||
struct Msg_header
|
||||
{
|
||||
genode_iovec iovec;
|
||||
genode_msghdr msg { };
|
||||
|
||||
Msg_header(void const *data, unsigned long size)
|
||||
: iovec { const_cast<void *>(data), size }
|
||||
{
|
||||
msg.iov = &iovec;
|
||||
msg.iovlen = 1;
|
||||
}
|
||||
|
||||
Msg_header(genode_sockaddr &name, void const *data, unsigned long size)
|
||||
: Msg_header(data, size)
|
||||
{
|
||||
msg.name = &name;
|
||||
}
|
||||
|
||||
genode_msghdr *header() { return &msg; }
|
||||
};
|
||||
|
||||
struct Data
|
||||
{
|
||||
enum { SIZE = MAX_UDP_LOAD * 10 };
|
||||
|
||||
char buf[SIZE];
|
||||
|
||||
Data()
|
||||
{
|
||||
char j = 'A';
|
||||
unsigned step = MAX_UDP_LOAD / 2;
|
||||
for (unsigned i = 0; i < size(); i += step, j += 1) {
|
||||
Genode::memset(buf + i, j, step);
|
||||
}
|
||||
}
|
||||
|
||||
char const *buffer() const { return buf; }
|
||||
unsigned long size() const { return SIZE; }
|
||||
};
|
||||
|
||||
struct Http
|
||||
{
|
||||
Genode::String<128> header
|
||||
{ "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" }; /* HTTP response header */
|
||||
|
||||
Genode::String<150> html
|
||||
{"<html><head><title>Congrats!</title></head><body>"
|
||||
"<h1>Welcome to our HTTP server!</h1>"
|
||||
"<p>This is a small test page.</body></html>"}; /* HTML page */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__DATA_H_ */
|
226
repos/dde_linux/src/test/lxip_raw/server/main.cc
Normal file
226
repos/dde_linux/src/test/lxip_raw/server/main.cc
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* \brief Genode socket-interface test server part
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-09-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023-2024 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 <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <net/ipv4.h>
|
||||
#include <util/endian.h>
|
||||
|
||||
#include <genode_c_api/socket_types.h>
|
||||
#include <genode_c_api/socket.h>
|
||||
|
||||
#include <data.h>
|
||||
|
||||
namespace Test {
|
||||
using namespace Net;
|
||||
struct Server;
|
||||
};
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
#define ASSERT(string, cond) { if (!(cond)) {\
|
||||
log("[", ++counter, "] ", string, " [failed]"); \
|
||||
error("assertion failed at line ", __LINE__, ": ", #cond); \
|
||||
throw -1;\
|
||||
} else { log("[", ++counter, "] ", string, " [ok]"); } }
|
||||
|
||||
|
||||
struct Test::Server
|
||||
{
|
||||
Env &env;
|
||||
|
||||
unsigned counter { 0 };
|
||||
|
||||
Attached_rom_dataspace config { env, "config" };
|
||||
|
||||
uint16_t const port { config.xml().attribute_value("port", (uint16_t)80) };
|
||||
|
||||
using Ipv4_string = String<16>;
|
||||
|
||||
Ipv4_string const ip {
|
||||
config.xml().attribute_value("ip_addr", Ipv4_string("0.0.0.0")) };
|
||||
Ipv4_string const netmask {
|
||||
config.xml().attribute_value("netmask", Ipv4_string("0.0.0.0")) };
|
||||
Ipv4_string const gateway {
|
||||
config.xml().attribute_value("gateway", Ipv4_string("0.0.0.0")) };
|
||||
Ipv4_string const nameserver {
|
||||
config.xml().attribute_value("nameserver", Ipv4_string("0.0.0.0")) };
|
||||
|
||||
Ipv4_address const ip_addr {
|
||||
config.xml().attribute_value("ip_addr", Ipv4_address()) };
|
||||
|
||||
Http http { };
|
||||
Data data { };
|
||||
|
||||
enum { SIZE = Data::SIZE };
|
||||
char buf[SIZE];
|
||||
|
||||
Server(Env &env) : env(env)
|
||||
{
|
||||
genode_socket_init(genode_env_ptr(env), nullptr);
|
||||
|
||||
genode_socket_config address_config = {
|
||||
.dhcp = false,
|
||||
.ip_addr = ip.string(),
|
||||
.netmask = netmask.string(),
|
||||
.gateway = gateway.string(),
|
||||
.nameserver = nameserver.string(),
|
||||
};
|
||||
|
||||
genode_socket_config_address(&address_config);
|
||||
}
|
||||
|
||||
void serve(genode_socket_handle *handle)
|
||||
{
|
||||
Constructible<Msg_header> msg;
|
||||
msg.construct(buf, SIZE);
|
||||
|
||||
/* Read the data from the port, blocking if nothing yet there.
|
||||
We assume the request (the part we care about) is in one packet */
|
||||
unsigned long bytes = 0;
|
||||
Errno err;
|
||||
while (true) {
|
||||
err = genode_socket_recvmsg(handle, msg->header(), &bytes, false);
|
||||
if (err == GENODE_EAGAIN)
|
||||
genode_socket_wait_for_progress();
|
||||
else break;
|
||||
}
|
||||
|
||||
ASSERT("recvmsg...", (bytes == 39 && err == GENODE_ENONE));
|
||||
|
||||
msg.destruct();
|
||||
|
||||
/* Is this an HTTP GET command? (only check the first 5 chars, since
|
||||
there are other formats for GET, and we're keeping it very simple)*/
|
||||
ASSERT("message is GET command...", !strcmp(buf, "GET /", 5));
|
||||
|
||||
/* send http header */
|
||||
msg.construct(http.header.string(), http.header.length());
|
||||
ASSERT("send HTTP header...",
|
||||
genode_socket_sendmsg(handle, msg->header(), &bytes) == GENODE_ENONE
|
||||
&& bytes == http.header.length());
|
||||
msg.destruct();
|
||||
|
||||
/* Send http header */
|
||||
msg.construct(http.html.string(), http.html.length());
|
||||
ASSERT("send HTML...",
|
||||
genode_socket_sendmsg(handle, msg->header(), &bytes) == GENODE_ENONE
|
||||
&& bytes == http.html.length());
|
||||
}
|
||||
|
||||
void run_tcp()
|
||||
{
|
||||
enum Errno err;
|
||||
genode_socket_handle *handle = nullptr;
|
||||
genode_socket_handle *handle_reuse = nullptr;
|
||||
ASSERT("create new socket (TCP)...",
|
||||
(handle = genode_socket(AF_INET, SOCK_STREAM, 0, &err)) != nullptr);
|
||||
|
||||
ASSERT("create new socket (TCP re-use port)...",
|
||||
(handle_reuse = genode_socket(AF_INET, SOCK_STREAM, 0, &err)) != nullptr);
|
||||
|
||||
int opt = 1;
|
||||
ASSERT("setsockopt REUSEPORT handle...",
|
||||
genode_socket_setsockopt(handle, GENODE_SOL_SOCKET, GENODE_SO_REUSEPORT,
|
||||
&opt, sizeof(opt)) == GENODE_ENONE);
|
||||
ASSERT("setsockopt REUSEPORT handle re-use...",
|
||||
genode_socket_setsockopt(handle_reuse, GENODE_SOL_SOCKET, GENODE_SO_REUSEPORT,
|
||||
&opt, sizeof(opt)) == GENODE_ENONE);
|
||||
|
||||
genode_sockaddr addr;
|
||||
addr.family = AF_INET;
|
||||
addr.in.port = host_to_big_endian(port);
|
||||
addr.in.addr = INADDR_ANY;
|
||||
ASSERT("bind socket...", genode_socket_bind(handle, &addr) == GENODE_ENONE);
|
||||
ASSERT("bind socket re-use...", genode_socket_bind(handle_reuse, &addr) == GENODE_ENONE);
|
||||
|
||||
ASSERT("listen...", genode_socket_listen(handle, 5) == GENODE_ENONE);
|
||||
|
||||
genode_socket_handle *client = nullptr;
|
||||
|
||||
err = GENODE_EAGAIN;
|
||||
for (unsigned i = 0; i < 100 && err == GENODE_EAGAIN; i++) {
|
||||
client = genode_socket_accept(handle, &addr, &err);
|
||||
|
||||
if (err == GENODE_EAGAIN)
|
||||
genode_socket_wait_for_progress();
|
||||
}
|
||||
|
||||
ASSERT("accept...", err == GENODE_ENONE && client != nullptr);
|
||||
|
||||
serve(client);
|
||||
|
||||
ASSERT("release socket...", genode_socket_release(handle) == GENODE_ENONE);
|
||||
}
|
||||
|
||||
void run_udp()
|
||||
{
|
||||
enum Errno err;
|
||||
genode_socket_handle *handle = nullptr;
|
||||
ASSERT("create new socket (UDP)...",
|
||||
(handle = genode_socket(AF_INET, SOCK_DGRAM, 0, &err)) != nullptr);
|
||||
|
||||
genode_sockaddr addr;
|
||||
addr.family = AF_INET;
|
||||
addr.in.port = host_to_big_endian<genode_uint16_t>(port);
|
||||
addr.in.addr = ip_addr.to_uint32_big_endian();
|
||||
ASSERT("bind socket...", genode_socket_bind(handle, &addr) == GENODE_ENONE);
|
||||
err = genode_socket_bind(handle, &addr);
|
||||
|
||||
unsigned long bytes_recv = 0;
|
||||
bool once = true;
|
||||
while (bytes_recv < SIZE) {
|
||||
unsigned long bytes = 0;
|
||||
genode_sockaddr recv_addr = { .family = AF_INET };
|
||||
Msg_header msg { recv_addr, buf + bytes_recv, SIZE - bytes_recv };
|
||||
|
||||
|
||||
err = genode_socket_recvmsg(handle, msg.header(), &bytes, false);
|
||||
|
||||
bytes_recv += bytes;
|
||||
|
||||
if (err == GENODE_EAGAIN) {
|
||||
genode_socket_wait_for_progress();
|
||||
} else if (err == GENODE_ENONE) {
|
||||
|
||||
if (once) {
|
||||
Ipv4_address sender_ip =
|
||||
Ipv4_address::from_uint32_big_endian(recv_addr.in.addr);
|
||||
|
||||
char expected[] = { 10, 0, 2, 2 };
|
||||
Ipv4_address expected_ip { expected };
|
||||
|
||||
ASSERT("check expected sender IP address...", expected_ip == sender_ip);
|
||||
once = false;
|
||||
}
|
||||
} else break;
|
||||
}
|
||||
ASSERT("receive bytes...", err == GENODE_ENONE);
|
||||
ASSERT("check bytes...", strcmp(data.buffer(), buf, SIZE) == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
static Test::Server server { env };
|
||||
|
||||
try {
|
||||
server.run_tcp();
|
||||
server.run_udp();
|
||||
log("Success");
|
||||
} catch (...) {
|
||||
log("Failure");
|
||||
}
|
||||
}
|
7
repos/dde_linux/src/test/lxip_raw/server/target.mk
Normal file
7
repos/dde_linux/src/test/lxip_raw/server/target.mk
Normal file
@ -0,0 +1,7 @@
|
||||
TARGET = test-lxip_server
|
||||
LIBS = lxip base net
|
||||
SRC_CC = main.cc
|
||||
|
||||
INC_DIR += $(PRG_DIR)/../include
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
Loading…
x
Reference in New Issue
Block a user