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
This commit is contained in:
Philippe Houdoin 2003-06-19 01:02:50 +00:00
parent 5d7c65c278
commit a91f266ff3
2 changed files with 138 additions and 164 deletions

View File

@ -162,7 +162,7 @@ _EXPORT int32 api_version = B_CUR_DRIVER_API_VERSION;
_EXPORT status_t init_hardware(void) _EXPORT status_t init_hardware(void)
{ {
bool safemode = false; bool safemode = false;
void * sfmptr; void *sfmptr;
#if SERIAL_DEBUGGING #if SERIAL_DEBUGGING
// XXX - switch on/off at top of file... // 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... // the network stack functions - mainly just pass throughs...
static status_t net_stack_open(const char * name, static status_t net_stack_open(const char *name, uint32 flags, void **cookie)
uint32 flags,
void ** cookie)
{ {
net_stack_cookie * nsc; net_stack_cookie *nsc;
nsc = (net_stack_cookie *) malloc(sizeof(*nsc)); nsc = (net_stack_cookie *) malloc(sizeof(*nsc));
if (!nsc) if (!nsc)
@ -300,7 +298,7 @@ static status_t net_stack_open(const char * name,
static status_t net_stack_close(void *cookie) static status_t net_stack_close(void *cookie)
{ {
net_stack_cookie * nsc = (net_stack_cookie *) cookie; net_stack_cookie *nsc = cookie;
int rv; int rv;
#if SHOW_INSANE_DEBUGGING #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) static status_t net_stack_free_cookie(void *cookie)
{ {
net_stack_cookie * nsc = (net_stack_cookie *) cookie; net_stack_cookie *nsc = cookie;
selecter * s; selecter *s;
#if SHOW_INSANE_DEBUGGING #if SHOW_INSANE_DEBUGGING
dprintf(LOGID "net_stack_free_cookie(%p)\n", cookie); 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); delete_sem(nsc->selecters_lock);
s = nsc->selecters; s = nsc->selecters;
while (s) { while (s) {
selecter * tmp = s; selecter *tmp = s;
s = s->next; s = s->next;
free(tmp); 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 #if SHOW_INSANE_DEBUGGING
dprintf(LOGID "net_stack_control(%p, 0x%lX, %p, %ld)\n", cookie, op, data, len); 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(); keep_driver_loaded();
#endif #endif
switch (op) { if (! nsc->socket) {
case NET_STACK_SOCKET: { switch (op) {
struct socket_args * args = (struct socket_args *) data; case NET_STACK_SOCKET: {
int rv;
// okay, now try to open a real socket behind this fd/net_stack_cookie pair // okay, now try to open a real socket behind this fd/net_stack_cookie pair
rv = core->socket_init(&nsc->socket); err = core->socket_init(&nsc->socket);
if (rv == 0) if (err == 0)
rv = core->socket_create(nsc->socket, args->family, args->type, args->proto); 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 // TODO: This is where the open flags need to be addressed
return rv; return err;
} }
case NET_STACK_CONNECT: { case NET_STACK_ASSOCIATE_SOCKET:
struct sockaddr_args * args = (struct sockaddr_args *) data; nsc->socket = args->u.associate.socket;
// args->addr == sockaddr to connect to return B_OK;
return core->socket_connect(nsc->socket, (caddr_t) args->addr, args->addrlen); };
} } else {
case NET_STACK_BIND: { switch (op) {
struct sockaddr_args * args = (struct sockaddr_args *) data; case NET_STACK_CONNECT:
// args->addr == sockaddr to try and bind to return core->socket_connect(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
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;
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); &retsize);
if (error == 0) if (err == 0)
return retsize; return retsize;
return error; return err;
} }
case NET_STACK_SENDTO: { case NET_STACK_SENDTO: {
struct msghdr * mh = (struct msghdr *) data; struct msghdr * mh = (struct msghdr *) data;
int retsize, error; int retsize;
error = core->socket_send(nsc->socket, mh, mh->msg_flags, err = core->socket_send(nsc->socket, mh, mh->msg_flags,
&retsize); &retsize);
if (error == 0) if (err == 0)
return retsize; return retsize;
return error; return err;
} }
case NET_STACK_SYSCTL: { case NET_STACK_SYSCTL:
struct sysctl_args * args = (struct sysctl_args *) data; return core->net_sysctl(args->u.sysctl.name, args->u.sysctl.namelen,
return core->net_sysctl(args->name, args->namelen, args->u.sysctl.oldp, args->u.sysctl.oldlenp,
args->oldp, args->oldlenp, args->u.sysctl.newp, args->u.sysctl.newlen);
args->newp, args->newlen);
} case NET_STACK_GETSOCKOPT:
case NET_STACK_GETSOCKOPT: { return core->socket_getsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
struct sockopt_args * args = (struct sockopt_args *) data; args->u.sockopt.optval, (size_t *) &args->u.sockopt.optlen);
return core->socket_getsockopt(nsc->socket, args->level, args->option,
args->optval, (size_t *) &args->optlen); case NET_STACK_SETSOCKOPT:
} return core->socket_setsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
case NET_STACK_SETSOCKOPT: { (const void *) args->u.sockopt.optval, args->u.sockopt.optlen);
struct sockopt_args * args = (struct sockopt_args *)data;
case NET_STACK_GETSOCKNAME:
return core->socket_setsockopt(nsc->socket, args->level, args->option, return core->socket_getsockname(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
(const void *) args->optval, args->optlen);
} case NET_STACK_GETPEERNAME:
case NET_STACK_GETSOCKNAME: { return core->socket_getpeername(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
struct sockaddr_args * args = (struct sockaddr_args *) data;
// args->addr == sockaddr to accept the sockname case B_SET_BLOCKING_IO:
return core->socket_getsockname(nsc->socket, args->addr, &args->addrlen); nsc->open_flags &= ~O_NONBLOCK;
} return B_OK;
case NET_STACK_GETPEERNAME: {
struct sockaddr_args * args = (struct sockaddr_args *) data; case B_SET_NONBLOCKING_IO:
// args->addr == sockaddr to accept the peername nsc->open_flags |= O_NONBLOCK;
return core->socket_getpeername(nsc->socket, args->addr, &args->addrlen); return B_OK;
}
case NET_STACK_STOP: { case NET_STACK_SELECT:
core->stop(); /* if we get this opcode, we are using the r5 kernel select() call,
return B_OK; * so we can't use his notify_select_event(), but our own implementation! */
} g_nse = r5_notify_select_event;
case B_SET_BLOCKING_IO: { return net_stack_select(cookie, (args->u.select.ref & 0x0F),
nsc->open_flags &= ~O_NONBLOCK; args->u.select.ref, args->u.select.sync);
return B_OK; case NET_STACK_DESELECT:
} return net_stack_deselect(cookie, (args->u.select.ref & 0x0F), args->u.select.sync);
case B_SET_NONBLOCKING_IO: {
nsc->open_flags |= O_NONBLOCK; default:
return B_OK; if (nsc->socket)
} // pass any unhandled opcode to the stack
case NET_STACK_SELECT: { return core->socket_ioctl(nsc->socket, op, data);
struct select_args *args = (struct select_args *) data; return B_BAD_VALUE;
};
/* 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;
}
} }

View File

@ -148,35 +148,15 @@ _EXPORT int listen(int sock, int backlog)
_EXPORT int accept(int sock, struct sockaddr *addr, int *addrlen) _EXPORT int accept(int sock, struct sockaddr *addr, int *addrlen)
{ {
struct sockaddr temp; struct sockaddr temp;
struct accept_args args; struct sockaddr_args args;
int rv; int new_sock;
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!
args.addr = g_beos_r5_compatibility ? &temp : addr; args.addr = g_beos_r5_compatibility ? &temp : addr;
args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen; args.addrlen = g_beos_r5_compatibility ? sizeof(temp) : *addrlen;
rv = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args)); new_sock = ioctl(sock, NET_STACK_ACCEPT, &args, sizeof(args));
if (rv < 0) { if (new_sock < 0)
close(new_sock); return new_sock;
return rv;
};
if (g_beos_r5_compatibility) { if (g_beos_r5_compatibility) {
convert_to_beos_r5_sockaddr(addr, &temp); 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) _EXPORT ssize_t recv(int sock, void *data, size_t datalen, int flags)
{ {
struct data_xfer_args args; struct xfer_args args;
int rv; int rv;
args.data = data; 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) _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; int rv;
args.data = (void *) data; args.data = (void *) data;