mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 11:16:57 +00:00
Remove libc_lxip
The libc_lxip library is superceded by vfs_lwip. Fix #2960 Fix #2535
This commit is contained in:
parent
db9ff821a2
commit
47c6377ac0
@ -29,24 +29,6 @@ namespace Lxip {
|
||||
|
||||
enum Type { TYPE_STREAM, TYPE_DGRAM };
|
||||
|
||||
class Socketcall;
|
||||
|
||||
/**
|
||||
* Init backend
|
||||
*
|
||||
* \param ip_addr_str IP address
|
||||
* \param netmask_str Netmask
|
||||
* \param gateway_str Gateway
|
||||
* \param nameserver_str Nameserver
|
||||
*
|
||||
* \return Reference to Socketcall object
|
||||
*/
|
||||
Socketcall & init(Genode::Env &env,
|
||||
char const *ip_addr_str,
|
||||
char const *netmask_str,
|
||||
char const *gateway_str,
|
||||
char const *nameserver_str);
|
||||
|
||||
typedef Genode::uint8_t uint8_t;
|
||||
typedef Genode::uint16_t uint16_t;
|
||||
typedef Genode::uint32_t uint32_t;
|
||||
@ -93,30 +75,4 @@ namespace Lxip {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class Lxip::Socketcall
|
||||
{
|
||||
public:
|
||||
|
||||
virtual Handle accept(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int bind(Handle h, uint16_t family, void *addr) = 0;
|
||||
virtual void close(Handle h) = 0;
|
||||
virtual int connect(Handle h, uint16_t family, void *addr) = 0;
|
||||
virtual int getpeername(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int getsockname(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int getsockopt(Handle h, int level, int optname,
|
||||
void *optval, int *optlen) = 0;
|
||||
virtual int ioctl(Handle h, int request, char *arg) = 0;
|
||||
virtual int listen(Handle h, int backlog) = 0;
|
||||
virtual int poll(Handle h, bool block) = 0;
|
||||
virtual ssize_t recv(Handle h, void *buf, size_t len, int flags,
|
||||
uint16_t family, void *addr, uint32_t *addr_len) = 0;
|
||||
virtual ssize_t send(Handle h, const void *buf, size_t len, int flags,
|
||||
uint16_t family, void *addr) = 0;
|
||||
virtual int setsockopt(Handle h, int level, int optname,
|
||||
const void *optval, uint32_t optlen) = 0;
|
||||
virtual int shutdown(Handle h, int how) = 0;
|
||||
virtual Handle socket(Type) = 0;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_LXIP_LXIP_H_ */
|
||||
|
@ -1,7 +0,0 @@
|
||||
SRC_CC = plugin.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_lxip
|
||||
|
||||
LIBS += lxip libc
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -25,7 +25,7 @@ CC_C_OPT += -Wno-unused-but-set-variable -Wno-pointer-sign
|
||||
CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h
|
||||
CC_CXX_OPT = -fpermissive
|
||||
|
||||
SRC_CC = dummies.cc lxcc_emul.cc nic_handler.cc socket_handler.cc \
|
||||
SRC_CC = dummies.cc lxcc_emul.cc nic_handler.cc \
|
||||
timer_handler.cc random.cc
|
||||
|
||||
SRC_CC += malloc.cc printf.cc env.cc
|
||||
|
@ -1,151 +0,0 @@
|
||||
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
||||
set use_nic_driver [expr [have_spec linux] || [expr !$use_usb_driver && ![have_spec imx53] && ![have_spec odroid_xu] && ![have_spec linux] && ![have_spec imx6q_sabrelite]]]
|
||||
|
||||
set lynx [installed_command lynx]
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
||||
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
|
||||
return gpio_drv }
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/nic
|
||||
test/lxip/http_srv
|
||||
}
|
||||
|
||||
lappend_if $use_usb_driver build_components drivers/usb
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</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="test-lxip_http_srv" caps="200">
|
||||
<resource name="RAM" quantum="28M"/>
|
||||
<config ld_verbose="yes">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="10.0.2.55" gateway="10.0.2.1" netmask="255.255.255.0"/>
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec gpio] config "
|
||||
<start name=\"[gpio_drv]\">
|
||||
<resource name=\"RAM\" quantum=\"4M\"/>
|
||||
<provides><service name=\"Gpio\"/></provides>
|
||||
<config/>
|
||||
</start>"
|
||||
|
||||
append_if $use_usb_driver config {
|
||||
<start name="usb_drv">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
</provides>
|
||||
<config ehci="yes">
|
||||
<nic mac="02:00:00:00:01:01" />
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append_if $use_nic_driver config {
|
||||
<start name="nic_drv" caps="120">
|
||||
<binary name="} [nic_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>}
|
||||
|
||||
append config {
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer posix.lib.so
|
||||
libc.lib.so vfs.lib.so libm.lib.so lxip.lib.so test-lxip_http_srv
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
lappend_if $use_usb_driver boot_modules usb_drv
|
||||
lappend_if $use_nic_driver boot_modules [nic_drv_binary]
|
||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
#
|
||||
# Execute test case
|
||||
#
|
||||
|
||||
# qemu config
|
||||
append qemu_args " -nographic "
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
|
||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
|
||||
|
||||
append qemu_args " -net user -redir tcp:5555::80 "
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
set match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
|
||||
run_genode_until $match_string 30
|
||||
|
||||
if {[have_include "power_on/qemu"]} {
|
||||
set uri "http://localhost:5555/"
|
||||
} else {
|
||||
regexp $match_string $output all ip_addr
|
||||
|
||||
set uri "http://$ip_addr:80/"
|
||||
}
|
||||
|
||||
puts "http server is up, try to query website $uri"
|
||||
|
||||
set website [exec $lynx -dump $uri]
|
||||
|
||||
puts "response:\n$website"
|
||||
|
||||
if {![regexp {Welcome to our HTTP demonstration server!} $website dummy]} {
|
||||
puts stderr "Query returned unexpected website"
|
||||
exit 2;
|
||||
}
|
||||
|
||||
# vi: set ft=tcl :
|
@ -1,128 +0,0 @@
|
||||
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
||||
set use_nic_driver [expr [have_spec linux] || [expr !$use_usb_driver && ![have_spec imx53] && ![have_spec odroid_xu] && ![have_spec linux]]]
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/nic
|
||||
test/lxip/udp_echo
|
||||
}
|
||||
|
||||
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
|
||||
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
|
||||
return gpio_drv }
|
||||
|
||||
lappend_if $use_usb_driver build_components drivers/usb
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL"/>
|
||||
</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="test-lxip_udp_echo" caps="200">
|
||||
<resource name="RAM" quantum="28M"/>
|
||||
<config port="1337">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="10.0.2.55"
|
||||
gateway="10.0.2.1" netmask="255.255.255.0"/>
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
append_if [have_spec gpio] config {
|
||||
<start name="} [gpio_drv] {">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Gpio"/></provides>
|
||||
<config/>
|
||||
</start>}
|
||||
|
||||
append_if $use_usb_driver config {
|
||||
<start name="usb_drv">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
</provides>
|
||||
<config ehci="yes">
|
||||
<nic mac="02:00:00:00:01:01" />
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append_if $use_nic_driver config {
|
||||
<start name="nic_drv" caps="120">
|
||||
<binary name="} [nic_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
</start>}
|
||||
|
||||
append config {
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer
|
||||
libc.lib.so vfs.lib.so libm.lib.so lxip.lib.so test-lxip_udp_echo
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
lappend_if $use_usb_driver boot_modules usb_drv
|
||||
lappend_if $use_nic_driver boot_modules [nic_drv_binary]
|
||||
lappend_if [have_spec gpio] boot_modules [gpio_drv]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
#
|
||||
# Execute test case
|
||||
#
|
||||
|
||||
# qemu config
|
||||
append qemu_args " -nographic "
|
||||
|
||||
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
|
||||
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
|
||||
|
||||
append qemu_args " -net user -redir udp:5555::1337 "
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
# vi: set ft=tcl :
|
@ -22,7 +22,6 @@ namespace Lx_kit { class Env; }
|
||||
namespace Lx {
|
||||
|
||||
void nic_client_init(Genode::Env &env,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Allocator &alloc,
|
||||
void (*ticker)());
|
||||
|
||||
|
@ -111,16 +111,15 @@ class Nic_client
|
||||
public:
|
||||
|
||||
Nic_client(Genode::Env &env,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Allocator &alloc,
|
||||
void (*ticker)())
|
||||
:
|
||||
_tx_block_alloc(&alloc),
|
||||
_nic(env, &_tx_block_alloc, BUF_SIZE, BUF_SIZE),
|
||||
_sink_ack(ep, *this, &Nic_client::_packet_avail),
|
||||
_sink_submit(ep, *this, &Nic_client::_ready_to_ack),
|
||||
_source_ack(ep, *this, &Nic_client::_ack_avail),
|
||||
_link_state_change(ep, *this, &Nic_client::_link_state),
|
||||
_sink_ack(env.ep(), *this, &Nic_client::_packet_avail),
|
||||
_sink_submit(env.ep(), *this, &Nic_client::_ready_to_ack),
|
||||
_source_ack(env.ep(), *this, &Nic_client::_ack_avail),
|
||||
_link_state_change(env.ep(), *this, &Nic_client::_link_state),
|
||||
_tick(ticker)
|
||||
{
|
||||
ic_link_state = _nic.link_state();
|
||||
@ -140,11 +139,10 @@ static Nic_client *_nic_client;
|
||||
|
||||
|
||||
void Lx::nic_client_init(Genode::Env &env,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Allocator &alloc,
|
||||
void (*ticker)())
|
||||
{
|
||||
static Nic_client _inst(env, ep, alloc, ticker);
|
||||
static Nic_client _inst(env, alloc, ticker);
|
||||
_nic_client = &_inst;
|
||||
}
|
||||
|
||||
|
@ -1,636 +0,0 @@
|
||||
/*
|
||||
* \brief Front-end and glue to IP stack
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-09-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/allocator.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/log.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* local includes */
|
||||
#include <lxip/lxip.h>
|
||||
#include <lx.h>
|
||||
#include <nic.h>
|
||||
|
||||
/* Lx_kit */
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/malloc.h>
|
||||
|
||||
static const bool verbose = false;
|
||||
|
||||
|
||||
namespace Linux {
|
||||
#include <lx_emul.h>
|
||||
#include <msghdr.h>
|
||||
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/socket.h>
|
||||
#include <uapi/linux/in.h>
|
||||
extern int sock_setsockopt(struct socket *sock, int level,
|
||||
int op, char __user *optval,
|
||||
unsigned int optlen);
|
||||
extern int sock_getsockopt(struct socket *sock, int level,
|
||||
int op, char __user *optval,
|
||||
int __user *optlen);
|
||||
struct socket *sock_alloc(void);
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
}
|
||||
|
||||
namespace Net
|
||||
{
|
||||
class Socketcall;
|
||||
|
||||
enum Opcode { OP_SOCKET = 0, OP_CLOSE = 1, OP_BIND = 2, OP_LISTEN = 3,
|
||||
OP_ACCEPT = 4, OP_POLL = 5, OP_RECV = 6, OP_CONNECT = 7,
|
||||
OP_SEND = 8, OP_SETOPT = 9, OP_GETOPT = 10, OP_GETNAME = 11,
|
||||
OP_PEERNAME = 12, OP_IOCTL = 13, OP_SHUTDOWN = 14 };
|
||||
|
||||
struct Call
|
||||
{
|
||||
Opcode opcode;
|
||||
Lxip::Handle handle;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Lxip::Type type;
|
||||
} socket;
|
||||
struct
|
||||
{
|
||||
int backlog;
|
||||
} listen;
|
||||
struct
|
||||
{
|
||||
void *addr;
|
||||
Lxip::uint32_t *len;
|
||||
} accept;
|
||||
struct
|
||||
{
|
||||
mutable void *buf;
|
||||
Lxip::size_t len;
|
||||
int flags;
|
||||
void *addr;
|
||||
Lxip::uint32_t *addr_len;
|
||||
} msg;
|
||||
struct
|
||||
{
|
||||
int level;
|
||||
int optname;
|
||||
const void *optval;
|
||||
Lxip::uint32_t optlen;
|
||||
int *optlen_ptr;
|
||||
} sockopt;
|
||||
struct {
|
||||
bool block;
|
||||
} poll;
|
||||
struct {
|
||||
int request;
|
||||
unsigned long arg;
|
||||
} ioctl;
|
||||
struct {
|
||||
int how;
|
||||
} shutdown;
|
||||
};
|
||||
|
||||
struct Linux::sockaddr_storage addr;
|
||||
Lxip::uint32_t addr_len;
|
||||
};
|
||||
|
||||
union Result
|
||||
{
|
||||
int err;
|
||||
Lxip::ssize_t len;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Net::Socketcall : public Lxip::Socketcall,
|
||||
public Genode::Entrypoint
|
||||
{
|
||||
private:
|
||||
|
||||
Call _call;
|
||||
Result _result;
|
||||
Lxip::Handle _handle;
|
||||
|
||||
Genode::Semaphore _block;
|
||||
Genode::Signal_handler<Socketcall> _dispatcher { *this, *this, &Socketcall::_dispatch };
|
||||
|
||||
void _submit_and_block()
|
||||
{
|
||||
Genode::Signal_transmitter(_dispatcher).submit();
|
||||
_block.down();
|
||||
}
|
||||
|
||||
void _unblock() { _block.up(); }
|
||||
|
||||
struct Linux::socket * call_socket()
|
||||
{
|
||||
return static_cast<struct Linux::socket *>(_call.handle.socket);
|
||||
}
|
||||
|
||||
|
||||
Lxip::uint32_t _family_handler(Lxip::uint16_t family, void *addr)
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
switch (family)
|
||||
{
|
||||
case AF_INET:
|
||||
|
||||
struct sockaddr_in *in = (struct sockaddr_in *)addr;
|
||||
struct sockaddr_in *out = (struct sockaddr_in *)&_call.addr;
|
||||
|
||||
out->sin_family = family;
|
||||
out->sin_port = in->sin_port;
|
||||
out->sin_addr.s_addr = in->sin_addr.s_addr;
|
||||
|
||||
return sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
** Glue interface to Linux TCP/IP stack **
|
||||
******************************************/
|
||||
|
||||
void _do_accept()
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
struct socket *sock = call_socket();
|
||||
struct socket *new_sock = sock_alloc();
|
||||
|
||||
_handle.socket = 0;
|
||||
|
||||
if (!new_sock)
|
||||
return;
|
||||
|
||||
new_sock->type = sock->type;
|
||||
new_sock->ops = sock->ops;
|
||||
|
||||
if ((sock->ops->accept(sock, new_sock, 0)) < 0) {
|
||||
kfree(new_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
_handle.socket = static_cast<void *>(new_sock);
|
||||
|
||||
if (!_call.accept.addr)
|
||||
return;
|
||||
|
||||
int len;
|
||||
if ((new_sock->ops->getname(new_sock, (struct sockaddr *)&_call.addr,
|
||||
&len, 2)) < 0)
|
||||
return;
|
||||
|
||||
*_call.accept.len = min(*_call.accept.len, len);
|
||||
Genode::memcpy(_call.accept.addr, &_call.addr, *_call.accept.len);
|
||||
}
|
||||
|
||||
void _do_bind()
|
||||
{
|
||||
struct Linux::socket *sock = call_socket();
|
||||
|
||||
_result.err = sock->ops->bind(sock, (struct Linux::sockaddr *) &_call.addr,
|
||||
_call.addr_len);
|
||||
}
|
||||
|
||||
void _do_close()
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
struct socket *s = call_socket();
|
||||
if (s->ops)
|
||||
s->ops->release(s);
|
||||
|
||||
kfree(s->wq);
|
||||
kfree(s);
|
||||
}
|
||||
|
||||
void _do_connect()
|
||||
{
|
||||
Linux::socket *sock = call_socket();
|
||||
|
||||
//XXX: have a look at the file flags
|
||||
_result.err = sock->ops->connect(sock, (struct Linux::sockaddr *) &_call.addr,
|
||||
_call.addr_len, 0);
|
||||
}
|
||||
|
||||
void _do_getname(int peer)
|
||||
{
|
||||
int len = sizeof(Linux::sockaddr_storage);
|
||||
_result.err = call_socket()->ops->getname(call_socket(),
|
||||
(struct Linux::sockaddr *)&_call.addr,
|
||||
&len, peer);
|
||||
|
||||
*_call.accept.len = min(*_call.accept.len, len);
|
||||
Genode::memcpy(_call.accept.addr, &_call.addr, *_call.accept.len);
|
||||
}
|
||||
|
||||
|
||||
void _do_getopt()
|
||||
{
|
||||
_result.err = Linux::sock_getsockopt(call_socket(), _call.sockopt.level,
|
||||
_call.sockopt.optname,
|
||||
(char *)_call.sockopt.optval,
|
||||
_call.sockopt.optlen_ptr);
|
||||
}
|
||||
|
||||
void _do_ioctl()
|
||||
{
|
||||
_result.err = call_socket()->ops->ioctl(call_socket(),
|
||||
_call.ioctl.request,
|
||||
_call.ioctl.arg);
|
||||
}
|
||||
|
||||
void _do_listen()
|
||||
{
|
||||
_result.err = call_socket()->ops->listen(call_socket(),
|
||||
_call.listen.backlog);
|
||||
}
|
||||
|
||||
void _do_poll()
|
||||
{
|
||||
using namespace Linux;
|
||||
struct socket *sock = call_socket();
|
||||
enum {
|
||||
POLLIN_SET = (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR),
|
||||
POLLOUT_SET = (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR),
|
||||
POLLEX_SET = (POLLPRI)
|
||||
};
|
||||
|
||||
/*
|
||||
* Needed by udp_poll because it may check file->f_flags
|
||||
*/
|
||||
struct file f;
|
||||
f.f_flags = 0;
|
||||
|
||||
/*
|
||||
* Set socket wait queue to one so we can block poll in 'tcp_poll -> poll_wait'
|
||||
*/
|
||||
set_sock_wait(sock, _call.poll.block ? 1 : 0);
|
||||
int mask = sock->ops->poll(&f, sock, 0);
|
||||
set_sock_wait(sock, 0);
|
||||
|
||||
_result.err = 0;
|
||||
if (mask & POLLIN_SET)
|
||||
_result.err |= Lxip::POLLIN;
|
||||
if (mask & POLLOUT_SET)
|
||||
_result.err |= Lxip::POLLOUT;
|
||||
if (mask & POLLEX_SET)
|
||||
_result.err |= Lxip::POLLEX;
|
||||
}
|
||||
|
||||
void _do_recv()
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
iovec iov { _call.msg.buf, _call.msg.len };
|
||||
|
||||
msghdr msg = create_msghdr(_call.addr_len ? &_call.addr : nullptr,
|
||||
_call.addr_len, _call.msg.len, &iov);
|
||||
|
||||
if (_call.handle.non_block)
|
||||
msg.msg_flags |= MSG_DONTWAIT;
|
||||
|
||||
//XXX: check for non-blocking flag
|
||||
_result.len = call_socket()->ops->recvmsg(call_socket(), &msg,
|
||||
_call.msg.len,
|
||||
_call.msg.flags);
|
||||
|
||||
if (_call.msg.addr) {
|
||||
*_call.msg.addr_len = min(*_call.msg.addr_len, msg.msg_namelen);
|
||||
Genode::memcpy(_call.msg.addr, &_call.addr, *_call.msg.addr_len);
|
||||
}
|
||||
}
|
||||
|
||||
void _do_send()
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
_result.len = socket_check_state(call_socket());
|
||||
if (_result.len < 0)
|
||||
return;
|
||||
|
||||
iovec iov { _call.msg.buf, _call.msg.len };
|
||||
|
||||
msghdr msg = create_msghdr(_call.addr_len ? &_call.addr : nullptr,
|
||||
_call.addr_len, _call.msg.len, &iov);
|
||||
|
||||
msg.msg_flags = _call.msg.flags;
|
||||
if (_call.handle.non_block)
|
||||
msg.msg_flags |= MSG_DONTWAIT;
|
||||
|
||||
_result.len = call_socket()->ops->sendmsg(call_socket(), &msg,
|
||||
_call.msg.len);
|
||||
}
|
||||
|
||||
void _do_setopt()
|
||||
{
|
||||
_result.err = Linux::sock_setsockopt(call_socket(), _call.sockopt.level,
|
||||
_call.sockopt.optname,
|
||||
(char *)_call.sockopt.optval,
|
||||
_call.sockopt.optlen);
|
||||
}
|
||||
|
||||
void _do_shutdown()
|
||||
{
|
||||
_result.err = call_socket()->ops->shutdown(call_socket(),
|
||||
_call.shutdown.how);
|
||||
}
|
||||
|
||||
void _do_socket()
|
||||
{
|
||||
using namespace Linux;
|
||||
int type = _call.socket.type == Lxip::TYPE_STREAM ? SOCK_STREAM :
|
||||
SOCK_DGRAM;
|
||||
|
||||
struct socket *s = sock_alloc();
|
||||
|
||||
if (sock_create_kern(nullptr, AF_INET, type, 0, &s)) {
|
||||
_handle.socket = 0;
|
||||
kfree(s);
|
||||
return;
|
||||
}
|
||||
|
||||
_handle.socket = static_cast<void *>(s);
|
||||
}
|
||||
|
||||
/***********************
|
||||
** Signal dispatcher **
|
||||
***********************/
|
||||
|
||||
void _dispatch()
|
||||
{
|
||||
Lx::timer_update_jiffies();
|
||||
|
||||
switch (_call.opcode) {
|
||||
|
||||
case OP_ACCEPT : _do_accept(); break;
|
||||
case OP_BIND : _do_bind(); break;
|
||||
case OP_CLOSE : _do_close(); break;
|
||||
case OP_CONNECT : _do_connect(); break;
|
||||
case OP_GETNAME : _do_getname(0); break;
|
||||
case OP_GETOPT : _do_getopt(); break;
|
||||
case OP_IOCTL : _do_ioctl(); break;
|
||||
case OP_PEERNAME : _do_getname(1); break;
|
||||
case OP_LISTEN : _do_listen(); break;
|
||||
case OP_POLL : _do_poll(); break;
|
||||
case OP_RECV : _do_recv(); break;
|
||||
case OP_SEND : _do_send(); break;
|
||||
case OP_SETOPT : _do_setopt(); break;
|
||||
case OP_SHUTDOWN : _do_shutdown(); break;
|
||||
case OP_SOCKET : _do_socket(); break;
|
||||
|
||||
default:
|
||||
_handle.socket = 0;
|
||||
Genode::warning("unkown opcode: ", (int)_call.opcode);
|
||||
}
|
||||
|
||||
_unblock();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Socketcall(Genode::Env &env)
|
||||
:
|
||||
Entrypoint(env, 64 * 1024 * sizeof(long), "socketcall",
|
||||
Genode::Affinity::Location())
|
||||
{ }
|
||||
|
||||
/**************************
|
||||
** Socketcall interface **
|
||||
**************************/
|
||||
|
||||
Lxip::Handle accept(Lxip::Handle h, void *addr, Lxip::uint32_t *len)
|
||||
{
|
||||
_call.opcode = OP_ACCEPT;
|
||||
_call.handle = h;
|
||||
_call.accept.addr = addr;
|
||||
_call.accept.len = len;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _handle;
|
||||
}
|
||||
|
||||
int bind(Lxip::Handle h, Lxip::uint16_t family, void *addr)
|
||||
{
|
||||
_call.opcode = OP_BIND;
|
||||
_call.handle = h;
|
||||
_call.addr_len = _family_handler(family, addr);
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
void close(Lxip::Handle h)
|
||||
{
|
||||
_call.opcode = OP_CLOSE;
|
||||
_call.handle = h;
|
||||
|
||||
_submit_and_block();
|
||||
}
|
||||
|
||||
int connect(Lxip::Handle h, Lxip::uint16_t family, void *addr)
|
||||
{
|
||||
_call.opcode = OP_CONNECT;
|
||||
_call.handle = h;
|
||||
_call.addr_len = _family_handler(family, addr);
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int getpeername(Lxip::Handle h, void *addr, Lxip::uint32_t *len)
|
||||
{
|
||||
_call.opcode = OP_PEERNAME;
|
||||
_call.handle = h;
|
||||
_call.accept.len = len;
|
||||
_call.accept.addr = addr;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int getsockname(Lxip::Handle h, void *addr, Lxip::uint32_t *len)
|
||||
{
|
||||
_call.opcode = OP_GETNAME;
|
||||
_call.handle = h;
|
||||
_call.accept.len = len;
|
||||
_call.accept.addr = addr;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int getsockopt(Lxip::Handle h, int level, int optname,
|
||||
void *optval, int *optlen)
|
||||
{
|
||||
_call.opcode = OP_GETOPT;
|
||||
_call.handle = h;
|
||||
_call.sockopt.level = level;
|
||||
_call.sockopt.optname = optname;
|
||||
_call.sockopt.optval = optval;
|
||||
_call.sockopt.optlen_ptr = optlen;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int ioctl(Lxip::Handle h, int request, char *arg)
|
||||
{
|
||||
_call.opcode = OP_IOCTL;
|
||||
_call.handle = h;
|
||||
_call.ioctl.request = request;
|
||||
_call.ioctl.arg = (unsigned long)arg;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int listen(Lxip::Handle h, int backlog)
|
||||
{
|
||||
_call.opcode = OP_LISTEN;
|
||||
_call.handle = h;
|
||||
_call.listen.backlog = backlog;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int poll(Lxip::Handle h, bool block)
|
||||
{
|
||||
_call.opcode = OP_POLL;
|
||||
_call.handle = h;
|
||||
_call.poll.block = block;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
Lxip::ssize_t recv(Lxip::Handle h, void *buf, Lxip::size_t len, int flags,
|
||||
Lxip::uint16_t family, void *addr,
|
||||
Lxip::uint32_t *addr_len)
|
||||
{
|
||||
_call.opcode = OP_RECV;
|
||||
_call.handle = h;
|
||||
_call.msg.buf = buf;
|
||||
_call.msg.len = len;
|
||||
_call.msg.addr = addr;
|
||||
_call.msg.addr_len = addr_len;
|
||||
_call.msg.flags = flags;
|
||||
_call.addr_len = _family_handler(family, addr);
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.len;
|
||||
}
|
||||
|
||||
Lxip::ssize_t send(Lxip::Handle h, const void *buf, Lxip::size_t len, int flags,
|
||||
Lxip::uint16_t family, void *addr)
|
||||
{
|
||||
_call.opcode = OP_SEND;
|
||||
_call.handle = h;
|
||||
_call.msg.buf = (void *)buf;
|
||||
_call.msg.len = len;
|
||||
_call.msg.flags = flags;
|
||||
_call.addr_len = _family_handler(family, addr);
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.len;
|
||||
}
|
||||
|
||||
int setsockopt(Lxip::Handle h, int level, int optname,
|
||||
const void *optval, Lxip::uint32_t optlen)
|
||||
{
|
||||
_call.opcode = OP_SETOPT,
|
||||
_call.handle = h;
|
||||
_call.sockopt.level = level;
|
||||
_call.sockopt.optname = optname;
|
||||
_call.sockopt.optval = optval;
|
||||
_call.sockopt.optlen = optlen;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
int shutdown(Lxip::Handle h, int how)
|
||||
{
|
||||
_call.opcode = OP_SHUTDOWN;
|
||||
_call.handle = h;
|
||||
_call.shutdown.how = how;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _result.err;
|
||||
}
|
||||
|
||||
Lxip::Handle socket(Lxip::Type type)
|
||||
{
|
||||
_call.opcode = OP_SOCKET;
|
||||
_call.socket.type = type;
|
||||
|
||||
_submit_and_block();
|
||||
|
||||
return _handle;
|
||||
}
|
||||
};
|
||||
|
||||
static void ticker() { }
|
||||
|
||||
Lxip::Socketcall & Lxip::init(Genode::Env &env,
|
||||
char const *ip_addr_str,
|
||||
char const *netmask_str,
|
||||
char const *gateway_str,
|
||||
char const *nameserver_str)
|
||||
{
|
||||
Lx_kit::Env &lx_env = Lx_kit::construct_env(env);
|
||||
|
||||
static Net::Socketcall socketcall(env);
|
||||
|
||||
Lx::lxcc_emul_init(lx_env);
|
||||
Lx::malloc_init(env, lx_env.heap());
|
||||
Lx::timer_init(env, socketcall, lx_env.heap(), ticker);
|
||||
Lx::event_init(env, socketcall, ticker);
|
||||
Lx::nic_client_init(env, socketcall, lx_env.heap(), ticker);
|
||||
|
||||
lxip_init();
|
||||
|
||||
if ((!ip_addr_str || (ip_addr_str[0] == 0)) ||
|
||||
(!netmask_str || (netmask_str[0] == 0)) ||
|
||||
(!gateway_str || (gateway_str[0] == 0)) ||
|
||||
(!nameserver_str || (nameserver_str[0] == 0)))
|
||||
lxip_configure_dhcp();
|
||||
else
|
||||
lxip_configure_static(ip_addr_str, netmask_str, gateway_str, nameserver_str);
|
||||
|
||||
return socketcall;
|
||||
}
|
@ -1971,7 +1971,7 @@ struct Lxip_factory : Vfs::File_system_factory
|
||||
Lx::malloc_init(env, lx_env.heap());
|
||||
Lx::timer_init(env, lx_env.env().ep(), lx_env.heap(), &poll_all);
|
||||
Lx::event_init(env, lx_env.env().ep(), &poll_all);
|
||||
Lx::nic_client_init(env, lx_env.env().ep(), lx_env.heap(), &poll_all);
|
||||
Lx::nic_client_init(env, lx_env.heap(), &poll_all);
|
||||
|
||||
lxip_init();
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* \brief Minimal HTTP server demonstration using socket API
|
||||
* \author Josef Soentgen
|
||||
* \date 2016-03-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-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/log.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
||||
const static char http_html_hdr[] =
|
||||
"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */
|
||||
|
||||
const static char http_index_html[] =
|
||||
"<html><head><title>Congrats!</title></head><body><h1>Welcome to our HTTP demonstration server!</h1><p>This is a small test page.</body></html>"; /* HTML page */
|
||||
|
||||
static void serve(int fd) {
|
||||
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 = recv(fd, buf, 1024, 0);
|
||||
|
||||
/* 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] == '/' ) {
|
||||
|
||||
/* Send http header */
|
||||
send(fd, http_html_hdr, sizeof(http_html_hdr), 0);
|
||||
|
||||
/* Send our HTML page */
|
||||
send(fd, http_index_html, sizeof(http_index_html), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int s;
|
||||
|
||||
Genode::log("create new socket ...");
|
||||
if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
Genode::error("no socket available!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::log("Now, I will bind ...");
|
||||
struct sockaddr_in in_addr;
|
||||
in_addr.sin_family = AF_INET;
|
||||
in_addr.sin_port = htons(80);
|
||||
in_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if(bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
|
||||
Genode::error("bind failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::log("Now, I will listen ...");
|
||||
if(listen(s, 5)) {
|
||||
Genode::error("listen failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Genode::log("Start the server loop ...");
|
||||
while(true) {
|
||||
struct sockaddr addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
int client = accept(s, &addr, &len);
|
||||
if(client < 0) {
|
||||
Genode::warning("invalid socket from accept!");
|
||||
continue;
|
||||
}
|
||||
serve(client);
|
||||
close(client);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
TARGET = test-lxip_http_srv
|
||||
LIBS = posix libc_lxip
|
||||
SRC_CC = main.cc
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* \brief Minimal datagram server demonstration using socket API
|
||||
* \author Josef Soentgen
|
||||
* \date 2016-04-22
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-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>
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
struct Test_failed : Genode::Exception { };
|
||||
|
||||
|
||||
static void server_loop(Genode::Xml_node config_node)
|
||||
{
|
||||
int s;
|
||||
|
||||
Genode::log("Create new socket ...");
|
||||
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
Genode::error("no socket available!");
|
||||
throw Test_failed();
|
||||
}
|
||||
|
||||
unsigned port = 0;
|
||||
try { config_node.attribute("port").value(&port); }
|
||||
catch (...) {
|
||||
error("Missing \"port\" attribute.");
|
||||
throw Xml_node::Nonexistent_attribute();
|
||||
}
|
||||
Genode::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;
|
||||
if(bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
|
||||
Genode::error("bind failed!");
|
||||
throw Test_failed();
|
||||
}
|
||||
|
||||
Genode::log("Start the server loop ...");
|
||||
while(true) {
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
socklen_t len = sizeof(addr);
|
||||
|
||||
char buf[4096];
|
||||
::memset(buf, 0, sizeof(buf));
|
||||
|
||||
ssize_t n = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
|
||||
|
||||
if (n == 0) {
|
||||
Genode::warning("Invalid request!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
Genode::error("Error ", n);
|
||||
break;
|
||||
}
|
||||
|
||||
Genode::log("Received ", n, " bytes");
|
||||
n = sendto(s, buf, n, 0, (struct sockaddr*)&addr, len);
|
||||
Genode::log("Send ", n, " bytes back");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Main(Genode::Env &env)
|
||||
{
|
||||
Genode::Attached_rom_dataspace config_rom { env, "config" };
|
||||
|
||||
Libc::with_libc([&] () {
|
||||
server_loop(config_rom.xml());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Libc::Component::construct(Libc::Env &env) { static Main main(env); }
|
@ -1,5 +0,0 @@
|
||||
TARGET = test-lxip_udp_echo
|
||||
LIBS = libc libc_lxip
|
||||
SRC_CC = main.cc
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
Loading…
Reference in New Issue
Block a user