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:
parent
5d7c65c278
commit
a91f266ff3
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user