diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index b97fa48249..5aea25d760 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -373,8 +373,7 @@ AddSymlinkToHaikuImage beos system add-ons Tracker AddFilesToHaikuImage beos system add-ons input_server devices : keyboard mouse wacom ; AddFilesToHaikuImage beos system add-ons input_server filters : screen_saver ; -AddFilesToHaikuImage beos system add-ons kernel network - : stack socket ; +AddFilesToHaikuImage beos system add-ons kernel network : stack ; AddFilesToHaikuImage beos system add-ons kernel network devices : $(BEOS_NETWORK_DEVICES) ; AddFilesToHaikuImage beos system add-ons kernel network datalink_protocols diff --git a/headers/os/drivers/socket_interface.h b/headers/os/drivers/socket_interface.h deleted file mode 100644 index 4132dfa7e2..0000000000 --- a/headers/os/drivers/socket_interface.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2007, Haiku Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - */ -#ifndef _SOCKET_INTERFACE_H -#define _SOCKET_INTERFACE_H - -//! Kernel interface to the socket API - - -#include - -#include - - -#define B_SOCKET_MODULE_NAME "network/socket/v1" - -struct socket_module_info { - struct module_info info; - - int (*accept)(int socket, struct sockaddr *address, socklen_t *_addressLength); - int (*bind)(int socket, const struct sockaddr *address, socklen_t addressLength); - int (*connect)(int socket, const struct sockaddr *address, socklen_t addressLength); - int (*getpeername)(int socket, struct sockaddr *address, socklen_t *_addressLength); - int (*getsockname)(int socket, struct sockaddr *address, socklen_t *_addressLength); - int (*getsockopt)(int socket, int level, int option, void *value, socklen_t *_length); - int (*listen)(int socket, int backlog); - ssize_t (*recv)(int socket, void *buffer, size_t length, int flags); - ssize_t (*recvfrom)(int socket, void *buffer, size_t bufferLength, int flags, - struct sockaddr *address, socklen_t *_addressLength); - ssize_t (*recvmsg)(int socket, struct msghdr *message, int flags); - ssize_t (*send)(int socket, const void *buffer, size_t length, int flags); - ssize_t (*sendmsg)(int socket, const struct msghdr *message, int flags); - ssize_t (*sendto)(int socket, const void *message, size_t length, int flags, - const struct sockaddr *address, socklen_t addressLength); - int (*setsockopt)(int socket, int level, int option, const void *value, - socklen_t length); - int (*shutdown)(int socket, int how); - int (*socket)(int domain, int type, int protocol); - int (*sockatmark)(int socket); - int (*socketpair)(int domain, int type, int protocol, int socketVector[2]); -}; - -#endif // _SOCKET_INTERFACE_H diff --git a/headers/private/net/net_stack_driver.h b/headers/private/net/net_stack_driver.h deleted file mode 100644 index 591ad5e5b9..0000000000 --- a/headers/private/net/net_stack_driver.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. - * This file may be used under the terms of the MIT License. - */ -#ifndef NET_STACK_DRIVER_H -#define NET_STACK_DRIVER_H - - -#include - -#include - - -// Forward declaration -struct sockaddr; - -#define NET_STACK_DRIVER_DEVICE "net/stack" -#define NET_STACK_DRIVER_PATH "/dev/" NET_STACK_DRIVER_DEVICE - -enum { - NET_STACK_IOCTL_BASE = 8800, - NET_STACK_IOCTL_END = 8999, - - // ops not acting on an existing socket - NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args * - NET_STACK_GET_COOKIE, // void ** - NET_STACK_CONTROL_NET_MODULE, // control_net_module_args * - NET_STACK_GET_NEXT_STAT, // get_next_stat_args * - - // ops acting on an existing socket - NET_STACK_BIND, // sockaddr_args * - NET_STACK_RECEIVE, // message_args * - NET_STACK_SEND, // message_args * - NET_STACK_LISTEN, // int_args * (value = backlog) - NET_STACK_ACCEPT, // sockaddr_args * - NET_STACK_CONNECT, // sockaddr_args * - NET_STACK_SHUTDOWN, // int_args * (value = how) - NET_STACK_GETSOCKOPT, // sockopt_args * - NET_STACK_SETSOCKOPT, // sockopt_args * - NET_STACK_GETSOCKNAME, // sockaddr_args * - NET_STACK_GETPEERNAME, // sockaddr_args * - NET_STACK_SOCKETPAIR, // socketpair_args * - - NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only) - - NET_STACK_IOCTL_MAX -}; - -struct sockaddr_args { // used by NET_STACK_CONNECT/_BIND/_GETSOCKNAME/_GETPEERNAME - struct sockaddr *address; - socklen_t address_length; -}; - -struct sockopt_args { // used by NET_STACK_SETSOCKOPT/_GETSOCKOPT - int level; - int option; - void *value; - int length; -}; - -struct message_args { - struct msghdr *header; - void *data; - size_t length; - int flags; -}; - -struct socket_args { // used by NET_STACK_SOCKET - int family; - int type; - int protocol; -}; - -struct socketpair_args { // used by NET_STACK_SOCKETPAIR - int second_socket; -}; - -struct accept_args { // used by NET_STACK_ACCEPT - int accept_socket; - struct sockaddr *address; - socklen_t address_length; -}; - -struct get_next_stat_args { // used by NET_STACK_GET_NEXT_STAT - uint32 cookie; - int family; - struct net_stat stat; -}; - -struct control_net_module_args { // used by NET_STACK_CONTROL_NET_MODULE - const char *name; - uint32 op; - void *data; - size_t length; -}; - -#endif /* NET_STACK_DRIVER_H */ diff --git a/src/add-ons/kernel/drivers/network/Jamfile b/src/add-ons/kernel/drivers/network/Jamfile index c688d31335..aafc022bfb 100644 --- a/src/add-ons/kernel/drivers/network/Jamfile +++ b/src/add-ons/kernel/drivers/network/Jamfile @@ -7,7 +7,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network pegasus ; SubInclude HAIKU_TOP src add-ons kernel drivers network rtl8139 ; SubInclude HAIKU_TOP src add-ons kernel drivers network rtl8169 ; SubInclude HAIKU_TOP src add-ons kernel drivers network sis900 ; -SubInclude HAIKU_TOP src add-ons kernel drivers network stack ; SubInclude HAIKU_TOP src add-ons kernel drivers network via_rhine ; SubInclude HAIKU_TOP src add-ons kernel drivers network vlance ; SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ; diff --git a/src/add-ons/kernel/drivers/network/stack/Jamfile b/src/add-ons/kernel/drivers/network/stack/Jamfile deleted file mode 100644 index 9c45ad0dc6..0000000000 --- a/src/add-ons/kernel/drivers/network/stack/Jamfile +++ /dev/null @@ -1,55 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel drivers network stack ; - -SetSubDirSupportedPlatformsBeOSCompatible ; - -if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { - UseHeaders [ FStandardOSHeaders ] : true ; - # Needed for and maybe other stuff. - UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; - # We need the public network headers also when not compiling for Haiku. - # Unfortunately we get more than we want, namely all POSIX headers. -} - -UsePrivateHeaders kernel net ; -UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; - -# a) Userland stack version: - -KernelAddon userland_net_server : - userland_server.cpp -; - -# b) Kernelland stack version: - -KernelAddon net_stack : - kernel_stack.cpp -; - -# Installation - -HaikuInstall install-networking : /boot/home/config/add-ons/kernel/drivers/bin : - userland_net_server - net_stack -; - -HaikuInstallRelSymLink install-networking : /boot/home/config/add-ons/kernel/drivers/dev/net : - userland_net_server - net_stack : - installed-symlink -; - -HaikuInstall install-userland-networking : /boot/home/config/add-ons/kernel/drivers/bin : - userland_net_server : - installed-userland-networking -; - -HaikuInstallRelSymLink install-userland-networking : /boot/home/config/add-ons/kernel/drivers/dev/net : - userland_net_server : - installed-userland-networking-symlink -; -Package haiku-networkingkit-cvs : - net_stack userland_net_server : - boot home config add-ons kernel drivers bin ; - -PackageDriverSymLink haiku-networkingkit-cvs : net net_stack ; -PackageDriverSymLink haiku-networkingkit-cvs : net userland_net_server ; diff --git a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp b/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp deleted file mode 100644 index 032c6d81b8..0000000000 --- a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright 2002-2008, Haiku, Inc. All Rights Reserved. - * This file may be used under the terms of the MIT License. - */ - -/*! - This file implements a very simple socket driver that is intended to - act as an interface to the networking stack. -*/ - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - - -#define NET_STARTER_MODULE_NAME "network/stack/starter/v1" - -// debugging macros -#define LOGID "net_stack_driver: " -#define ERROR(format, args...) dprintf(LOGID "ERROR: " format, ## args) - -#ifdef DEBUG -# define TRACE(format, args...) dprintf(format, ## args) -#else -# define TRACE(format, args...) -#endif - - -// the cookie we attach to each file descriptor opened on our driver entry -struct net_stack_cookie { - net_socket *socket; - // is set using NET_STACK_SOCKET/_ACCEPT -}; - - -int32 api_version = B_CUR_DRIVER_API_VERSION; - -static int32 sOpenCount = 0; -static status_t sInitializationStatus = B_NO_INIT; -static sem_id sInitializationSem; -static struct net_socket_module_info *sSocket = NULL; - - -// #pragma mark - internal functions - - -template status_t -return_address(ArgType &args, void *data) -{ - sockaddr_storage *target; - socklen_t length; - - if (user_memcpy(&target, &((ArgType *)data)->address, sizeof(void *)) - < B_OK - || user_memcpy(&length, &((ArgType *)data)->address_length, - sizeof(socklen_t)) < B_OK) - return B_BAD_ADDRESS; - - if (target == NULL) - return B_OK; - - if (user_memcpy(&((ArgType *)data)->address_length, &args.address_length, - sizeof(socklen_t)) < B_OK - || user_memcpy(target, args.address, min_c(length, args.address_length)) - < B_OK) - return B_BAD_ADDRESS; - - return B_OK; -} - - -template status_t -check_args_and_address(ArgType &args, sockaddr_storage &address, void *data, - size_t length, bool copyAddress = true) -{ - if (data == NULL || length != sizeof(ArgType)) - return B_BAD_VALUE; - - if (user_memcpy(&args, data, sizeof(ArgType)) < B_OK) - return B_BAD_ADDRESS; - - if (copyAddress && args.address_length > sizeof(sockaddr_storage)) - return B_BAD_VALUE; - - if (copyAddress - && user_memcpy(&address, args.address, args.address_length) < B_OK) - return B_BAD_ADDRESS; - - args.address = (sockaddr *)&address; - return B_OK; -} - - -static status_t -check_message_args(message_args &args, msghdr &header, - sockaddr_storage &address, void *data, size_t length, - sockaddr **originalAddress) -{ - if (length < sizeof(message_args)) - return B_BAD_VALUE; - - status_t status = user_memcpy(&args, data, sizeof(message_args)); - if (status < B_OK) - return status; - - if (args.header != NULL) { - status = user_memcpy(&header, args.header, sizeof(msghdr)); - if (status < B_OK) - return status; - - if (header.msg_name == NULL) - return B_OK; - - if (originalAddress == NULL) { - if (header.msg_namelen > sizeof(address)) - return B_BAD_VALUE; - - if (header.msg_name != NULL) { - status = user_memcpy(&address, header.msg_name, - header.msg_namelen); - if (status < B_OK) - return B_BAD_ADDRESS; - } - } else { - *originalAddress = (sockaddr *)header.msg_name; - } - - header.msg_name = (char *)&address; - } - - return B_OK; -} - - -template status_t -check_args(ArgType &args, void *data, size_t length) -{ - if (data == NULL || length != sizeof(ArgType)) - return B_BAD_VALUE; - - if (user_memcpy(&args, data, sizeof(ArgType)) < B_OK) - return B_BAD_ADDRESS; - - return B_OK; -} - - -#ifdef DEBUG -static const char* -opcode_name(int op) -{ -#define C2N(op) { op, #op } - // op-code to name - struct commands_info { - int op; - const char *name; - } *ci, commands_info[] = { - C2N(NET_STACK_SOCKET), - C2N(NET_STACK_GET_COOKIE), - C2N(NET_STACK_CONTROL_NET_MODULE), - C2N(NET_STACK_GET_NEXT_STAT), - C2N(NET_STACK_BIND), - C2N(NET_STACK_RECEIVE), - C2N(NET_STACK_SEND), - C2N(NET_STACK_LISTEN), - C2N(NET_STACK_ACCEPT), - C2N(NET_STACK_CONNECT), - C2N(NET_STACK_SHUTDOWN), - C2N(NET_STACK_GETSOCKOPT), - C2N(NET_STACK_SETSOCKOPT), - C2N(NET_STACK_GETSOCKNAME), - C2N(NET_STACK_GETPEERNAME), - C2N(NET_STACK_SOCKETPAIR), - C2N(NET_STACK_NOTIFY_SOCKET_EVENT), - - // Userland IPC-specific opcodes - // C2N(NET_STACK_OPEN), - // C2N(NET_STACK_CLOSE), - // C2N(NET_STACK_NEW_CONNECTION), - - // Standard BeOS opcodes - C2N(FIONBIO), - C2N(B_SET_BLOCKING_IO), - C2N(B_SET_NONBLOCKING_IO), - - { 0, "Unknown!" } - }; -#undef C2N - - ci = commands_info; - while(ci && ci->op) { - if (ci->op == op) - return ci->name; - ci++; - } - - return "???"; -} -#endif // DEBUG - - -static status_t -resolve_cookie(int kernel, int socket, net_stack_cookie **cookie) -{ - if (kernel) - return ioctl(socket, NET_STACK_GET_COOKIE, cookie, sizeof(*cookie)); - - return user_fd_kernel_ioctl(socket, NET_STACK_GET_COOKIE, cookie, - sizeof(*cookie)); -} - - -// #pragma mark - device - - -static status_t -net_stack_open(const char *name, uint32 flags, void **_cookie) -{ - if (atomic_add(&sOpenCount, 1) == 0) { - // When we're opened for the first time, we'll try to load the - // networking stack - module_info *module; - status_t status = get_module(NET_STARTER_MODULE_NAME, &module); - if (status == B_OK) { - status = get_module(NET_SOCKET_MODULE_NAME, - (module_info **)&sSocket); - if (status != B_OK) { - put_module(NET_STARTER_MODULE_NAME); - ERROR("Can't load " NET_SOCKET_MODULE_NAME " module: %ld\n", - status); - } - } else - ERROR("Can't load network stack module: %ld\n", status); - - sInitializationStatus = status; - release_sem_etc(sInitializationSem, 1, - B_RELEASE_ALL | B_DO_NOT_RESCHEDULE); - - if (status < B_OK) { - atomic_add(&sOpenCount, -1); - return status; - } - } else { - while (sInitializationStatus == B_NO_INIT) { - acquire_sem(sInitializationSem); - } - if (sInitializationStatus != B_OK) { - atomic_add(&sOpenCount, -1); - return sInitializationStatus; - } - } - - net_stack_cookie *cookie = (net_stack_cookie *)malloc( - sizeof(net_stack_cookie)); - if (cookie == NULL) - return B_NO_MEMORY; - - cookie->socket = NULL; - *_cookie = cookie; - - TRACE("net_stack_open(%s, %s%s) return this cookie: %p\n", - name, - (((flags & O_RWMASK) == O_RDONLY) ? "O_RDONLY" : - ((flags & O_RWMASK) == O_WRONLY) ? "O_WRONLY" : "O_RDWR"), - (flags & O_NONBLOCK) ? " O_NONBLOCK" : "", - cookie); - - return B_OK; -} - - -static status_t -net_stack_close(void *_cookie) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_close(%p)\n", cookie); - - if (cookie->socket == NULL) - return B_OK; - - return sSocket->close(cookie->socket); -} - - -static status_t -net_stack_free_cookie(void *_cookie) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_free_cookie(%p)\n", cookie); - - if (cookie->socket != NULL) - sSocket->free(cookie->socket); - - free(cookie); - - if (atomic_add(&sOpenCount, -1) == 1) { - // the last reference to us has been removed, unload the networking - // stack again (it will only be actually unloaded in case there is - // no interface defined) - put_module(NET_SOCKET_MODULE_NAME); - put_module(NET_STARTER_MODULE_NAME); - sInitializationStatus = B_NO_INIT; - } - - return B_OK; -} - - -static status_t -net_stack_control(void *_cookie, uint32 op, void *data, size_t length) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - status_t status; - - TRACE("net_stack_control(%p, %s (0x%lX), %p, %ld)\n", - _cookie, opcode_name(op), op, data, length); - - if (cookie->socket == NULL) { - switch (op) { - case NET_STACK_SOCKET: - { - socket_args args; - status = check_args(args, data, length); - if (status < B_OK) - return status; - - return sSocket->open_socket(args.family, args.type, - args.protocol, &cookie->socket); - } - - case NET_STACK_GET_COOKIE: - if (!IS_KERNEL_ADDRESS(data)) - return B_BAD_ADDRESS; - *((net_stack_cookie **)data) = cookie; - return B_OK; - - case NET_STACK_GET_NEXT_STAT: - { - get_next_stat_args args; - status = check_args(args, data, length); - if (status < B_OK) - return status; - - status = sSocket->get_next_stat(&args.cookie, args.family, - &args.stat); - if (status < B_OK) - return status; - - return user_memcpy(data, &args, sizeof(get_next_stat_args)); - } - - default: - return B_BAD_VALUE; - } - } else { - switch (op) { - case NET_STACK_CONNECT: - { - sockaddr_storage address; - sockaddr_args args; - status = check_args_and_address(args, address, data, length); - if (status < B_OK) - return status; - - status = sSocket->connect(cookie->socket, args.address, - args.address_length); - - return syscall_restart_ioctl_handle_post(status); - } - - case NET_STACK_BIND: - { - sockaddr_storage address; - sockaddr_args args; - status = check_args_and_address(args, address, data, length); - if (status < B_OK) - return status; - - return sSocket->bind(cookie->socket, args.address, - args.address_length); - } - - case NET_STACK_LISTEN: - // backlog to set - return sSocket->listen(cookie->socket, (int)data); - - case NET_STACK_ACCEPT: - { - int kernel = IS_KERNEL_ADDRESS(data); - sockaddr_storage address; - accept_args args; - - status = check_args_and_address(args, address, data, length, - false); - if (status < B_OK) - return status; - - net_stack_cookie *acceptCookie; - status = resolve_cookie(kernel, args.accept_socket, - &acceptCookie); - if (status < B_OK) - return status; - - status = sSocket->accept(cookie->socket, args.address, - &args.address_length, &acceptCookie->socket); - - if (status < B_OK) - return syscall_restart_ioctl_handle_post(status); - - return return_address(args, data); - } - - case NET_STACK_SHUTDOWN: - return sSocket->shutdown(cookie->socket, (int)data); - - case NET_STACK_SEND: - { - sockaddr_storage address; - message_args args; - msghdr header; - - status = check_message_args(args, header, address, data, - length, NULL); - if (status < B_OK) - return status; - - ssize_t bytesSent = sSocket->send(cookie->socket, - args.header ? &header : NULL, - args.data, args.length, args.flags); - - return syscall_restart_ioctl_handle_post(bytesSent); - } - - case NET_STACK_RECEIVE: - { - sockaddr *originalAddress = NULL; - sockaddr_storage address; - message_args args; - msghdr header; - - status = check_message_args(args, header, address, data, - length, &originalAddress); - if (status < B_OK) - return status; - - ssize_t bytesRead = sSocket->receive(cookie->socket, - args.header ? &header : NULL, args.data, - args.length, args.flags); - if (bytesRead < B_OK) - return syscall_restart_ioctl_handle_post(bytesRead); - - if (args.header != NULL) { - if (header.msg_name != NULL) { - if (user_memcpy(originalAddress, header.msg_name, - header.msg_namelen) < B_OK) - return B_BAD_ADDRESS; - } - - if (user_memcpy(&args.header->msg_flags, &header.msg_flags, - sizeof(int)) < B_OK) - return B_BAD_ADDRESS; - } - - return bytesRead; - } - - case NET_STACK_GETSOCKOPT: - { - sockopt_args args; - status = check_args(args, data, length); - if (status < B_OK) - return status; - - char valueBuffer[256]; - if (args.length > (int)sizeof(valueBuffer)) - return ENOBUFS; - - status = sSocket->getsockopt(cookie->socket, args.level, - args.option, valueBuffer, &args.length); - if (status < B_OK) - return status; - - if (user_memcpy(args.value, valueBuffer, args.length) < B_OK - || user_memcpy(&((sockopt_args *)data)->length, - &args.length, sizeof(int)) < B_OK) - return B_BAD_ADDRESS; - - return B_OK; - } - - case NET_STACK_SETSOCKOPT: - { - sockopt_args args; - status = check_args(args, data, length); - if (status < B_OK) - return status; - - char valueBuffer[256]; - if (args.length > (int)sizeof(valueBuffer)) - return ENOBUFS; - if (user_memcpy(valueBuffer, args.value, args.length) < B_OK) - return B_BAD_ADDRESS; - - return sSocket->setsockopt(cookie->socket, args.level, - args.option, valueBuffer, args.length); - } - - case NET_STACK_GETSOCKNAME: - { - sockaddr_storage address; - sockaddr_args args; - status = check_args_and_address(args, address, data, length, - false); - if (status < B_OK) - return status; - - status = sSocket->getsockname(cookie->socket, args.address, - &args.address_length); - if (status < B_OK) - return status; - - return return_address(args, data); - } - - case NET_STACK_GETPEERNAME: - { - sockaddr_storage address; - sockaddr_args args; - status = check_args_and_address(args, address, data, length, - false); - if (status < B_OK) - return status; - - status = sSocket->getpeername(cookie->socket, args.address, - &args.address_length); - if (status < B_OK) - return status; - - return return_address(args, data); - } - - case FIONBIO: - { - int value = (int)data; - return sSocket->setsockopt(cookie->socket, SOL_SOCKET, - SO_NONBLOCK, &value, sizeof(int)); - } - - case B_SET_BLOCKING_IO: - case B_SET_NONBLOCKING_IO: - { - int value = op == B_SET_NONBLOCKING_IO; - return sSocket->setsockopt(cookie->socket, SOL_SOCKET, - SO_NONBLOCK, &value, sizeof(int)); - } - - default: - if (op < NET_STACK_IOCTL_BASE || op > NET_STACK_IOCTL_END) { - // we only accept networking ioctl()s to get into our stack - return B_BAD_VALUE; - } - - return sSocket->control(cookie->socket, op, data, length); - } - } - - return B_BAD_VALUE; -} - - -static status_t -net_stack_read(void *_cookie, off_t /*offset*/, void *buffer, size_t *_length) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_read(%p, %p, %ld)\n", cookie, buffer, *_length); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - ssize_t bytesRead = sSocket->receive(cookie->socket, NULL, buffer, *_length, - 0); - if (bytesRead < 0) { - *_length = 0; - return bytesRead; - } - - *_length = bytesRead; - return B_OK; -} - - -static status_t -net_stack_readv(void *_cookie, off_t /*offset*/, const struct iovec *vecs, - size_t count, size_t *_length) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_readv(%p, (%p, %lu), %ld)\n", cookie, vecs, count, *_length); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - return sSocket->readv(cookie->socket, vecs, count, _length); -} - - -static status_t -net_stack_write(void *_cookie, off_t /*offset*/, const void *buffer, - size_t *_length) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_write(%p, %p, %ld)\n", cookie, buffer, *_length); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - ssize_t bytesWritten = sSocket->send(cookie->socket, NULL, buffer, *_length, - 0); - if (bytesWritten < 0) { - *_length = 0; - return bytesWritten; - } - - *_length = bytesWritten; - return B_OK; -} - - -static status_t -net_stack_writev(void *_cookie, off_t /*offset*/, const struct iovec *vecs, - size_t count, size_t *_length) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_writev(%p, (%p, %lu), %ld)\n", cookie, vecs, count, *_length); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - return sSocket->writev(cookie->socket, vecs, count, _length); -} - - -static status_t -net_stack_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_select(%p, %d, %ld, %p)\n", cookie, event, ref, sync); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - return sSocket->request_notification(cookie->socket, event, ref, sync); -} - - -static status_t -net_stack_deselect(void *_cookie, uint8 event, selectsync *sync) -{ - net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - - TRACE("net_stack_deselect(%p, %d, %p)\n", cookie, event, sync); - - if (cookie->socket == NULL) - return B_BAD_VALUE; - - return sSocket->cancel_notification(cookie->socket, event, sync); -} - - -// #pragma mark - driver - - -status_t -init_hardware(void) -{ - return B_OK; -} - - -status_t -init_driver(void) -{ - sInitializationSem = create_sem(1, "net stack init"); - if (sInitializationSem < B_OK) - return sInitializationSem; - - sInitializationStatus = B_NO_INIT; - return B_OK; -} - - -void -uninit_driver(void) -{ - delete_sem(sInitializationSem); -} - - -const char ** -publish_devices(void) -{ - static const char *devices[] = { - NET_STACK_DRIVER_DEVICE, - NULL - }; - - return devices; -} - - -device_hooks* -find_device(const char* device_name) -{ - static device_hooks hooks = { - net_stack_open, - net_stack_close, - net_stack_free_cookie, - net_stack_control, - net_stack_read, - net_stack_write, - net_stack_select, - net_stack_deselect, - net_stack_readv, - net_stack_writev, - }; - - return &hooks; -} diff --git a/src/add-ons/kernel/drivers/network/stack/userland_server.cpp b/src/add-ons/kernel/drivers/network/stack/userland_server.cpp deleted file mode 100644 index 0b9b0443e5..0000000000 --- a/src/add-ons/kernel/drivers/network/stack/userland_server.cpp +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright 2002-2006, Haiku, Inc. All Rights Reserved. - * This file may be used under the terms of the MIT License. - */ - -/*! - This file implements a very simple socket driver - that is intended to act as an interface to the networking stack when - it is loaded in userland, hosted by a net_server-like app. - The communication is slow, and could probably be much better, but it's - working, and that should be enough for now. -*/ - -#ifndef _KERNEL_MODE -# error "This module MUST be built as a kernel driver!" -#endif - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - - -#define DEBUG_PREFIX "userland_net_server: " -#define __out dprintf - -#define DEBUG 1 -#ifdef DEBUG - #define PRINT(x) { __out(DEBUG_PREFIX); __out x; } - #define REPORT_ERROR(status) __out(DEBUG_PREFIX "%s:%ld: %s\n",__FUNCTION__,__LINE__,strerror(status)); - #define RETURN_ERROR(err) { status_t _status = err; if (_status < B_OK) REPORT_ERROR(_status); return _status;} - #define FATAL(x) { __out(DEBUG_PREFIX); __out x; } - #define INFORM(x) { __out(DEBUG_PREFIX); __out x; } - #define FUNCTION() __out(DEBUG_PREFIX "%s()\n",__FUNCTION__); - #define FUNCTION_START(x) { __out(DEBUG_PREFIX "%s() ",__FUNCTION__); __out x; } -// #define FUNCTION() ; -// #define FUNCTION_START(x) ; - #define D(x) {x;}; -#else - #define PRINT(x) ; - #define REPORT_ERROR(status) ; - #define RETURN_ERROR(status) return status; - #define FATAL(x) { __out(DEBUG_PREFIX); __out x; } - #define INFORM(x) { __out(DEBUG_PREFIX); __out x; } - #define FUNCTION() ; - #define FUNCTION_START(x) ; - #define D(x) ; -#endif - -#define NET_SERVER_DRIVER_DEV "net/userland_server" - -/* wait one second when waiting on the stack */ -#define STACK_TIMEOUT 1000000LL - -#ifdef COMPILE_FOR_R5 - typedef status_t (*notify_select_event_function)(selectsync * sync, uint32 ref); -#else - typedef status_t (*notify_select_event_function)(selectsync * sync, uint32 ref, uint8 event); -#endif - - -// this struct will store one select() event to monitor per thread -typedef struct selecter { - struct selecter * next; - thread_id thread; - uint32 event; - selectsync * sync; - uint32 ref; -} selecter; - - -// the cookie we attach to each file descriptor opened on our driver entry -typedef struct { - port_id local_port; - port_id remote_port; - area_id area; - thread_id socket_thread; - - sem_id command_sem; - net_command *commands; - int32 command_index; - int32 nb_commands; - - sem_id selecters_lock; // protect the selecters linked-list - selecter * selecters; // the select()'ers lists (thread-aware) -} net_server_cookie; - -/* device hooks */ -static status_t net_server_open(const char *name, uint32 flags, void **cookie); -static status_t net_server_close(void *cookie); -static status_t net_server_free_cookie(void *cookie); -static status_t net_server_control(void *cookie, uint32 msg, void *data, size_t datalen); -static status_t net_server_read(void *cookie, off_t pos, void *data, size_t *datalen); -static status_t net_server_write(void *cookie, off_t pos, const void *data, size_t *datalen); -static status_t net_server_select(void *cookie, uint8 event, uint32 ref, selectsync *sync); -static status_t net_server_deselect(void *cookie, uint8 event, selectsync *sync); - -/* select() support */ -static int32 socket_event_listener(void *data); -static void on_socket_event(void *socket, uint32 event, void *cookie); -static status_t r5_notify_select_event(selectsync *sync, uint32 ref, uint8 event); - -/* command queue */ -static status_t init_connection(void **cookie); -static void shutdown_connection(net_server_cookie *nsc); -static net_command *get_command(net_server_cookie *nsc, int32 *index); -static status_t execute_command(net_server_cookie *nsc, uint32 op, void *data, uint32 length); - - -int32 api_version = B_CUR_DRIVER_API_VERSION; - -// by default, assert we can use kernel select() support -notify_select_event_function g_nse = notify_select_event; -thread_id sSocketEventThread = -1; -port_id sSocketEventPort = -1; - -static port_id sUserlandPort = -1; - - -// #pragma mark - driver - - -status_t -init_hardware(void) -{ - return B_OK; -} - - -status_t -init_driver(void) -{ - thread_id thread; - port_id port; - - FUNCTION(); - - port = create_port(32, "socket_event_listener"); - if (port < B_OK) - return port; - set_port_owner(port, B_SYSTEM_TEAM); - - thread = spawn_kernel_thread(socket_event_listener, "socket_event_listener", - B_NORMAL_PRIORITY, NULL); - if (thread < B_OK) { - delete_port(port); - return thread; - } - - sSocketEventThread = thread; - sSocketEventPort = port; - - return resume_thread(thread); -} - - -void -uninit_driver(void) -{ - FUNCTION(); - - delete_port(sSocketEventPort); - - status_t dummy; - wait_for_thread(sSocketEventThread, &dummy); -} - - -const char ** -publish_devices(void) -{ - FUNCTION(); - static const char *deviceNames[] = { - "net/userland_server", - NULL - }; - - return deviceNames; -} - - -device_hooks * -find_device(const char *deviceName) -{ - FUNCTION(); - device_hooks hooks = { - net_server_open, - net_server_close, - net_server_free_cookie, - net_server_control, - net_server_read, - net_server_write, - net_server_select, - net_server_deselect, - NULL, - NULL - }; - - return &hooks; -} - - -// #pragma mark - -//*****************************************************/ -// Device hooks -//*****************************************************/ - - -static status_t -net_server_open(const char *name, uint32 flags, void **cookie) -{ - net_server_cookie *nsc; - - status_t status = init_connection(cookie); - if (status < B_OK) - return status; - - nsc = *cookie; - - status = execute_command(nsc, NET_STACK_OPEN, &flags, sizeof(uint32)); - if (status < B_OK) - net_server_free_cookie(nsc); - - return status; -} - - -static status_t -net_server_close(void *cookie) -{ - net_server_cookie *nsc = cookie; - if (nsc == NULL) - return B_BAD_VALUE; - - // we don't care here if the stack isn't alive anymore - - // from the kernel's point of view, the device can always - // be closed - execute_command(nsc, NET_STACK_CLOSE, NULL, 0); - return B_OK; -} - - -static status_t -net_server_free_cookie(void *cookie) -{ - net_server_cookie *nsc = cookie; - if (nsc == NULL) - return B_BAD_VALUE; - - shutdown_connection(nsc); - return B_OK; -} - - -static status_t -net_server_control(void *cookie, uint32 op, void *data, size_t length) -{ - net_server_cookie *nsc = cookie; - struct stack_driver_args *args = data; - - //FUNCTION_START(("cookie = %p, op = %lx, data = %p, length = %ld\n", cookie, op, data, length)); - - if (nsc == NULL) - return B_BAD_VALUE; - - switch (op) { - case NET_STACK_SELECT: - // if we get this call via ioctl() we are obviously called from an - // R5 compatible libnet: we are using the r5 kernel select() call, - // So, we can't use the kernel notify_select_event(), but our own implementation! - g_nse = r5_notify_select_event; - return net_server_select(cookie, (args->u.select.ref & 0x0F), args->u.select.ref, args->u.select.sync); - - case NET_STACK_DESELECT: - return net_server_deselect(cookie, (args->u.select.ref & 0x0F), args->u.select.sync); - - default: - return execute_command(nsc, op, data, -1); - }; -} - - -static status_t -net_server_read(void *cookie, off_t pos, void *buffer, size_t *length) -{ - net_server_cookie *nsc = cookie; - struct stack_driver_args args; - int status; - - memset(&args, 0, sizeof(args)); - args.u.transfer.data = buffer; - args.u.transfer.datalen = *length; - - status = execute_command(nsc, NET_STACK_RECV, &args, sizeof(args)); - if (status > 0) { - *length = status; - return B_OK; - } - return status; -} - - -static status_t -net_server_write(void *cookie, off_t pos, const void *buffer, size_t *length) -{ - net_server_cookie *nsc = cookie; - struct stack_driver_args args; - int status; - - memset(&args, 0, sizeof(args)); - args.u.transfer.data = (void *) buffer; - args.u.transfer.datalen = *length; - - status = execute_command(nsc, NET_STACK_SEND, &args, sizeof(args)); - if (status > 0) { - *length = status; - return B_OK; - } - return status; -} - - -static status_t -net_server_select(void *cookie, uint8 event, uint32 ref, selectsync *sync) -{ - net_server_cookie *nsc = cookie; - struct notify_socket_event_args args; - selecter *s; - status_t status; - - FUNCTION_START(("cookie = %p, event = %d, ref = %lx, sync =%p\n", cookie, event, ref, sync)); - - s = (selecter *) malloc(sizeof(selecter)); - if (!s) - return B_NO_MEMORY; - - - // lock the selecters list - status = acquire_sem(nsc->selecters_lock); - if (status != B_OK) { - free(s); - return status; - }; - - s->thread = find_thread(NULL); // current thread id - s->event = event; - s->sync = sync; - s->ref = ref; - - // add it to selecters list - s->next = nsc->selecters; - nsc->selecters = s; - - // unlock the selecters list - release_sem(nsc->selecters_lock); - - // Tell the net_server to notify event(s) for this socket - memset(&args, 0, sizeof(args)); - args.notify_port = sSocketEventPort; - args.cookie = cookie;; - - return execute_command(nsc, NET_STACK_NOTIFY_SOCKET_EVENT, &args, sizeof(args)); -} - - -static status_t -net_server_deselect(void *cookie, uint8 event, selectsync *sync) -{ - net_server_cookie *nsc = cookie; - selecter *previous; - selecter *s; - thread_id current_thread; - status_t status; - - FUNCTION_START(("cookie = %p, event = %d, sync =%p\n", cookie, event, sync)); - - if (!nsc) - return B_BAD_VALUE; - - current_thread = find_thread(NULL); - - // lock the selecters list - status = acquire_sem(nsc->selecters_lock); - if (status != B_OK) - return status; - - previous = NULL; - s = nsc->selecters; - while (s) { - if (s->thread == current_thread && - s->event == event && s->sync == sync) - // selecter found! - break; - - previous = s; - s = s->next; - }; - - if (s != NULL) { - // remove it from selecters list - if (previous) - previous->next = s->next; - else - nsc->selecters = s->next; - free(s); - }; - - status = B_OK; - if (nsc->selecters == NULL) { - struct notify_socket_event_args args; - - // Selecters list is empty: no need to monitor socket events anymore - // Tell the net_server to stop notifying event(s) for this socket - memset(&args, 0, sizeof(args)); - args.notify_port = -1; // stop notifying - args.cookie = cookie; // for sanity check - status = execute_command(nsc, NET_STACK_NOTIFY_SOCKET_EVENT, &args, sizeof(args)); - }; - - // unlock the selecters list - release_sem(nsc->selecters_lock); - - return status; -} - - -// #pragma mark - -//*****************************************************/ -// select() support -//*****************************************************/ - -/* - This is started as separate thread at init_driver() time to wait for - socket event notification. - - One port to listen them all. - One port to find them. - One port to get them and in [r5_]notify_select_event() send them. - - Okay, I should stop watch this movie *now*. -*/ - -static int32 socket_event_listener(void *data) -{ - struct socket_event_data sed; - int32 msg; - ssize_t bytes; - - while(true) { - bytes = read_port(sSocketEventPort, &msg, &sed, sizeof(sed)); - if (bytes < B_OK) - return bytes; - - if (msg == NET_STACK_SOCKET_EVENT_NOTIFICATION) - // yep, we pass a NULL "socket" pointer here, but don't worry, we don't use anyway - on_socket_event(NULL, sed.event, sed.cookie); - }; - return 0; -} - - -static void on_socket_event(void *socket, uint32 event, void *cookie) -{ - net_server_cookie *nsc = cookie; - selecter *s; - - if (!nsc) - return; - - FUNCTION_START(("socket = %p, event = %ld, cookie = %p\n", socket, event, cookie)); - - // lock the selecters list - if (acquire_sem(nsc->selecters_lock) != B_OK) - return; - - s = nsc->selecters; - while (s) { - if (s->event == event) - // notify this selecter (thread/event pair) -#ifdef COMPILE_FOR_R5 - g_nse(s->sync, s->ref); -#else - g_nse(s->sync, s->ref, (uint8) event); -#endif - s = s->next; - }; - - // unlock the selecters list - release_sem(nsc->selecters_lock); - return; -} - - -/* - Under vanilla R5, we can't use the kernel notify_select_event(), - as select() kernel implementation is too buggy to be usefull. - So, here is our own notify_select_event() implementation, the driver-side pair - of the our libnet.so select() implementation... -*/ -static status_t r5_notify_select_event(selectsync *sync, uint32 ref, uint8 event) -{ - area_id area; - struct r5_selectsync *rss; - int fd; - - FUNCTION_START(("sync = %p, ref = %lx\n", sync, ref)); - - rss = NULL; - area = clone_area("r5_selectsync_area (driver)", (void **) &rss, - B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA, (area_id) sync); - if (area < B_OK) { -#if SHOW_INSANE_DEBUGGING - dprintf(LOGID "r5_notify_select_event: clone_area(%d) failed -> %d!\n", (area_id) sync, area); -#endif - return area; - }; - -#if SHOW_INSANE_DEBUGGING - dprintf(LOGID "r5_selectsync at %p (area %ld, clone from %ld):\n" - "lock %ld\n" - "wakeup %ld\n", rss, area, (area_id) sync, rss->lock, rss->wakeup); -#endif - - if (acquire_sem(rss->lock) != B_OK) - // if we can't (anymore?) lock the shared r5_selectsync, select() party is done - goto error; - - fd = ref >> 8; - switch (ref & 0xFF) { // event == ref & 0xFF ! - case B_SELECT_READ: - FD_SET(fd, &rss->rbits); - break; - case B_SELECT_WRITE: - FD_SET(fd, &rss->wbits); - break; - case B_SELECT_ERROR: - FD_SET(fd, &rss->ebits); - break; - }; - - // wakeup select() - release_sem(rss->wakeup); - - release_sem(rss->lock); - -error: - delete_area(area); - return B_ERROR; -} - - -// #pragma mark - - - -//*****************************************************/ -// The Command Queue -//*****************************************************/ - - -static net_command * -get_command(net_server_cookie *nsc, int32 *index) -{ - int32 i, count = 0; - net_command *command; - - while (count < nsc->nb_commands*2) { - i = atomic_add(&nsc->command_index,1) & (nsc->nb_commands - 1); - command = nsc->commands + i; - - if (command->op == 0) { - // command is free to use - *index = i; - return command; - } - count++; - } - return NULL; -} - - -static status_t -get_area_from_address(net_area_info *info, void *data) -{ - area_info areaInfo; - - if (data == NULL) - return B_OK; - - info->id = area_for(data); - if (info->id < B_OK) - return info->id; - - if (get_area_info(info->id,&areaInfo) != B_OK) - return B_BAD_VALUE; - - info->offset = areaInfo.address; - return B_OK; -} - - -static void -set_command_areas(net_command *command) -{ - struct stack_driver_args *args = (void *) command->data; - - if (args == NULL) - return; - - if (get_area_from_address(&command->area[0], args) < B_OK) - return; - - switch (command->op) { - case NET_STACK_GETSOCKOPT: - case NET_STACK_SETSOCKOPT: - get_area_from_address(&command->area[1], args->u.sockopt.optval); - break; - - case NET_STACK_CONNECT: - case NET_STACK_BIND: - case NET_STACK_GETSOCKNAME: - case NET_STACK_GETPEERNAME: - get_area_from_address(&command->area[1], args->u.sockaddr.addr); - break; - - case NET_STACK_RECV: - case NET_STACK_SEND: - get_area_from_address(&command->area[1], args->u.transfer.data); - get_area_from_address(&command->area[2], args->u.transfer.addr); - break; - - case NET_STACK_RECVFROM: - case NET_STACK_SENDTO: { - struct msghdr *mh = (void *) args; - get_area_from_address(&command->area[1],mh->msg_name); - get_area_from_address(&command->area[2],mh->msg_iov); - get_area_from_address(&command->area[3],mh->msg_control); - break; - } - - case NET_STACK_ACCEPT: - /* accept_args.cookie is always in the address space of the server */ - get_area_from_address(&command->area[1], args->u.accept.addr); - break; - - case NET_STACK_SYSCTL: - get_area_from_address(&command->area[1], args->u.sysctl.name); - get_area_from_address(&command->area[2], args->u.sysctl.oldp); - get_area_from_address(&command->area[3], args->u.sysctl.oldlenp); - get_area_from_address(&command->area[4], args->u.sysctl.newp); - break; - - case NET_STACK_CONTROL_NET_MODULE: - // TODO! - break; - - case OSIOCGIFCONF: - case SIOCGIFCONF: { - struct ifconf *ifc = (void *) args; - - get_area_from_address(&command->area[1], ifc->ifc_buf); - break; - } - } -} - - -static status_t -execute_command(net_server_cookie *nsc, uint32 op, void *data, uint32 length) -{ - uint32 command_index; - net_command *command = get_command(nsc, (long *) &command_index); - int32 max_tries = 200; - status_t status; - ssize_t bytes; - - if (command == NULL) { - FATAL(("execute: command queue is full\n")); - return B_ERROR; - } - - memset(command, 0, sizeof(net_command)); - - command->op = op; - command->data = data; - set_command_areas(command); - - bytes = write_port(nsc->remote_port, command_index, NULL, 0); - if (bytes < B_OK) { - FATAL(("execute %ld: couldn't contact stack (id = %ld): %s\n",op, nsc->remote_port, strerror(bytes))); - return bytes; - } - - // if we're closing the connection, there is no need to - // wait for a result - if (op == NET_STACK_CLOSE) - return B_OK; - - while (true) { - // wait until we get the results back from our command - if ((status = acquire_sem_etc(nsc->command_sem, 1, B_CAN_INTERRUPT, 0)) == B_OK) { - if (command->op != 0) { - if (--max_tries <= 0) { - FATAL(("command is not freed after 200 tries!\n")); - return B_ERROR; - } - release_sem(nsc->command_sem); - continue; - } - return command->result; - } - FATAL(("command couldn't be executed: %s\n", strerror(status))); - if (status == B_INTERRUPTED) - // Signaling our net_server counterpart, so his socket thread awake too... - send_signal_etc(nsc->socket_thread, SIGINT, 0); - return status; - } -} - - -static status_t -init_connection(void **cookie) -{ - net_connection connection; - ssize_t bytes; - uint32 msg; - - net_server_cookie *nsc = (net_server_cookie *) malloc(sizeof(net_server_cookie)); - if (nsc == NULL) - return B_NO_MEMORY; - - // create a new port and get a connection from the stack - - nsc->local_port = create_port(CONNECTION_QUEUE_LENGTH, "net_driver connection"); - if (nsc->local_port < B_OK) { - FATAL(("open: couldn't create port: %s\n", strerror(nsc->local_port))); - free(cookie); - return B_ERROR; - } - set_port_owner(nsc->local_port, B_SYSTEM_TEAM); - - bytes = write_port(sUserlandPort, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id)); - if (bytes == B_BAD_PORT_ID) { - sUserlandPort = find_port(NET_STACK_PORTNAME); - PRINT(("try to get net_server's port id: %ld\n", sUserlandPort)); - bytes = write_port(sUserlandPort, NET_STACK_NEW_CONNECTION, &nsc->local_port, sizeof(port_id)); - } - if (bytes < B_OK) { - FATAL(("open: couldn't contact stack: %s\n",strerror(bytes))); - delete_port(nsc->local_port); - free(nsc); - return bytes; - } - - bytes = read_port_etc(nsc->local_port, &msg, &connection, sizeof(net_connection), B_TIMEOUT,STACK_TIMEOUT); - if (bytes < B_OK) { - FATAL(("open: didn't hear back from stack: %s\n",strerror(bytes))); - delete_port(nsc->local_port); - free(nsc); - return bytes; - } - if (msg != NET_STACK_NEW_CONNECTION) { - FATAL(("open: received wrong answer: %ld\n",msg)); - delete_port(nsc->local_port); - free(nsc); - return B_ERROR; - } - - // set up communication channels - - // ToDo: close server connection if anything fails - // -> could also be done by the server, if it doesn't receive NET_STACK_OPEN - - nsc->remote_port = connection.port; - nsc->command_sem = connection.commandSemaphore; - nsc->area = clone_area("net connection buffer", (void **) &nsc->commands, - B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, connection.area); - if (nsc->area < B_OK) { - status_t err; - FATAL(("couldn't clone command queue: %s\n", strerror(nsc->area))); - err = nsc->area; - delete_port(nsc->local_port); - free(nsc); - return err; - } - - nsc->socket_thread = connection.socket_thread; - nsc->nb_commands = connection.numCommands; - nsc->command_index = 0; - nsc->selecters = NULL; - - nsc->selecters_lock = create_sem(1, "socket_selecters_lock"); - if (nsc->selecters_lock < B_OK) { - status_t err; - FATAL(("couldn't create socket_selecters_lock semaphore: %s\n", strerror(nsc->selecters_lock))); - err = nsc->selecters_lock; - delete_port(nsc->local_port); - delete_area(nsc->area); - free(nsc); - return err; - } - - *cookie = nsc; - return B_OK; -} - - -static void -shutdown_connection(net_server_cookie *nsc) -{ - selecter *s; - - delete_area(nsc->area); - delete_port(nsc->local_port); - - // free the selecters list - delete_sem(nsc->selecters_lock); - s = nsc->selecters; - while (s) { - selecter * tmp = s; - s = s->next; - free(tmp); - }; - - free(nsc); -} - diff --git a/src/add-ons/kernel/network/Jamfile b/src/add-ons/kernel/network/Jamfile index 99f91268af..25e6f30907 100644 --- a/src/add-ons/kernel/network/Jamfile +++ b/src/add-ons/kernel/network/Jamfile @@ -3,5 +3,4 @@ SubDir HAIKU_TOP src add-ons kernel network ; SubInclude HAIKU_TOP src add-ons kernel network datalink_protocols ; SubInclude HAIKU_TOP src add-ons kernel network devices ; SubInclude HAIKU_TOP src add-ons kernel network protocols ; -SubInclude HAIKU_TOP src add-ons kernel network socket ; SubInclude HAIKU_TOP src add-ons kernel network stack ; diff --git a/src/add-ons/kernel/network/socket/Jamfile b/src/add-ons/kernel/network/socket/Jamfile deleted file mode 100644 index cd81fa4585..0000000000 --- a/src/add-ons/kernel/network/socket/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel network socket ; - -UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; -UsePrivateHeaders net ; - -KernelAddon socket : - socket.cpp -; diff --git a/src/add-ons/kernel/network/socket/socket.cpp b/src/add-ons/kernel/network/socket/socket.cpp deleted file mode 100644 index d2d7e770eb..0000000000 --- a/src/add-ons/kernel/network/socket/socket.cpp +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2007, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Axel Dörfler, axeld@pinc-software.de - */ - -/*! - The kernel socket API directly forwards all requests into the stack - via the networking stack driver. -*/ - -#include - -#include - -#include -#include -#include - - -int -socket(int family, int type, int protocol) -{ - int socket = open(NET_STACK_DRIVER_PATH, O_RDWR); - if (socket < 0) - return -1; - - socket_args args; - args.family = family; - args.type = type; - args.protocol = protocol; - - if (ioctl(socket, NET_STACK_SOCKET, &args, sizeof(args)) < 0) { - close(socket); - return -1; - } - - return socket; -} - - -int -bind(int socket, const struct sockaddr *address, socklen_t addressLength) -{ - sockaddr_args args; - args.address = const_cast(address); - args.address_length = addressLength; - - return ioctl(socket, NET_STACK_BIND, &args, sizeof(args)); -} - - -int -shutdown(int socket, int how) -{ - return ioctl(socket, NET_STACK_SHUTDOWN, (void *)how, 0); -} - - -int -connect(int socket, const struct sockaddr *address, socklen_t addressLength) -{ - sockaddr_args args; - args.address = const_cast(address); - args.address_length = addressLength; - - return ioctl(socket, NET_STACK_CONNECT, &args, sizeof(args)); -} - - -int -listen(int socket, int backlog) -{ - return ioctl(socket, NET_STACK_LISTEN, (void *)backlog, 0); -} - - -int -accept(int socket, struct sockaddr *address, socklen_t *_addressLength) -{ - int acceptSocket = open(NET_STACK_DRIVER_PATH, O_RDWR); - if (acceptSocket < 0) - return -1; - - accept_args args; - args.accept_socket = acceptSocket; - args.address = address; - args.address_length = _addressLength ? *_addressLength : 0; - - if (ioctl(socket, NET_STACK_ACCEPT, &args, sizeof(args)) < 0) { - close(acceptSocket); - return -1; - } - - if (_addressLength != NULL) - *_addressLength = args.address_length; - - return acceptSocket; -} - - -ssize_t -recv(int socket, void *data, size_t length, int flags) -{ - message_args args; - args.data = data; - args.length = length; - args.flags = flags; - args.header = NULL; - - return ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args)); -} - - -ssize_t -recvfrom(int socket, void *data, size_t length, int flags, - struct sockaddr *address, socklen_t *_addressLength) -{ - message_args args; - msghdr header; - - memset(&header, 0, sizeof(header)); - - args.data = data; - args.length = length; - args.flags = flags; - args.header = &header; - - header.msg_name = (char *)address; - header.msg_namelen = _addressLength ? *_addressLength : 0; - - ssize_t bytesReceived = ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args)); - if (bytesReceived < 0) - return -1; - - if (_addressLength != NULL) - *_addressLength = header.msg_namelen; - - return bytesReceived; -} - - -ssize_t -recvmsg(int socket, struct msghdr *message, int flags) -{ - message_args args; - - if (message == NULL || (message->msg_iovlen > 0 && message->msg_iov == NULL)) - return B_BAD_VALUE; - - args.header = message; - args.flags = flags; - - if (message->msg_iovlen > 0) { - args.data = message->msg_iov[0].iov_base; - args.length = message->msg_iov[0].iov_len; - } else { - args.data = NULL; - args.length = 0; - } - - return ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args)); -} - - -ssize_t -send(int socket, const void *data, size_t length, int flags) -{ - message_args args; - args.data = const_cast(data); - args.length = length; - args.flags = flags; - args.header = NULL; - - return ioctl(socket, NET_STACK_SEND, &args, sizeof(args)); -} - - -ssize_t -sendto(int socket, const void *data, size_t length, int flags, - const struct sockaddr *address, socklen_t addressLength) -{ - message_args args; - msghdr header; - memset(&header, 0, sizeof(header)); - - args.data = const_cast(data); - args.length = length; - args.flags = flags; - args.header = &header; - header.msg_name = (char *)const_cast(address); - header.msg_namelen = addressLength; - - return ioctl(socket, NET_STACK_SEND, &args, sizeof(args)); -} - - -ssize_t -sendmsg(int socket, const struct msghdr *message, int flags) -{ - message_args args; - - if (message == NULL || (message->msg_iovlen > 0 && message->msg_iov == NULL)) - return B_BAD_VALUE; - - args.header = (msghdr *)message; - args.flags = flags; - - if (message->msg_iovlen > 0) { - args.data = message->msg_iov[0].iov_base; - args.length = message->msg_iov[0].iov_len; - } else { - args.data = NULL; - args.length = 0; - } - - return ioctl(socket, NET_STACK_SEND, &args, sizeof(args)); -} - - -int -getsockopt(int socket, int level, int option, void *value, socklen_t *_length) -{ - sockopt_args args; - args.level = level; - args.option = option; - args.value = value; - args.length = _length ? *_length : 0; - - if (ioctl(socket, NET_STACK_GETSOCKOPT, &args, sizeof(args)) < 0) - return -1; - - if (_length) - *_length = args.length; - - return 0; -} - - -int -setsockopt(int socket, int level, int option, const void *value, socklen_t length) -{ - sockopt_args args; - args.level = level; - args.option = option; - args.value = const_cast(value); - args.length = length; - - return ioctl(socket, NET_STACK_SETSOCKOPT, &args, sizeof(args)); -} - - -int -getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength) -{ - sockaddr_args args; - args.address = address; - args.address_length = _addressLength ? *_addressLength : 0; - - if (ioctl(socket, NET_STACK_GETPEERNAME, &args, sizeof(args)) < 0) - return -1; - - if (_addressLength != NULL) - *_addressLength = args.address_length; - - return 0; -} - - -int -getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength) -{ - sockaddr_args args; - args.address = address; - args.address_length = _addressLength ? *_addressLength : 0; - - if (ioctl(socket, NET_STACK_GETSOCKNAME, &args, sizeof(args)) < 0) - return -1; - - if (_addressLength != NULL) - *_addressLength = args.address_length; - - return 0; -} - - -int -sockatmark(int socket) -{ - // TODO: implement me! - return -1; -} - - -int -socketpair(int family, int type, int protocol, int socketVector[2]) -{ - socketVector[0] = socket(family, type, protocol); - if (socketVector[0] < 0) - return -1; - - socketVector[1] = socket(family, type, protocol); - if (socketVector[1] < 0) - goto err1; - - socketpair_args args; - args.second_socket = socketVector[1]; - - if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0) - goto err2; - - return 0; - -err2: - close(socketVector[1]); -err1: - close(socketVector[0]); - return -1; -} - - -// #pragma mark - - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - - default: - return B_ERROR; - } -} - - -static socket_module_info sSocketModule = { - { - B_SOCKET_MODULE_NAME, - 0, - std_ops - }, - - accept, - bind, - connect, - getpeername, - getsockname, - getsockopt, - listen, - recv, - recvfrom, - recvmsg, - send, - sendmsg, - sendto, - setsockopt, - shutdown, - socket, - sockatmark, - socketpair, -}; - -module_info *modules[] = { - (module_info *)&sSocketModule, - NULL -};