mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-02 20:16:48 +00:00
parent
d9a4773194
commit
9b31aac1de
@ -1,2 +1,2 @@
|
|||||||
source ${genode_dir}/repos/ports/run/vfs_lxip.inc
|
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||||
source ${genode_dir}/repos/libports/run/fetchurl.inc
|
source ${genode_dir}/repos/libports/run/fetchurl.inc
|
||||||
|
@ -37,6 +37,7 @@ set build_components {
|
|||||||
core init
|
core init
|
||||||
drivers/timer drivers/nic
|
drivers/timer drivers/nic
|
||||||
test/lwip/http_srv
|
test/lwip/http_srv
|
||||||
|
lib/vfs/lwip
|
||||||
}
|
}
|
||||||
|
|
||||||
lappend_if $use_usb_driver build_components drivers/usb
|
lappend_if $use_usb_driver build_components drivers/usb
|
||||||
@ -78,10 +79,13 @@ set config {
|
|||||||
<provides> <service name="Timer"/> </provides>
|
<provides> <service name="Timer"/> </provides>
|
||||||
</start>
|
</start>
|
||||||
<start name="test-lwip_httpsrv" caps="120">
|
<start name="test-lwip_httpsrv" caps="120">
|
||||||
<resource name="RAM" quantum="5M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<config>
|
<config>
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
<dir name="dev"> <log/> </dir>
|
||||||
|
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
@ -125,7 +129,7 @@ install_config $config
|
|||||||
# generic modules
|
# generic modules
|
||||||
set boot_modules {
|
set boot_modules {
|
||||||
core init timer
|
core init timer
|
||||||
ld.lib.so libc.lib.so vfs.lib.so libm.lib.so lwip_legacy.lib.so test-lwip_httpsrv posix.lib.so
|
ld.lib.so libc.lib.so vfs.lib.so vfs_lwip.lib.so test-lwip_httpsrv
|
||||||
}
|
}
|
||||||
|
|
||||||
# platform-specific modules
|
# platform-specific modules
|
||||||
@ -149,12 +153,12 @@ append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
|
|||||||
|
|
||||||
append qemu_args " -net user -redir tcp:5555::80 "
|
append qemu_args " -net user -redir tcp:5555::80 "
|
||||||
|
|
||||||
run_genode_until {.*got IP address .*\n} 30
|
run_genode_until {.*lwIP Nic interface up.*\n} 30
|
||||||
|
|
||||||
if {[have_include "power_on/qemu"]} {
|
if {[have_include "power_on/qemu"]} {
|
||||||
set uri "http://localhost:5555/"
|
set uri "http://localhost:5555/"
|
||||||
} else {
|
} else {
|
||||||
set match_string "got IP address (.*)\033.*\n"
|
set match_string "lwIP Nic interface up address=.* netmask.*\n"
|
||||||
regexp $match_string $output ip_addr
|
regexp $match_string $output ip_addr
|
||||||
regexp {[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+} $ip_addr ip_addr
|
regexp {[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+} $ip_addr ip_addr
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ set build_components {
|
|||||||
core init
|
core init
|
||||||
drivers/timer drivers/nic
|
drivers/timer drivers/nic
|
||||||
server/nic_bridge
|
server/nic_bridge
|
||||||
test/lwip/http_srv_static
|
test/lwip/http_srv
|
||||||
test/lwip/http_clnt
|
test/lwip/http_clnt
|
||||||
|
lib/vfs/lwip
|
||||||
}
|
}
|
||||||
|
|
||||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||||
@ -60,24 +60,27 @@ append config {
|
|||||||
<resource name="RAM" quantum="24M"/>
|
<resource name="RAM" quantum="24M"/>
|
||||||
<provides><service name="Nic"/></provides>
|
<provides><service name="Nic"/></provides>
|
||||||
<config verbose="yes">
|
<config verbose="yes">
|
||||||
<policy label_prefix="test-lwip_httpsrv_static" ip_addr="10.0.2.55"/>
|
<policy label_prefix="test-lwip_httpsrv" ip_addr="10.0.2.55"/>
|
||||||
</config>
|
</config>
|
||||||
<route>
|
<route>
|
||||||
<service name="Nic"> <child name="nic_drv"/> </service>
|
<service name="Nic"> <child name="nic_drv"/> </service>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</route>
|
</route>
|
||||||
</start>
|
</start>
|
||||||
<start name="test-lwip_httpsrv_static">
|
<start name="test-lwip_httpsrv">
|
||||||
<resource name="RAM" quantum="32M"/>
|
<resource name="RAM" quantum="32M"/>
|
||||||
<route>
|
<route>
|
||||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</route>
|
</route>
|
||||||
<config port="80">
|
<config port="80">
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log" stderr="/dev/log"
|
<dir name="socket">
|
||||||
ip_addr="10.0.2.55" netmask="255.255.255.0"
|
<lwip ip_addr="10.0.2.55" netmask="255.255.255.0" gateway="10.0.2.1"/>
|
||||||
gateway="10.0.2.1"/>
|
</dir>
|
||||||
|
<dir name="dev"> <log/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
<start name="test-http_clnt" caps="120">
|
<start name="test-http_clnt" caps="120">
|
||||||
@ -87,8 +90,11 @@ append config {
|
|||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</route>
|
</route>
|
||||||
<config server_ip="10.0.2.55" server_port="80">
|
<config server_ip="10.0.2.55" server_port="80">
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||||
|
<dir name="dev"> <log/> </dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||||
</config>
|
</config>
|
||||||
</start>
|
</start>
|
||||||
</config>}
|
</config>}
|
||||||
@ -106,9 +112,9 @@ append boot_modules {
|
|||||||
nic_bridge
|
nic_bridge
|
||||||
ld.lib.so
|
ld.lib.so
|
||||||
libc.lib.so vfs.lib.so
|
libc.lib.so vfs.lib.so
|
||||||
lwip_legacy.lib.so
|
|
||||||
test-http_clnt
|
test-http_clnt
|
||||||
test-lwip_httpsrv_static
|
test-lwip_httpsrv
|
||||||
|
vfs_lwip.lib.so
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||||
|
|
||||||
set targets "core init drivers/timer server/nic_router server/nic_bridge
|
set targets "core init drivers/timer server/nic_router server/nic_bridge
|
||||||
test/lwip/http_srv_static test/lwip/http_clnt test/lwip/udp
|
test/lwip/http_srv test/lwip/http_clnt test/lwip/udp
|
||||||
server/nic_loopback [platform_drv_build_components]"
|
server/nic_loopback lib/vfs/lwip [platform_drv_build_components]"
|
||||||
|
|
||||||
proc client_bin { prot } {
|
proc client_bin { prot } {
|
||||||
if {$prot == "udp"} { return "test-lwip-udp-client" }
|
if {$prot == "udp"} { return "test-lwip-udp-client" }
|
||||||
@ -11,31 +11,35 @@ proc client_bin { prot } {
|
|||||||
|
|
||||||
proc server_bin { prot } {
|
proc server_bin { prot } {
|
||||||
if {$prot == "udp"} { return "test-lwip-udp-server" }
|
if {$prot == "udp"} { return "test-lwip-udp-server" }
|
||||||
if {$prot == "http"} { return "test-lwip_httpsrv_static" } }
|
if {$prot == "http"} { return "test-lwip_httpsrv" } }
|
||||||
|
|
||||||
proc client_config { name prot ip_addr gateway netmask nic srv_port srv_ip } {
|
proc client_config { name prot ip_addr gateway netmask nic srv_port srv_ip } {
|
||||||
global nr_of_clients
|
global nr_of_clients
|
||||||
incr nr_of_clients
|
incr nr_of_clients
|
||||||
append result {
|
append result {
|
||||||
<start name="} $name {" caps="200" priority="-1">
|
<start name="} $name {" priority="-1">
|
||||||
<binary name="} [client_bin $prot] {" />
|
<binary name="} [client_bin $prot] {" />
|
||||||
<resource name="RAM" quantum="10M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<route>
|
<route>
|
||||||
<service name="Nic"> <child name="} $nic {"/> </service>
|
<service name="Nic"> <child name="} $nic {"/> </service>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</route>
|
</route>
|
||||||
<config server_ip="} $srv_ip {" server_port="} $srv_port {">
|
<config server_ip="} $srv_ip {" server_port="} $srv_port {">
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"/>
|
||||||
|
<vfs>
|
||||||
|
<dir name="dev"> <log/> </dir>
|
||||||
|
<dir name="socket">
|
||||||
}
|
}
|
||||||
if {$ip_addr == "dhcp"} {
|
if {$ip_addr == "dhcp"} {
|
||||||
append result {
|
append result {
|
||||||
<libc stdout="/dev/log" stderr="/dev/log"/>}
|
<lwip dhcp="yes"/>}
|
||||||
} else {
|
} else {
|
||||||
append result {
|
append result {
|
||||||
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="} $ip_addr {"
|
<lwip ip_addr="} $ip_addr {" gateway="} $gateway {" netmask="} $netmask {"/>}
|
||||||
gateway="} $gateway {" netmask="} $netmask {"/>}
|
|
||||||
}
|
}
|
||||||
append result {
|
append result {
|
||||||
|
</dir>
|
||||||
|
</vfs>
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
return $result
|
return $result
|
||||||
@ -43,17 +47,22 @@ proc client_config { name prot ip_addr gateway netmask nic srv_port srv_ip } {
|
|||||||
|
|
||||||
proc server_config { name prot ip_addr gateway netmask nic port } {
|
proc server_config { name prot ip_addr gateway netmask nic port } {
|
||||||
append result {
|
append result {
|
||||||
<start name="} $name {" caps="200" priority="-1">
|
<start name="} $name {" priority="-1">
|
||||||
<binary name="} [server_bin $prot] {" />
|
<binary name="} [server_bin $prot] {" />
|
||||||
<resource name="RAM" quantum="10M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<route>
|
<route>
|
||||||
<service name="Nic"> <child name="} $nic {"/> </service>
|
<service name="Nic"> <child name="} $nic {"/> </service>
|
||||||
<any-service> <parent/> <any-child/> </any-service>
|
<any-service> <parent/> <any-child/> </any-service>
|
||||||
</route>
|
</route>
|
||||||
<config port="} $port {">
|
<config port="} $port {">
|
||||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
<vfs>
|
||||||
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="} $ip_addr {"
|
<dir name="dev"> <log/> </dir>
|
||||||
gateway="} $gateway {" netmask="} $netmask {"/>
|
<dir name="socket">
|
||||||
|
<lwip ip_addr="} $ip_addr {" gateway="} $gateway {" netmask="} $netmask {"/>
|
||||||
|
</dir>
|
||||||
|
</vfs>
|
||||||
|
<libc stdout="/dev/log" stderr="/dev/log" socket="/socket"
|
||||||
|
ip_addr="} $ip_addr {" gateway="} $gateway {" netmask="} $netmask {"/>
|
||||||
</config>
|
</config>
|
||||||
</start>}
|
</start>}
|
||||||
return $result
|
return $result
|
||||||
@ -61,7 +70,7 @@ proc server_config { name prot ip_addr gateway netmask nic port } {
|
|||||||
|
|
||||||
set boot_modules "
|
set boot_modules "
|
||||||
core init timer nic_router nic_bridge nic_loopback ld.lib.so
|
core init timer nic_router nic_bridge nic_loopback ld.lib.so
|
||||||
libc.lib.so vfs.lib.so lwip_legacy.lib.so [client_bin udp] [server_bin udp]
|
libc.lib.so vfs.lib.so vfs_lwip.lib.so [client_bin udp] [server_bin udp]
|
||||||
[client_bin http] [server_bin http] [platform_drv_boot_modules]"
|
[client_bin http] [server_bin http] [platform_drv_boot_modules]"
|
||||||
|
|
||||||
append qemu_args "-nographic "
|
append qemu_args "-nographic "
|
||||||
|
@ -8,7 +8,7 @@ proc enable_test_3 { } { return 1 }
|
|||||||
proc enable_test_4 { } { return 1 }
|
proc enable_test_4 { } { return 1 }
|
||||||
proc enable_test_5 { } { return 1 }
|
proc enable_test_5 { } { return 1 }
|
||||||
proc enable_test_6 { } { return 1 }
|
proc enable_test_6 { } { return 1 }
|
||||||
proc enable_test_7 { } { return 0 }
|
proc enable_test_7 { } { return 1 }
|
||||||
|
|
||||||
source ${genode_dir}/repos/libports/run/nic_router.inc
|
source ${genode_dir}/repos/libports/run/nic_router.inc
|
||||||
|
|
||||||
@ -364,4 +364,4 @@ for {set i 0} {$i < $nr_of_clients} {incr i 1} {
|
|||||||
append done_string {.*Test done.*\n}
|
append done_string {.*Test done.*\n}
|
||||||
}
|
}
|
||||||
|
|
||||||
run_genode_until $done_string 240
|
run_genode_until $done_string 60
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* \brief HTTP client test
|
* \brief HTTP client test
|
||||||
* \author Ivan Loskutov
|
* \author Ivan Loskutov
|
||||||
|
* \author Martin Stein
|
||||||
* \date 2012-12-21
|
* \date 2012-12-21
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -20,117 +21,117 @@
|
|||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
|
||||||
extern "C" {
|
/* Libc includes */
|
||||||
#include <lwip/sockets.h>
|
#include <stdio.h>
|
||||||
#include <lwip/api.h>
|
#include <errno.h>
|
||||||
#include <netif/etharp.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
void close_socket(Libc::Env &env, int sd)
|
||||||
|
{
|
||||||
|
if (::shutdown(sd, SHUT_RDWR)) {
|
||||||
|
error("failed to shutdown");
|
||||||
|
env.parent().exit(-1);
|
||||||
|
}
|
||||||
|
if (::close(sd)) {
|
||||||
|
error("failed to close");
|
||||||
|
env.parent().exit(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
|
|
||||||
|
static void test(Libc::Env &env)
|
||||||
/**
|
|
||||||
* The client simply loops endless,
|
|
||||||
* and sends as much 'http get' requests as possible,
|
|
||||||
* printing out the response.
|
|
||||||
*/
|
|
||||||
void Libc::Component::construct(Libc::Env &env)
|
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using Ipv4_string = String<16>;
|
||||||
using Address = Genode::String<16>;
|
enum { NR_OF_REPLIES = 5 };
|
||||||
|
enum { NR_OF_TRIALS = 15 };
|
||||||
|
|
||||||
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
|
/* read component configuration */
|
||||||
|
Attached_rom_dataspace config_rom { env, "config" };
|
||||||
|
Xml_node config_node { config_rom.xml() };
|
||||||
|
Ipv4_string const srv_ip { config_node.attribute_value("server_ip", Ipv4_string("0.0.0.0")) };
|
||||||
|
uint16_t const srv_port { config_node.attribute_value("server_port", (uint16_t)0) };
|
||||||
|
|
||||||
static Timer::Connection _timer(env);
|
/* construct server socket address */
|
||||||
_timer.msleep(2000);
|
struct sockaddr_in srv_addr;
|
||||||
lwip_tcpip_init();
|
srv_addr.sin_port = htons(srv_port);
|
||||||
|
srv_addr.sin_family = AF_INET;
|
||||||
|
srv_addr.sin_addr.s_addr = inet_addr(srv_ip.string());
|
||||||
|
|
||||||
uint32_t ip = 0, nm = 0, gw = 0;
|
/* try several times to request a reply */
|
||||||
Address serv_addr, ip_addr, netmask, gateway;
|
for (unsigned trial_cnt = 0, reply_cnt = 0; trial_cnt < NR_OF_TRIALS;
|
||||||
|
trial_cnt++)
|
||||||
Attached_rom_dataspace config(env, "config");
|
|
||||||
Xml_node config_node = config.xml();
|
|
||||||
Xml_node libc_node = env.libc_config();
|
|
||||||
try {
|
|
||||||
libc_node.attribute("ip_addr").value(&ip_addr);
|
|
||||||
libc_node.attribute("netmask").value(&netmask);
|
|
||||||
libc_node.attribute("gateway").value(&gateway);
|
|
||||||
ip = inet_addr(ip_addr.string());
|
|
||||||
nm = inet_addr(netmask.string());
|
|
||||||
gw = inet_addr(gateway.string());
|
|
||||||
} catch (...) {}
|
|
||||||
config_node.attribute("server_ip").value(&serv_addr);
|
|
||||||
|
|
||||||
if (lwip_nic_init(ip, nm, gw, BUF_SIZE, BUF_SIZE)) {
|
|
||||||
error("We got no IP address!");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned trial_cnt = 0, success_cnt = 0; trial_cnt < 10; trial_cnt++)
|
|
||||||
{
|
{
|
||||||
_timer.msleep(2000);
|
/* pause a while between each trial */
|
||||||
|
usleep(1000000);
|
||||||
|
|
||||||
log("Create new socket ...");
|
/* create socket */
|
||||||
int s = lwip_socket(AF_INET, SOCK_STREAM, 0 );
|
int sd = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (s < 0) {
|
if (sd < 0) {
|
||||||
error("no socket available!");
|
error("failed to create socket");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* connect to server */
|
||||||
log("Connect to server ...");
|
if (::connect(sd, (struct sockaddr *)&srv_addr, sizeof(srv_addr))) {
|
||||||
|
error("Failed to connect to server");
|
||||||
unsigned port = 0;
|
close_socket(env, sd);
|
||||||
try { config_node.attribute("server_port").value(&port); }
|
|
||||||
catch (...) {
|
|
||||||
error("Missing \"server_port\" attribute.");
|
|
||||||
throw Xml_node::Nonexistent_attribute();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
addr.sin_port = htons(port);
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_addr.s_addr = inet_addr(serv_addr.string());
|
|
||||||
|
|
||||||
if((lwip_connect(s, (struct sockaddr *)&addr, sizeof(addr))) < 0) {
|
|
||||||
error("Could not connect!");
|
|
||||||
lwip_close(s);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* send request */
|
||||||
log("Send request...");
|
char const *req = "GET / HTTP/1.0\r\nHost: localhost:80\r\n\r\n";
|
||||||
|
size_t const req_sz = Genode::strlen(req);
|
||||||
/* simple HTTP request header */
|
if (::send(sd, req, req_sz, 0) != (int)req_sz) {
|
||||||
static const char *http_get_request =
|
error("failed to send request");
|
||||||
"GET / HTTP/1.0\r\nHost: localhost:80\r\n\r\n";
|
close_socket(env, sd);
|
||||||
|
|
||||||
unsigned long bytes = lwip_send(s, (char*)http_get_request,
|
|
||||||
Genode::strlen(http_get_request), 0);
|
|
||||||
if ( bytes < 0 ) {
|
|
||||||
error("couldn't send request ...");
|
|
||||||
lwip_close(s);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* receive reply */
|
||||||
/* Receive http header and content independently in 2 packets */
|
enum { REPLY_BUF_SZ = 1024 };
|
||||||
for(int i=0; i<2; i++) {
|
char reply_buf[REPLY_BUF_SZ];
|
||||||
char buf[1024];
|
size_t reply_sz = 0;
|
||||||
ssize_t buflen;
|
bool reply_failed = false;
|
||||||
buflen = lwip_recv(s, buf, 1024, 0);
|
char const *reply_end = "</html>";
|
||||||
if(buflen > 0) {
|
size_t const reply_end_sz = Genode::strlen(reply_end);
|
||||||
buf[buflen] = 0;
|
for (; reply_sz <= REPLY_BUF_SZ; ) {
|
||||||
log("Received \"", String<64>(buf), " ...\"");
|
char *rcv_buf = &reply_buf[reply_sz];
|
||||||
;
|
size_t const rcv_buf_sz = REPLY_BUF_SZ - reply_sz;
|
||||||
if (++success_cnt >= 5) {
|
signed long rcv_sz = ::recv(sd, rcv_buf, rcv_buf_sz, 0);
|
||||||
log("Test done");
|
if (rcv_sz < 0) {
|
||||||
env.parent().exit(0);
|
reply_failed = true;
|
||||||
}
|
|
||||||
} else
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
reply_sz += rcv_sz;
|
||||||
|
if (reply_sz >= reply_end_sz) {
|
||||||
|
if (!strcmp(&reply_buf[reply_sz - reply_end_sz], reply_end, reply_end_sz)) {
|
||||||
|
break; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* ignore failed replies */
|
||||||
/* Close socket */
|
if (reply_failed) {
|
||||||
lwip_close(s);
|
error("failed to receive reply");
|
||||||
|
close_socket(env, sd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* handle reply */
|
||||||
|
reply_buf[reply_sz] = 0;
|
||||||
|
log("Received \"", Cstring(reply_buf), "\"");
|
||||||
|
if (++reply_cnt == NR_OF_REPLIES) {
|
||||||
|
log("Test done");
|
||||||
|
env.parent().exit(0);
|
||||||
|
}
|
||||||
|
/* close socket and retry */
|
||||||
|
close_socket(env, sd);
|
||||||
}
|
}
|
||||||
log("Test failed");
|
log("Test failed");
|
||||||
env.parent().exit(-1);
|
env.parent().exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env) { with_libc([&] () { test(env); }); }
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
TARGET = test-http_clnt
|
TARGET = test-http_clnt
|
||||||
LIBS = lwip_legacy libc
|
LIBS = libc
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/lib/lwip/include
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* \brief Minimal HTTP server lwIP demonstration
|
* \brief Minimal HTTP server lwIP demonstration
|
||||||
* \author lwIP Team
|
* \author lwIP Team
|
||||||
* \author Stefan Kalkowski
|
* \author Stefan Kalkowski
|
||||||
|
* \author Martin Stein
|
||||||
* \date 2009-10-23
|
* \date 2009-10-23
|
||||||
*
|
*
|
||||||
* This small example shows how to use the LwIP in Genode directly.
|
* This small example shows how to use the LwIP in Genode directly.
|
||||||
@ -18,19 +19,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/thread.h>
|
#include <libc/component.h>
|
||||||
#include <util/string.h>
|
|
||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
|
#include <util/string.h>
|
||||||
|
|
||||||
/* LwIP includes */
|
/* Libc includes */
|
||||||
extern "C" {
|
#include <stdio.h>
|
||||||
#include <lwip/sockets.h>
|
#include <errno.h>
|
||||||
#include <lwip/api.h>
|
#include <stdlib.h>
|
||||||
}
|
#include <string.h>
|
||||||
|
|
||||||
#include <lwip_legacy/genode.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
const static char http_html_hdr[] =
|
const static char http_html_hdr[] =
|
||||||
"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */
|
"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */
|
||||||
@ -44,13 +51,14 @@ const static char http_index_html[] =
|
|||||||
*
|
*
|
||||||
* \param conn socket connected to the client
|
* \param conn socket connected to the client
|
||||||
*/
|
*/
|
||||||
void http_server_serve(int conn) {
|
void http_server_serve(int conn)
|
||||||
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
ssize_t buflen;
|
ssize_t buflen;
|
||||||
|
|
||||||
/* Read the data from the port, blocking if nothing yet there.
|
/* Read the data from the port, blocking if nothing yet there.
|
||||||
We assume the request (the part we care about) is in one packet */
|
We assume the request (the part we care about) is in one packet */
|
||||||
buflen = lwip_recv(conn, buf, 1024, 0);
|
buflen = recv(conn, buf, 1024, 0);
|
||||||
Genode::log("Packet received!");
|
Genode::log("Packet received!");
|
||||||
|
|
||||||
/* Ignore all receive errors */
|
/* Ignore all receive errors */
|
||||||
@ -68,62 +76,57 @@ void http_server_serve(int conn) {
|
|||||||
Genode::log("Will send response");
|
Genode::log("Will send response");
|
||||||
|
|
||||||
/* Send http header */
|
/* Send http header */
|
||||||
lwip_send(conn, http_html_hdr, Genode::strlen(http_html_hdr), 0);
|
send(conn, http_html_hdr, Genode::strlen(http_html_hdr), 0);
|
||||||
|
|
||||||
/* Send our HTML page */
|
/* Send our HTML page */
|
||||||
lwip_send(conn, http_index_html, Genode::strlen(http_index_html), 0);
|
send(conn, http_index_html, Genode::strlen(http_index_html), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
static void test(Libc::Env &env)
|
||||||
{
|
{
|
||||||
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
|
Attached_rom_dataspace config(env, "config");
|
||||||
|
uint16_t const port = config.xml().attribute_value("port", (uint16_t)80);
|
||||||
int s;
|
|
||||||
|
|
||||||
lwip_tcpip_init();
|
|
||||||
|
|
||||||
/* Initialize network stack and do DHCP */
|
|
||||||
if (lwip_nic_init(0, 0, 0, BUF_SIZE, BUF_SIZE)) {
|
|
||||||
Genode::error("got no IP address!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::log("Create new socket ...");
|
Genode::log("Create new socket ...");
|
||||||
if((s = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
int s;
|
||||||
Genode::error("no socket available!");
|
if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||||
return -1;
|
error("no socket available!");
|
||||||
|
env.parent().exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::log("Now, I will bind ...");
|
Genode::log("Now, I will bind ...");
|
||||||
struct sockaddr_in in_addr;
|
struct sockaddr_in in_addr;
|
||||||
in_addr.sin_family = AF_INET;
|
in_addr.sin_family = AF_INET;
|
||||||
in_addr.sin_port = htons(80);
|
in_addr.sin_port = htons(port);
|
||||||
in_addr.sin_addr.s_addr = INADDR_ANY;
|
in_addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
if(lwip_bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
|
if (bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
|
||||||
Genode::error("bind failed!");
|
Genode::error("bind failed!");
|
||||||
return -1;
|
env.parent().exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::log("Now, I will listen ...");
|
Genode::log("Now, I will listen ...");
|
||||||
if(lwip_listen(s, 5)) {
|
if (listen(s, 5)) {
|
||||||
Genode::error("listen failed!");
|
Genode::error("listen failed!");
|
||||||
return -1;
|
env.parent().exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::log("Start the server loop ...");
|
Genode::log("Start the server loop ...");
|
||||||
while(true) {
|
while (true) {
|
||||||
struct sockaddr addr;
|
struct sockaddr addr;
|
||||||
socklen_t len = sizeof(addr);
|
socklen_t len = sizeof(addr);
|
||||||
int client = lwip_accept(s, &addr, &len);
|
int client = accept(s, &addr, &len);
|
||||||
if(client < 0) {
|
if(client < 0) {
|
||||||
Genode::warning("invalid socket from accept!");
|
Genode::warning("invalid socket from accept!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
http_server_serve(client);
|
http_server_serve(client);
|
||||||
lwip_close(client);
|
close(client);
|
||||||
}
|
}
|
||||||
return 0;
|
env.parent().exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env) { with_libc([&] () { test(env); }); }
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
TARGET = test-lwip_httpsrv
|
TARGET = test-lwip_httpsrv
|
||||||
LIBS = lwip_legacy posix
|
LIBS = libc
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/lib/lwip/include
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
TARGET = httpsrv_connect
|
|
||||||
SRC = main.c net.c
|
|
||||||
|
|
||||||
CFLAGS = -Wall -Wextra -Wno-unused
|
|
||||||
ifeq ($(time),1)
|
|
||||||
CC_DEF += -DUGLY_MEASURE_TIME
|
|
||||||
endif
|
|
||||||
LDFLAGS = -pthread
|
|
||||||
|
|
||||||
OBJS = $(SRC:.c=.o)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
$(TARGET): $(OBJS)
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
$(CC) -c $(CFLAGS) $(CC_DEF) $^ -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf ./$(TARGET) ./*.o
|
|
@ -1,2 +0,0 @@
|
|||||||
This is just a simple test client for http_srv, that runs on the host
|
|
||||||
system. Therefore it does not use the Genode buildsystem.
|
|
@ -1,197 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Simple http_srv client
|
|
||||||
* \author Josef Soentgen
|
|
||||||
* \date 2012-8-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* prototypes for net.c functions */
|
|
||||||
extern int dial(struct addrinfo*);
|
|
||||||
extern struct addrinfo *lookup(const char*, const char*, const char*);
|
|
||||||
|
|
||||||
/* pthread error handling */
|
|
||||||
#define handle_error_en(en, msg) \
|
|
||||||
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
|
|
||||||
|
|
||||||
/* send request, currently hardcoded and works with httpsrv test only */
|
|
||||||
const char req[] = "GET /";
|
|
||||||
|
|
||||||
/* thread arguments */
|
|
||||||
struct args {
|
|
||||||
struct addrinfo* ai;
|
|
||||||
int flags;
|
|
||||||
int count;
|
|
||||||
int verbose;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* receive flag */
|
|
||||||
enum { F_NONE, F_RECV };
|
|
||||||
|
|
||||||
/* pthread start function */
|
|
||||||
void *
|
|
||||||
run(void *arg)
|
|
||||||
{
|
|
||||||
char buf[1 << 20]; /* 1 MiB should be enough */
|
|
||||||
struct args *ap = (struct args *) arg;
|
|
||||||
int count = ap->count;
|
|
||||||
int flags = ap->flags;
|
|
||||||
int verbose = ap->verbose;
|
|
||||||
int i, s, nbytes, sum_nbytes;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
s = dial(ap->ai); /* create socket and connect */
|
|
||||||
if (s == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* only send/receive if flag is set { */
|
|
||||||
if (flags & F_RECV) {
|
|
||||||
/* first send request and second get header */
|
|
||||||
write(s, req, sizeof(req));
|
|
||||||
nbytes = read(s, buf, sizeof (buf));
|
|
||||||
|
|
||||||
/* get data */
|
|
||||||
sum_nbytes = 0;
|
|
||||||
#if UGLY_MEASURE_TIME
|
|
||||||
struct timeval start, end;
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
#endif
|
|
||||||
do {
|
|
||||||
/**
|
|
||||||
* override buffer because we don't care about
|
|
||||||
* the actual data.
|
|
||||||
*/
|
|
||||||
nbytes = read(s, buf, sizeof (buf));
|
|
||||||
sum_nbytes += nbytes;
|
|
||||||
|
|
||||||
} while (nbytes > 0 && nbytes != -1);
|
|
||||||
|
|
||||||
if (nbytes == -1)
|
|
||||||
perror("read");
|
|
||||||
|
|
||||||
#if UGLY_MEASURE_TIME
|
|
||||||
gettimeofday(&end, NULL);
|
|
||||||
int sec = end.tv_sec - start.tv_sec;
|
|
||||||
int usec = end.tv_usec - start.tv_usec;
|
|
||||||
if (usec < 0) {
|
|
||||||
usec += 1000000;
|
|
||||||
sec--;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("time: %d ms\n",
|
|
||||||
((sec) * 1000) + ((usec) / 1000));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
printf("bytes read: %d\n", sum_nbytes);
|
|
||||||
}
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
close(s);
|
|
||||||
}
|
|
||||||
/* XXX s == -1 handling */
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
struct args a;
|
|
||||||
struct addrinfo *ai;
|
|
||||||
const char *proto = "tcp", *host, *port;
|
|
||||||
int i, err, verbose = 0, flags = F_NONE, count = 1, threads = 1;
|
|
||||||
pthread_t *thread;
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
fprintf(stderr, "usage: %s [-vr] [-c count] [-t threads] "
|
|
||||||
"[-p protocol] <host> <port>\n", argv[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* argument parsing { */
|
|
||||||
while ((i = getopt(argc, argv, "c:p:t:rv")) != -1) {
|
|
||||||
switch (i) {
|
|
||||||
case 'c': count = atoi(optarg); break;
|
|
||||||
/**
|
|
||||||
* valid values are only 'tcp' and 'udp'
|
|
||||||
*/
|
|
||||||
case 'p': proto = optarg; break;
|
|
||||||
case 't': threads = atoi(optarg); break;
|
|
||||||
/**
|
|
||||||
* If receive is specified we will read from the socket,
|
|
||||||
* just connect to the host otherwise.
|
|
||||||
*/
|
|
||||||
case 'r': flags |= F_RECV; break;
|
|
||||||
case 'v': verbose = 1; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((argc - optind) != 2) {
|
|
||||||
fprintf(stderr, "missing host and/or port\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
host = argv[optind++];
|
|
||||||
port = argv[optind];
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* main { */
|
|
||||||
thread = (pthread_t *) calloc(threads, sizeof (pthread_t));
|
|
||||||
if (thread == NULL) {
|
|
||||||
perror("calloc");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get addrinfo once and use it for all threads */
|
|
||||||
ai = lookup(proto, host, port);
|
|
||||||
if (ai == NULL) {
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill thread argument structure */
|
|
||||||
a.ai = ai;
|
|
||||||
a.count = count / threads; /* XXX check if -c > -t */
|
|
||||||
a.flags = flags;
|
|
||||||
a.verbose = verbose;
|
|
||||||
|
|
||||||
printf("connect to '%s!%s!%s' roughly %d times, %d per thread\n",
|
|
||||||
proto, host, port, count, a.count);
|
|
||||||
|
|
||||||
for (i = 0; i < threads; i++) {
|
|
||||||
err = pthread_create(&thread[i], NULL, run, (void*)&a);
|
|
||||||
if (err != 0)
|
|
||||||
handle_error_en(err, "pthread_create");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < threads; i++) {
|
|
||||||
err = pthread_join(thread[i], NULL);
|
|
||||||
if (err != 0)
|
|
||||||
handle_error_en(err, "pthread_create");
|
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo(ai);
|
|
||||||
free(thread);
|
|
||||||
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Simple http_srv client
|
|
||||||
* \author Josef Soentgen
|
|
||||||
* \date 2012-8-30
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2012-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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
dial(struct addrinfo *ai)
|
|
||||||
{
|
|
||||||
struct addrinfo *aip;
|
|
||||||
int s, err;
|
|
||||||
|
|
||||||
for (aip = ai; aip != NULL; aip->ai_next) {
|
|
||||||
s = socket(aip->ai_family, aip->ai_socktype,
|
|
||||||
aip->ai_protocol);
|
|
||||||
if (s == -1) {
|
|
||||||
perror("socket");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = connect(s, aip->ai_addr, aip->ai_addrlen);
|
|
||||||
if (err != -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
close(s);
|
|
||||||
s = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct addrinfo *
|
|
||||||
lookup(const char *proto, const char *host, const char *port)
|
|
||||||
{
|
|
||||||
struct addrinfo hints, *r;
|
|
||||||
int err, socktype, protocol;
|
|
||||||
|
|
||||||
if (proto == NULL) {
|
|
||||||
fprintf(stderr, "protocol is not set\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* actually we can simply use protcol == 0 but we
|
|
||||||
* set it explicitly anyway.
|
|
||||||
*/
|
|
||||||
if (strcmp(proto, "tcp") == 0) {
|
|
||||||
socktype = SOCK_STREAM;
|
|
||||||
protocol = IPPROTO_TCP;
|
|
||||||
}
|
|
||||||
else if (strcmp(proto, "udp") == 0) {
|
|
||||||
socktype = SOCK_DGRAM;
|
|
||||||
protocol = IPPROTO_UDP;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "protocol '%s' invalid\n", proto);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
hints.ai_socktype = socktype;
|
|
||||||
hints.ai_flags = 0;
|
|
||||||
hints.ai_protocol = protocol;
|
|
||||||
|
|
||||||
err = getaddrinfo(host, port, &hints, &r);
|
|
||||||
if (err != 0) {
|
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* \brief Minimal HTTP server lwIP demonstration
|
|
||||||
* \author lwIP Team
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2009-10-23
|
|
||||||
*
|
|
||||||
* This small example shows how to use the LwIP in Genode directly.
|
|
||||||
* If you simply want to use LwIP's socket API, you might use
|
|
||||||
* Genode's libc together with its LwIP backend, especially useful
|
|
||||||
* when porting legacy code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2009-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 <base/log.h>
|
|
||||||
#include <libc/component.h>
|
|
||||||
#include <nic/packet_allocator.h>
|
|
||||||
#include <util/string.h>
|
|
||||||
|
|
||||||
/* LwIP includes */
|
|
||||||
extern "C" {
|
|
||||||
#include <lwip/sockets.h>
|
|
||||||
#include <lwip/api.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <lwip_legacy/genode.h>
|
|
||||||
|
|
||||||
using Response = Genode::String<1024>;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a single client's request.
|
|
||||||
*
|
|
||||||
* \param conn socket connected to the client
|
|
||||||
*/
|
|
||||||
void http_server_serve(int conn, Response & response)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
ssize_t buflen;
|
|
||||||
|
|
||||||
/* Read the data from the port, blocking if nothing yet there.
|
|
||||||
We assume the request (the part we care about) is in one packet */
|
|
||||||
buflen = lwip_recv(conn, buf, 1024, 0);
|
|
||||||
Genode::log("Packet received!");
|
|
||||||
|
|
||||||
/* Ignore all receive errors */
|
|
||||||
if (buflen > 0) {
|
|
||||||
|
|
||||||
/* 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)*/
|
|
||||||
if (buflen >= 5 &&
|
|
||||||
buf[0] == 'G' &&
|
|
||||||
buf[1] == 'E' &&
|
|
||||||
buf[2] == 'T' &&
|
|
||||||
buf[3] == ' ' &&
|
|
||||||
buf[4] == '/' ) {
|
|
||||||
|
|
||||||
Genode::log("Will send response");
|
|
||||||
|
|
||||||
/* Send our HTML page */
|
|
||||||
lwip_send(conn, response.string(), response.length(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Initialization_failed {};
|
|
||||||
#define ASSERT(cond, err) \
|
|
||||||
if (!cond) { \
|
|
||||||
Genode::error(err); \
|
|
||||||
throw Initialization_failed(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
void Libc::Component::construct(Libc::Env & env)
|
|
||||||
{
|
|
||||||
using namespace Genode;
|
|
||||||
using Address = Genode::String<16>;
|
|
||||||
|
|
||||||
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
|
|
||||||
|
|
||||||
|
|
||||||
lwip_tcpip_init();
|
|
||||||
|
|
||||||
uint32_t ip = 0;
|
|
||||||
uint32_t nm = 0;
|
|
||||||
uint32_t gw = 0;
|
|
||||||
unsigned port = 0;
|
|
||||||
|
|
||||||
Address ip_addr_str;
|
|
||||||
Address netmask_str;
|
|
||||||
Address gateway_str;
|
|
||||||
|
|
||||||
Attached_rom_dataspace config(env, "config");
|
|
||||||
Xml_node libc_node = env.libc_config();
|
|
||||||
libc_node.attribute("ip_addr").value(&ip_addr_str);
|
|
||||||
libc_node.attribute("netmask").value(&netmask_str);
|
|
||||||
libc_node.attribute("gateway").value(&gateway_str);
|
|
||||||
config.xml().attribute("port").value(&port);
|
|
||||||
|
|
||||||
log("static network interface: ip=", ip_addr_str, " nm=", netmask_str, " gw=", gateway_str);
|
|
||||||
|
|
||||||
ip = inet_addr(ip_addr_str.string());
|
|
||||||
nm = inet_addr(netmask_str.string());
|
|
||||||
gw = inet_addr(gateway_str.string());
|
|
||||||
|
|
||||||
ASSERT((ip != INADDR_NONE && nm != INADDR_NONE && gw != INADDR_NONE),
|
|
||||||
"Invalid network interface config.");
|
|
||||||
|
|
||||||
/* Initialize network stack */
|
|
||||||
ASSERT(!lwip_nic_init(ip, nm, gw, BUF_SIZE, BUF_SIZE),
|
|
||||||
"got no IP address!");
|
|
||||||
|
|
||||||
log("Create new socket ...");
|
|
||||||
|
|
||||||
int s;
|
|
||||||
ASSERT(((s = lwip_socket(AF_INET, SOCK_STREAM, 0)) >= 0),
|
|
||||||
"no socket available!");
|
|
||||||
|
|
||||||
static Response response(
|
|
||||||
"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"
|
|
||||||
"<html><head></head><body>"
|
|
||||||
"<h1>HTTP server at %s:%u</h1>"
|
|
||||||
"<p>This is a small test page.</body></html>",
|
|
||||||
ip_addr_str.string(), port);
|
|
||||||
|
|
||||||
log("Now, I will bind ...");
|
|
||||||
|
|
||||||
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;
|
|
||||||
ASSERT(!lwip_bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr)),
|
|
||||||
"bind failed!");
|
|
||||||
|
|
||||||
log("Now, I will listen ...");
|
|
||||||
ASSERT(!lwip_listen(s, 5),
|
|
||||||
"listen failed!");
|
|
||||||
|
|
||||||
log("Start the server loop ...");
|
|
||||||
while (true) {
|
|
||||||
struct sockaddr addr;
|
|
||||||
socklen_t len = sizeof(addr);
|
|
||||||
int client = lwip_accept(s, &addr, &len);
|
|
||||||
if(client < 0) {
|
|
||||||
warning("invalid socket from accept!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
http_server_serve(client, response);
|
|
||||||
lwip_close(client);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
TARGET = test-lwip_httpsrv_static
|
|
||||||
LIBS = lwip_legacy libc
|
|
||||||
SRC_CC = main.cc
|
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/lib/lwip/include
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = test-lwip_loop
|
TARGET = test-lwip_loop
|
||||||
LIBS = lwip_legacy posix libc_lwip_loopback
|
LIBS = posix
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -23,19 +23,19 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using Ipv4_addr_str = Genode::String<16>;
|
using Ipv4_addr_str = Genode::String<16>;
|
||||||
|
|
||||||
void Libc::Component::construct(Libc::Env &env)
|
static void test(Libc::Env &env)
|
||||||
{
|
{
|
||||||
/* wait a while for the server to come up */
|
|
||||||
Timer::Connection timer(env);
|
Timer::Connection timer(env);
|
||||||
timer.msleep(4000);
|
|
||||||
/* try to send and receive a message multiple times */
|
/* try to send and receive a message multiple times */
|
||||||
for (unsigned trial_cnt = 0, success_cnt = 0; trial_cnt < 10; trial_cnt++)
|
for (unsigned trial_cnt = 0, success_cnt = 0; trial_cnt < 15; trial_cnt++)
|
||||||
{
|
{
|
||||||
timer.msleep(2000);
|
usleep(1000);
|
||||||
|
|
||||||
/* create socket */
|
/* create socket */
|
||||||
int s = socket(AF_INET, SOCK_DGRAM, 0 );
|
int s = socket(AF_INET, SOCK_DGRAM, 0 );
|
||||||
@ -85,3 +85,5 @@ void Libc::Component::construct(Libc::Env &env)
|
|||||||
log("Test failed");
|
log("Test failed");
|
||||||
env.parent().exit(-1);
|
env.parent().exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env) { with_libc([&] () { test(env); }); }
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
TARGET = test-lwip-udp-client
|
TARGET = test-lwip-udp-client
|
||||||
LIBS = libc libc_lwip_nic_dhcp libc_lwip lwip_legacy
|
LIBS = libc
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/lib/lwip/include
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/attached_rom_dataspace.h>
|
|
||||||
#include <libc/component.h>
|
#include <libc/component.h>
|
||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
@ -34,7 +33,7 @@ struct Bind_failed : Genode::Exception { };
|
|||||||
struct Read_port_attr_failed : Genode::Exception { };
|
struct Read_port_attr_failed : Genode::Exception { };
|
||||||
|
|
||||||
|
|
||||||
void Libc::Component::construct(Libc::Env & env)
|
static void test(Libc::Env & env)
|
||||||
{
|
{
|
||||||
/* create socket */
|
/* create socket */
|
||||||
int s = socket(AF_INET, SOCK_DGRAM, 0 );
|
int s = socket(AF_INET, SOCK_DGRAM, 0 );
|
||||||
@ -43,12 +42,12 @@ void Libc::Component::construct(Libc::Env & env)
|
|||||||
}
|
}
|
||||||
/* read server port */
|
/* read server port */
|
||||||
unsigned port = 0;
|
unsigned port = 0;
|
||||||
Attached_rom_dataspace config(env, "config");
|
env.config([&] (Xml_node config_node) {
|
||||||
Xml_node config_node = config.xml();
|
try { config_node.attribute("port").value(&port); }
|
||||||
try { config_node.attribute("port").value(&port); }
|
catch (...) {
|
||||||
catch (...) {
|
throw Read_port_attr_failed();
|
||||||
throw Read_port_attr_failed();
|
}
|
||||||
}
|
});
|
||||||
/* create server socket address */
|
/* create server socket address */
|
||||||
struct sockaddr_in in_addr;
|
struct sockaddr_in in_addr;
|
||||||
in_addr.sin_family = AF_INET;
|
in_addr.sin_family = AF_INET;
|
||||||
@ -78,3 +77,5 @@ void Libc::Component::construct(Libc::Env & env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Libc::Component::construct(Libc::Env &env) { with_libc([&] () { test(env); }); }
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
TARGET = test-lwip-udp-server
|
TARGET = test-lwip-udp-server
|
||||||
LIBS = libc libc_lwip_nic_dhcp libc_lwip lwip_legacy
|
LIBS = libc
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
|
|
||||||
INC_DIR += $(REP_DIR)/src/lib/lwip/include
|
|
||||||
|
|
||||||
CC_CXX_WARN_STRICT =
|
CC_CXX_WARN_STRICT =
|
||||||
|
@ -23,5 +23,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lwip.inc
|
set ip_match_string "address=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/libports/run/vfs_lwip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -23,5 +23,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lwip.inc
|
set ip_match_string "address=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/libports/run/vfs_lwip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -22,5 +22,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lwip.inc
|
set ip_match_string "address=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/libports/run/vfs_lwip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -32,7 +32,9 @@ set use_usb_30 "no"
|
|||||||
set wifi_ssid $::env(GENODE_WIFI_SSID)
|
set wifi_ssid $::env(GENODE_WIFI_SSID)
|
||||||
set wifi_psk $::env(GENODE_WIFI_PSK)
|
set wifi_psk $::env(GENODE_WIFI_PSK)
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lwip.inc
|
set ip_match_string "address=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/libports/run/vfs_lwip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
|
||||||
# remove firmware images
|
# remove firmware images
|
||||||
|
@ -23,5 +23,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lxip.inc
|
set ip_match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -23,5 +23,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lxip.inc
|
set ip_match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -22,5 +22,7 @@ set use_usb_11 "no"
|
|||||||
set use_usb_20 "no"
|
set use_usb_20 "no"
|
||||||
set use_usb_30 "yes"
|
set use_usb_30 "yes"
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lxip.inc
|
set ip_match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
@ -32,7 +32,9 @@ set use_usb_30 "no"
|
|||||||
set wifi_ssid $::env(GENODE_WIFI_SSID)
|
set wifi_ssid $::env(GENODE_WIFI_SSID)
|
||||||
set wifi_psk $::env(GENODE_WIFI_PSK)
|
set wifi_psk $::env(GENODE_WIFI_PSK)
|
||||||
|
|
||||||
source ${genode_dir}/repos/ports/run/netperf_lxip.inc
|
set ip_match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||||
|
|
||||||
|
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||||
source ${genode_dir}/repos/ports/run/netperf.inc
|
source ${genode_dir}/repos/ports/run/netperf.inc
|
||||||
|
|
||||||
# remove firmware images
|
# remove firmware images
|
||||||
|
Loading…
Reference in New Issue
Block a user