diff --git a/src/add-ons/kernel/drivers/network/stack/Jamfile b/src/add-ons/kernel/drivers/network/stack/Jamfile index 43be58feca..f3b9a8f2e5 100644 --- a/src/add-ons/kernel/drivers/network/stack/Jamfile +++ b/src/add-ons/kernel/drivers/network/stack/Jamfile @@ -16,11 +16,11 @@ R5KernelAddon net_server_driver : kernel drivers bin : # ; # b) Kernelland stack version: -# + R5KernelAddon net_stack_driver : kernel drivers bin : net_stack_driver.c ; -# + # For OpenBeOS we should be building the kernel stack driver objects this way. #KernelObjects # net_stack_driver.c diff --git a/src/add-ons/kernel/drivers/network/stack/net_server_driver.c b/src/add-ons/kernel/drivers/network/stack/net_server_driver.c index d2177e82a5..d9c7aee012 100644 --- a/src/add-ons/kernel/drivers/network/stack/net_server_driver.c +++ b/src/add-ons/kernel/drivers/network/stack/net_server_driver.c @@ -102,7 +102,7 @@ typedef struct { sem_id selecters_lock; // protect the selecters linked-list selecter * selecters; // the select()'ers lists (thread-aware) -} net_stack_cookie; +} net_server_cookie; //*****************************************************/ @@ -110,16 +110,16 @@ typedef struct { //*****************************************************/ /* device hooks */ -static status_t net_stack_open(const char * name, uint32 flags, void ** cookie); -static status_t net_stack_close(void * cookie); -static status_t net_stack_free_cookie(void * cookie); -static status_t net_stack_control(void * cookie, uint32 msg,void * data, size_t datalen); -static status_t net_stack_read(void * cookie, off_t pos, void * data, size_t * datalen); -static status_t net_stack_write(void * cookie, off_t pos, const void * data, size_t * datalen); -static status_t net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync); -static status_t net_stack_deselect(void *cookie, uint8 event, selectsync *sync); -// static status_t net_stack_readv(void * cookie, off_t pos, const iovec * vec, size_t count, size_t * len); -// static status_t net_stack_writev(void * cookie, off_t pos, const iovec * vec, size_t count, size_t * len); +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); +// static status_t net_server_readv(void * cookie, off_t pos, const iovec * vec, size_t count, size_t * len); +// static status_t net_server_writev(void * cookie, off_t pos, const iovec * vec, size_t count, size_t * len); /* select() support */ static int32 socket_event_listener(void * data); @@ -128,30 +128,33 @@ static void r5_notify_select_event(selectsync *sync, uint32 ref); /* command queue */ static status_t init_connection(void **cookie); -static void shutdown_connection(net_stack_cookie *nsc); -static net_command *get_command(net_stack_cookie *nsc, int32 *index); -static status_t execute_command(net_stack_cookie *nsc, int32 op, void *data, uint32 length); +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, int32 op, void *data, uint32 length); /* * Global variables * ---------------- */ +#define NET_SERVER_DRIVER_DEV "net/server" +#define NET_SERVER_DRIVER_PATH "/dev/" ## NET_SERVER_DRIVER_DEV + const char * g_device_names_list[] = { "net/server", NULL }; -device_hooks g_net_stack_driver_hooks = +device_hooks g_net_server_driver_hooks = { - net_stack_open, /* -> open entry point */ - net_stack_close, /* -> close entry point */ - net_stack_free_cookie, /* -> free entry point */ - net_stack_control, /* -> control entry point */ - net_stack_read, /* -> read entry point */ - net_stack_write, /* -> write entry point */ - net_stack_select, /* -> select entry point */ - net_stack_deselect, /* -> deselect entry point */ + net_server_open, /* -> open entry point */ + net_server_close, /* -> close entry point */ + net_server_free_cookie, /* -> free entry point */ + net_server_control, /* -> control entry point */ + net_server_read, /* -> read entry point */ + net_server_write, /* -> write entry point */ + net_server_select, /* -> select entry point */ + net_server_deselect, /* -> deselect entry point */ NULL, /* -> readv entry pint */ NULL /* -> writev entry point */ }; @@ -230,7 +233,7 @@ _EXPORT device_hooks * find_device(const char *deviceName) { FUNCTION(); - return &g_net_stack_driver_hooks; + return &g_net_server_driver_hooks; } @@ -241,9 +244,9 @@ find_device(const char *deviceName) static status_t -net_stack_open(const char *name, uint32 flags, void ** cookie) +net_server_open(const char *name, uint32 flags, void **cookie) { - net_stack_cookie * nsc; + net_server_cookie *nsc; status_t status = init_connection(cookie); if (status < B_OK) @@ -253,16 +256,16 @@ net_stack_open(const char *name, uint32 flags, void ** cookie) status = execute_command(nsc, NET_STACK_OPEN, &flags, sizeof(uint32)); if (status < B_OK) - net_stack_free_cookie(nsc); + net_server_free_cookie(nsc); return status; } static status_t -net_stack_close(void *cookie) +net_server_close(void *cookie) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + net_server_cookie *nsc = cookie; if (nsc == NULL) return B_BAD_VALUE; @@ -275,9 +278,9 @@ net_stack_close(void *cookie) static status_t -net_stack_free_cookie(void *cookie) +net_server_free_cookie(void *cookie) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + net_server_cookie *nsc = cookie; if (nsc == NULL) return B_BAD_VALUE; @@ -287,9 +290,10 @@ net_stack_free_cookie(void *cookie) static status_t -net_stack_control(void *cookie, uint32 op, void *data, size_t length) +net_server_control(void *cookie, uint32 op, void *data, size_t length) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + 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)); @@ -297,19 +301,16 @@ net_stack_control(void *cookie, uint32 op, void *data, size_t length) return B_BAD_VALUE; switch (op) { - case NET_STACK_SELECT: { - struct select_args *args = (struct select_args *) data; - + 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_stack_select(cookie, (args->ref & 0x0F), args->ref, args->sync); - } - case NET_STACK_DESELECT: { - struct select_args * args = (struct select_args *) data; - return net_stack_deselect(cookie, (args->ref & 0x0F), args->sync); - } + 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); }; @@ -317,15 +318,15 @@ net_stack_control(void *cookie, uint32 op, void *data, size_t length) static status_t -net_stack_read(void *cookie, off_t pos, void *buffer, size_t *length) +net_server_read(void *cookie, off_t pos, void *buffer, size_t *length) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; - struct data_xfer_args args; + net_server_cookie *nsc = cookie; + struct stack_driver_args args; int status; memset(&args, 0, sizeof(args)); - args.data = buffer; - args.datalen = *length; + args.u.transfer.data = buffer; + args.u.transfer.datalen = *length; status = execute_command(nsc, NET_STACK_RECV, &args, sizeof(args)); if (status > 0) { @@ -337,15 +338,15 @@ net_stack_read(void *cookie, off_t pos, void *buffer, size_t *length) static status_t -net_stack_write(void *cookie, off_t pos, const void *buffer, size_t *length) +net_server_write(void *cookie, off_t pos, const void *buffer, size_t *length) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; - struct data_xfer_args args; + net_server_cookie *nsc = cookie; + struct stack_driver_args args; int status; memset(&args, 0, sizeof(args)); - args.data = (void *) buffer; - args.datalen = *length; + args.u.transfer.data = (void *) buffer; + args.u.transfer.datalen = *length; status = execute_command(nsc, NET_STACK_SEND, &args, sizeof(args)); if (status > 0) { @@ -357,11 +358,11 @@ net_stack_write(void *cookie, off_t pos, const void *buffer, size_t *length) static status_t -net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync) +net_server_select(void *cookie, uint8 event, uint32 ref, selectsync *sync) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + net_server_cookie *nsc = cookie; struct notify_socket_event_args args; - selecter * s; + selecter *s; status_t status; FUNCTION_START(("cookie = %p, event = %d, ref = %lx, sync =%p\n", cookie, event, ref, sync)); @@ -400,11 +401,11 @@ net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync) static status_t -net_stack_deselect(void *cookie, uint8 event, selectsync *sync) +net_server_deselect(void *cookie, uint8 event, selectsync *sync) { - net_stack_cookie *nsc = (net_stack_cookie *) cookie; - selecter * previous; - selecter * s; + net_server_cookie *nsc = cookie; + selecter *previous; + selecter *s; thread_id current_thread; status_t status; @@ -476,7 +477,7 @@ net_stack_deselect(void *cookie, uint8 event, selectsync *sync) Okay, I should stop watch this movie *now*. */ -static int32 socket_event_listener(void * data) +static int32 socket_event_listener(void *data) { struct socket_event_data sed; int32 msg; @@ -495,10 +496,10 @@ static int32 socket_event_listener(void * data) } -static void on_socket_event(void * socket, uint32 event, void * cookie) +static void on_socket_event(void *socket, uint32 event, void *cookie) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; - selecter * s; + net_server_cookie *nsc = cookie; + selecter *s; if (!nsc) return; @@ -529,10 +530,10 @@ static void on_socket_event(void * socket, uint32 event, void * cookie) So, here is our own notify_select_event() implementation, the driver-side pair of the our libnet.so select() implementation... */ -static void r5_notify_select_event(selectsync * sync, uint32 ref) +static void r5_notify_select_event(selectsync *sync, uint32 ref) { area_id area; - struct r5_selectsync * rss; + struct r5_selectsync *rss; int fd; FUNCTION_START(("sync = %p, ref = %lx\n", sync, ref)); @@ -589,7 +590,7 @@ error: static net_command * -get_command(net_stack_cookie *nsc, int32 *index) +get_command(net_server_cookie *nsc, int32 *index) { int32 i, count = 0; net_command *command; @@ -632,77 +633,60 @@ get_area_from_address(net_area_info *info, void *data) static void set_command_areas(net_command *command) { - void *data = command->data; - if (data == NULL) + struct stack_driver_args *args = (void *) command->data; + + if (args == NULL) return; - if (get_area_from_address(&command->area[0],data) < B_OK) + if (get_area_from_address(&command->area[0], args) < B_OK) return; switch (command->op) { case NET_STACK_GETSOCKOPT: case NET_STACK_SETSOCKOPT: - { - struct sockopt_args *sockopt = (struct sockopt_args *)data; - - get_area_from_address(&command->area[1],sockopt->optval); + 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: - { - struct sockaddr_args *args = (struct sockaddr_args *)data; - - get_area_from_address(&command->area[1],args->addr); + get_area_from_address(&command->area[1], args->u.sockaddr.addr); break; - } case NET_STACK_RECV: case NET_STACK_SEND: - { - struct data_xfer_args *args = (struct data_xfer_args *)data; - get_area_from_address(&command->area[1],args->data); - get_area_from_address(&command->area[2],args->addr); + 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 = (struct msghdr *)data; + 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: - { - struct accept_args *args = (struct accept_args *)data; - /* accept_args.cookie is always in the address space of the server */ - get_area_from_address(&command->area[1],args->addr); - 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: - { - struct sysctl_args *sysctl = (struct sysctl_args *)data; - - get_area_from_address(&command->area[1],sysctl->name); - get_area_from_address(&command->area[2],sysctl->oldp); - get_area_from_address(&command->area[3],sysctl->oldlenp); - get_area_from_address(&command->area[4],sysctl->newp); + 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; - } /* TODO/FIXME: phoudoin: where are these opcodes defined!?! case OSIOCGIFCONF: case SIOCGIFCONF: { - struct ifconf *ifc = (struct ifconf *)data; + struct ifconf *ifc = data; get_area_from_address(&command->area[1],ifc->ifc_buf); break; @@ -713,7 +697,7 @@ set_command_areas(net_command *command) static status_t -execute_command(net_stack_cookie *nsc, int32 op, void *data, uint32 length) +execute_command(net_server_cookie *nsc, int32 op, void *data, uint32 length) { uint32 command_index; net_command *command = get_command(nsc, (long *) &command_index); @@ -769,7 +753,7 @@ init_connection(void **cookie) ssize_t bytes; int32 msg; - net_stack_cookie * nsc = (net_stack_cookie *) malloc(sizeof(net_stack_cookie)); + net_server_cookie *nsc = (net_server_cookie *) malloc(sizeof(net_server_cookie)); if (nsc == NULL) return B_NO_MEMORY; @@ -849,9 +833,9 @@ init_connection(void **cookie) static void -shutdown_connection(net_stack_cookie *nsc) +shutdown_connection(net_server_cookie *nsc) { - selecter * s; + selecter *s; delete_area(nsc->area); delete_port(nsc->local_port); diff --git a/src/add-ons/kernel/drivers/network/stack/net_stack_driver.c b/src/add-ons/kernel/drivers/network/stack/net_stack_driver.c index 5fb5ab246c..b9b0a536c6 100644 --- a/src/add-ons/kernel/drivers/network/stack/net_stack_driver.c +++ b/src/add-ons/kernel/drivers/network/stack/net_stack_driver.c @@ -366,55 +366,46 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le // TODO: This is where the open flags need to be addressed return err; } - case NET_STACK_ASSOCIATE_SOCKET: - nsc->socket = args->u.associate.socket; + case NET_STACK_GET_COOKIE: { + /* this is needed by accept() call, allowing libnet.so accept() to pass back + * in NET_STACK_ACCEPT opcode the cookie (aka the net_stack_cookie!) + * of the filedescriptor to use for the new accepted socket + */ + + *((void **) data) = cookie; return B_OK; + } }; } else { switch (op) { case NET_STACK_CONNECT: return core->socket_connect(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen); + case NET_STACK_SHUTDOWN: + return core->socket_shutdown(nsc->socket, args->u.integer); + case NET_STACK_BIND: return core->socket_bind(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen); case NET_STACK_LISTEN: // backlog to set - return core->socket_listen(nsc->socket, args->u.integer.value); + return core->socket_listen(nsc->socket, args->u.integer); case NET_STACK_ACCEPT: { - int fd; - struct socket *s; - struct associate_socket_args associate; - - err = core->socket_accept(nsc->socket, &s, (void *) args->u.sockaddr.addr, &args->u.sockaddr.addrlen); - if (err < 0) - return err; - - // Okay, we have a new socket, but it should be a file descriptor too: - fd = open(NET_STACK_DRIVER_PATH, O_RDWR); - if (fd < 0) { - core->socket_close(s); - return fd; - }; - - associate.socket = s; - err = ioctl(fd, NET_STACK_ASSOCIATE_SOCKET, &associate, sizeof(associate)); - if (err < 0) { - core->socket_close(s); - close(fd); - return err; - }; - - return fd; + /* args->u.accept.cookie == net_stack_cookie of the already opened fd + * in libnet.so accept() call to bind to newly accepted socket + */ + + net_stack_cookie *ansc = args->u.accept.cookie; + return core->socket_accept(nsc->socket, &ansc->socket, (void *)args->u.accept.addr, &args->u.accept.addrlen); } case NET_STACK_SEND: // TODO: flags gets ignored here... - return net_stack_write(cookie, 0, args->u.xfer.data, &args->u.xfer.datalen); + return net_stack_write(cookie, 0, args->u.transfer.data, &args->u.transfer.datalen); case NET_STACK_RECV: // TODO: flags gets ignored here... - return net_stack_read(cookie, 0, args->u.xfer.data, &args->u.xfer.datalen); + return net_stack_read(cookie, 0, args->u.transfer.data, &args->u.transfer.datalen); case NET_STACK_RECVFROM: { struct msghdr * mh = (struct msghdr *) data; @@ -454,7 +445,7 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le case NET_STACK_GETPEERNAME: return core->socket_getpeername(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen); - + case B_SET_BLOCKING_IO: nsc->open_flags &= ~O_NONBLOCK; return B_OK; diff --git a/src/add-ons/kernel/network/core/core.c b/src/add-ons/kernel/network/core/core.c index 3b0ea82f74..666bddcc24 100644 --- a/src/add-ons/kernel/network/core/core.c +++ b/src/add-ons/kernel/network/core/core.c @@ -187,7 +187,8 @@ struct core_module_info core_info = { socket_getsockopt, socket_getpeername, socket_getsockname, - socket_set_event_callback + socket_set_event_callback, + socket_shutdown }; static int32 if_thread(void *data)