From a91f266ff3a7f29b153107eec36cadd284deece2 Mon Sep 17 00:00:00 2001 From: Philippe Houdoin Date: Thu, 19 Jun 2003 01:02:50 +0000 Subject: [PATCH] Hide the accept() trick more deeper: now the stack driver manage the trick himself. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3572 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../drivers/network/stack/net_stack_driver.c | 266 +++++++++--------- src/kits/network/libnet/socket.c | 36 +-- 2 files changed, 138 insertions(+), 164 deletions(-) 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 1e30cc1cba..5fb5ab246c 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 @@ -162,7 +162,7 @@ _EXPORT int32 api_version = B_CUR_DRIVER_API_VERSION; _EXPORT status_t init_hardware(void) { bool safemode = false; - void * sfmptr; + void *sfmptr; #if SERIAL_DEBUGGING // XXX - switch on/off at top of file... @@ -266,11 +266,9 @@ _EXPORT device_hooks * find_device(const char* device_name) */ // the network stack functions - mainly just pass throughs... -static status_t net_stack_open(const char * name, - uint32 flags, - void ** cookie) +static status_t net_stack_open(const char *name, uint32 flags, void **cookie) { - net_stack_cookie * nsc; + net_stack_cookie *nsc; nsc = (net_stack_cookie *) malloc(sizeof(*nsc)); if (!nsc) @@ -300,7 +298,7 @@ static status_t net_stack_open(const char * name, static status_t net_stack_close(void *cookie) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + net_stack_cookie *nsc = cookie; int rv; #if SHOW_INSANE_DEBUGGING @@ -320,8 +318,8 @@ static status_t net_stack_close(void *cookie) static status_t net_stack_free_cookie(void *cookie) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; - selecter * s; + net_stack_cookie *nsc = cookie; + selecter *s; #if SHOW_INSANE_DEBUGGING dprintf(LOGID "net_stack_free_cookie(%p)\n", cookie); @@ -331,7 +329,7 @@ static status_t net_stack_free_cookie(void *cookie) delete_sem(nsc->selecters_lock); s = nsc->selecters; while (s) { - selecter * tmp = s; + selecter *tmp = s; s = s->next; free(tmp); }; @@ -343,9 +341,11 @@ static status_t net_stack_free_cookie(void *cookie) -static status_t net_stack_control(void *cookie, uint32 op, void * data, size_t len) +static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t len) { - net_stack_cookie * nsc = (net_stack_cookie *) cookie; + net_stack_cookie *nsc = cookie; + struct stack_driver_args *args = data; + int err; #if SHOW_INSANE_DEBUGGING dprintf(LOGID "net_stack_control(%p, 0x%lX, %p, %ld)\n", cookie, op, data, len); @@ -355,136 +355,130 @@ static status_t net_stack_control(void *cookie, uint32 op, void * data, size_t l keep_driver_loaded(); #endif - switch (op) { - case NET_STACK_SOCKET: { - struct socket_args * args = (struct socket_args *) data; - int rv; + if (! nsc->socket) { + switch (op) { + case NET_STACK_SOCKET: { - // okay, now try to open a real socket behind this fd/net_stack_cookie pair - rv = core->socket_init(&nsc->socket); - if (rv == 0) - rv = core->socket_create(nsc->socket, args->family, args->type, args->proto); - // TODO: This is where the open flags need to be addressed - return rv; - } - case NET_STACK_CONNECT: { - struct sockaddr_args * args = (struct sockaddr_args *) data; - // args->addr == sockaddr to connect to - return core->socket_connect(nsc->socket, (caddr_t) args->addr, args->addrlen); - } - case NET_STACK_BIND: { - struct sockaddr_args * args = (struct sockaddr_args *) data; - // args->addr == sockaddr to try and bind to - return core->socket_bind(nsc->socket, (caddr_t) args->addr, args->addrlen); - } - case NET_STACK_LISTEN: { - struct int_args * args = (struct int_args *) data; - // args->value == backlog to set - return core->socket_listen(nsc->socket, args->value); - } - case NET_STACK_GET_COOKIE: { - /* this is needed by accept() call, to be able 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; - } - case NET_STACK_ACCEPT: { - struct accept_args * args = (struct accept_args *) data; - net_stack_cookie * ansc = (net_stack_cookie *) args->cookie; - /* args->cookie == net_stack_cookie * of the already opened fd to use to the - * newly accepted socket - */ - return core->socket_accept(nsc->socket, &ansc->socket, (void *)args->addr, &args->addrlen); - } - case NET_STACK_SEND: { - struct data_xfer_args * args = (struct data_xfer_args *) data; - // TODO: flags gets ignored here... - return net_stack_write(cookie, 0, args->data, &args->datalen); - } - case NET_STACK_RECV: { - struct data_xfer_args * args = (struct data_xfer_args *) data; - // TODO: flags gets ignored here... - return net_stack_read(cookie, 0, args->data, &args->datalen); - } - case NET_STACK_RECVFROM: { - struct msghdr * mh = (struct msghdr *) data; - int retsize, error; + // okay, now try to open a real socket behind this fd/net_stack_cookie pair + err = core->socket_init(&nsc->socket); + if (err == 0) + err = core->socket_create(nsc->socket, args->u.socket.family, args->u.socket.type, args->u.socket.proto); + // TODO: This is where the open flags need to be addressed + return err; + } + case NET_STACK_ASSOCIATE_SOCKET: + nsc->socket = args->u.associate.socket; + 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); - error = core->socket_recv(nsc->socket, mh, (caddr_t)&mh->msg_namelen, + 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); + + 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; + } + case NET_STACK_SEND: + // TODO: flags gets ignored here... + return net_stack_write(cookie, 0, args->u.xfer.data, &args->u.xfer.datalen); + + case NET_STACK_RECV: + // TODO: flags gets ignored here... + return net_stack_read(cookie, 0, args->u.xfer.data, &args->u.xfer.datalen); + + case NET_STACK_RECVFROM: { + struct msghdr * mh = (struct msghdr *) data; + int retsize; + + err = core->socket_recv(nsc->socket, mh, (caddr_t)&mh->msg_namelen, &retsize); - if (error == 0) - return retsize; - return error; - } - case NET_STACK_SENDTO: { - struct msghdr * mh = (struct msghdr *) data; - int retsize, error; + if (err == 0) + return retsize; + return err; + } + case NET_STACK_SENDTO: { + struct msghdr * mh = (struct msghdr *) data; + int retsize; - error = core->socket_send(nsc->socket, mh, mh->msg_flags, + err = core->socket_send(nsc->socket, mh, mh->msg_flags, &retsize); - if (error == 0) - return retsize; - return error; - } - case NET_STACK_SYSCTL: { - struct sysctl_args * args = (struct sysctl_args *) data; - return core->net_sysctl(args->name, args->namelen, - args->oldp, args->oldlenp, - args->newp, args->newlen); - } - case NET_STACK_GETSOCKOPT: { - struct sockopt_args * args = (struct sockopt_args *) data; - return core->socket_getsockopt(nsc->socket, args->level, args->option, - args->optval, (size_t *) &args->optlen); - } - case NET_STACK_SETSOCKOPT: { - struct sockopt_args * args = (struct sockopt_args *)data; - - return core->socket_setsockopt(nsc->socket, args->level, args->option, - (const void *) args->optval, args->optlen); - } - case NET_STACK_GETSOCKNAME: { - struct sockaddr_args * args = (struct sockaddr_args *) data; - // args->addr == sockaddr to accept the sockname - return core->socket_getsockname(nsc->socket, args->addr, &args->addrlen); - } - case NET_STACK_GETPEERNAME: { - struct sockaddr_args * args = (struct sockaddr_args *) data; - // args->addr == sockaddr to accept the peername - return core->socket_getpeername(nsc->socket, args->addr, &args->addrlen); - } - case NET_STACK_STOP: { - core->stop(); - return B_OK; - } - case B_SET_BLOCKING_IO: { - nsc->open_flags &= ~O_NONBLOCK; - return B_OK; - } - case B_SET_NONBLOCKING_IO: { - nsc->open_flags |= O_NONBLOCK; - return B_OK; - } - case NET_STACK_SELECT: { - struct select_args *args = (struct select_args *) data; - - /* if we get this opcode, we are using the r5 kernel select() call, - * so we can't use his 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); - } - default: - if (nsc->socket) - // pass any unhandled opcode to the stack - return core->socket_ioctl(nsc->socket, op, data); - return B_BAD_VALUE; - } + if (err == 0) + return retsize; + return err; + } + case NET_STACK_SYSCTL: + return core->net_sysctl(args->u.sysctl.name, args->u.sysctl.namelen, + args->u.sysctl.oldp, args->u.sysctl.oldlenp, + args->u.sysctl.newp, args->u.sysctl.newlen); + + case NET_STACK_GETSOCKOPT: + return core->socket_getsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option, + args->u.sockopt.optval, (size_t *) &args->u.sockopt.optlen); + + case NET_STACK_SETSOCKOPT: + return core->socket_setsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option, + (const void *) args->u.sockopt.optval, args->u.sockopt.optlen); + + case NET_STACK_GETSOCKNAME: + return core->socket_getsockname(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen); + + 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; + + case B_SET_NONBLOCKING_IO: + nsc->open_flags |= O_NONBLOCK; + return B_OK; + + case NET_STACK_SELECT: + /* if we get this opcode, we are using the r5 kernel select() call, + * so we can't use his notify_select_event(), but our own implementation! */ + g_nse = r5_notify_select_event; + return net_stack_select(cookie, (args->u.select.ref & 0x0F), + args->u.select.ref, args->u.select.sync); + case NET_STACK_DESELECT: + return net_stack_deselect(cookie, (args->u.select.ref & 0x0F), args->u.select.sync); + + default: + if (nsc->socket) + // pass any unhandled opcode to the stack + return core->socket_ioctl(nsc->socket, op, data); + return B_BAD_VALUE; + }; + }; } diff --git a/src/kits/network/libnet/socket.c b/src/kits/network/libnet/socket.c index fba409c97c..92c571132f 100644 --- a/src/kits/network/libnet/socket.c +++ b/src/kits/network/libnet/socket.c @@ -148,35 +148,15 @@ _EXPORT int listen(int sock, int backlog) _EXPORT int accept(int sock, struct sockaddr *addr, int *addrlen) { struct sockaddr temp; - struct accept_args args; - int rv; - int new_sock; - void *cookie; - - new_sock = open(get_stack_driver_path(), O_RDWR); - if (new_sock < 0) - return new_sock; - - // The network stack driver will need to know to which net_stack_cookie to - // *bind* with the new accepted socket. He can't know himself find out - // the net_stack_cookie of our new_sock file descriptor, the just open() one... - // So, here, we ask him the net_stack_cookie value for our fd... :-) - rv = ioctl(new_sock, NET_STACK_GET_COOKIE, &cookie); - if (rv < 0) { - close(new_sock); - return rv; - }; - - args.cookie = cookie; // this way driver can use the right fd/cookie for the new_sock! + struct sockaddr_args args; + int new_sock; args.addr = g_beos_r5_compatibility ? &temp : addr; args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen; - - rv = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args)); - if (rv < 0) { - close(new_sock); - return rv; - }; + + new_sock = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args)); + if (new_sock < 0) + return new_sock; if (g_beos_r5_compatibility) { convert_to_beos_r5_sockaddr(addr, &temp); @@ -257,7 +237,7 @@ _EXPORT ssize_t sendto(int sock, const void *buffer, size_t buflen, int flags, */ _EXPORT ssize_t recv(int sock, void *data, size_t datalen, int flags) { - struct data_xfer_args args; + struct xfer_args args; int rv; args.data = data; @@ -276,7 +256,7 @@ _EXPORT ssize_t recv(int sock, void *data, size_t datalen, int flags) _EXPORT ssize_t send(int sock, const void *data, size_t datalen, int flags) { - struct data_xfer_args args; + struct xfer_args args; int rv; args.data = (void *) data;