Support PRU_BIND / PRU_LISTEN / PRU_ACCEPT in sockin.
This commit is contained in:
parent
50176705eb
commit
eebcd28057
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rumpuser.h,v 1.2 2008/11/18 12:39:35 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser.h,v 1.3 2008/11/25 20:39:57 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Antti Kantee. All Rights Reserved.
|
||||
@ -154,5 +154,8 @@ int rumpuser_net_socket(int, int, int, int *);
|
||||
int rumpuser_net_sendmsg(int, const struct msghdr *, int, int *);
|
||||
int rumpuser_net_recvmsg(int, struct msghdr *, int, int *);
|
||||
int rumpuser_net_connect(int, const struct sockaddr *, int, int *);
|
||||
int rumpuser_net_bind(int, const struct sockaddr *, int, int *);
|
||||
int rumpuser_net_accept(int, struct sockaddr *, int *, int *);
|
||||
int rumpuser_net_listen(int, int, int *);
|
||||
|
||||
#endif /* _RUMP_RUMPUSER_H_ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rumpuser_net.c,v 1.3 2008/10/15 13:02:29 pooka Exp $ */
|
||||
/* $NetBSD: rumpuser_net.c,v 1.4 2008/11/25 20:39:57 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
@ -61,3 +61,24 @@ rumpuser_net_connect(int s, const struct sockaddr *name, int len, int *error)
|
||||
|
||||
DOCALL_KLOCK(int, (connect(s, name, (socklen_t)len)));
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_net_bind(int s, const struct sockaddr *name, int len, int *error)
|
||||
{
|
||||
|
||||
DOCALL_KLOCK(int, (bind(s, name, (socklen_t)len)));
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_net_accept(int s, struct sockaddr *name, int *lenp, int *error)
|
||||
{
|
||||
|
||||
DOCALL_KLOCK(int, (accept(s, name, (socklen_t *)lenp)));
|
||||
}
|
||||
|
||||
int
|
||||
rumpuser_net_listen(int s, int backlog, int *error)
|
||||
{
|
||||
|
||||
DOCALL_KLOCK(int, (listen(s, backlog)));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sockin.c,v 1.4 2008/10/26 18:39:01 minskim Exp $ */
|
||||
/* $NetBSD: sockin.c,v 1.5 2008/11/25 20:39:57 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
|
||||
@ -101,6 +101,37 @@ struct domain sockindomain = {
|
||||
#define SO2S(so) ((intptr_t)(so->so_internal))
|
||||
#define SOCKIN_SBSIZE 65536
|
||||
|
||||
struct sockin_unit {
|
||||
struct socket *su_so;
|
||||
|
||||
LIST_ENTRY(sockin_unit) su_entries;
|
||||
};
|
||||
static LIST_HEAD(, sockin_unit) su_ent = LIST_HEAD_INITIALIZER(su_ent);
|
||||
static kmutex_t su_mtx;
|
||||
static bool rebuild;
|
||||
static int nsock;
|
||||
|
||||
static int
|
||||
registersock(struct socket *so, int news)
|
||||
{
|
||||
struct sockin_unit *su;
|
||||
|
||||
su = kmem_alloc(sizeof(*su), KM_NOSLEEP);
|
||||
if (!su)
|
||||
return ENOMEM;
|
||||
|
||||
so->so_internal = (void *)(intptr_t)news;
|
||||
su->su_so = so;
|
||||
|
||||
mutex_enter(&su_mtx);
|
||||
LIST_INSERT_HEAD(&su_ent, su, su_entries);
|
||||
nsock++;
|
||||
rebuild = true;
|
||||
mutex_exit(&su_mtx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sockin_process(struct socket *so)
|
||||
{
|
||||
@ -142,17 +173,32 @@ sockin_process(struct socket *so)
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
struct sockin_unit {
|
||||
struct socket *su_so;
|
||||
|
||||
LIST_ENTRY(sockin_unit) su_entries;
|
||||
};
|
||||
static LIST_HEAD(, sockin_unit) su_ent = LIST_HEAD_INITIALIZER(su_ent);
|
||||
static kmutex_t su_mtx;
|
||||
static bool rebuild;
|
||||
static int nsock;
|
||||
|
||||
#ifndef SOCKIN_NOTHREAD
|
||||
static void
|
||||
sockin_accept(struct socket *so)
|
||||
{
|
||||
struct socket *nso;
|
||||
struct sockaddr_in sin;
|
||||
int news, error, slen;
|
||||
|
||||
slen = sizeof(sin);
|
||||
news = rumpuser_net_accept(SO2S(so), (struct sockaddr *)&sin,
|
||||
&slen, &error);
|
||||
if (news == -1)
|
||||
return;
|
||||
|
||||
if ((nso = sonewconn(so, SS_ISCONNECTED)) == NULL)
|
||||
goto errout;
|
||||
if (registersock(nso, news) != 0)
|
||||
goto errout;
|
||||
return;
|
||||
|
||||
errout:
|
||||
rumpuser_close(news, &error);
|
||||
if (nso)
|
||||
soclose(nso);
|
||||
}
|
||||
|
||||
#define POLLTIMEOUT 100 /* check for new entries every 100ms */
|
||||
|
||||
/* XXX: doesn't handle socket (kernel) locking properly? */
|
||||
@ -161,6 +207,7 @@ sockinworker(void *arg)
|
||||
{
|
||||
struct pollfd *pfds = NULL, *npfds;
|
||||
struct sockin_unit *su_iter;
|
||||
struct socket *so;
|
||||
int cursock = 0, i, rv, error;
|
||||
|
||||
/*
|
||||
@ -200,9 +247,15 @@ sockinworker(void *arg)
|
||||
mutex_enter(&su_mtx);
|
||||
LIST_FOREACH(su_iter, &su_ent, su_entries) {
|
||||
if (SO2S(su_iter->su_so)==pfds[i].fd) {
|
||||
so = su_iter->su_so;
|
||||
mutex_exit(&su_mtx);
|
||||
mutex_enter(softnet_lock);
|
||||
sockin_process(su_iter->su_so);
|
||||
if(so->so_options&SO_ACCEPTCONN)
|
||||
sockin_accept(so);
|
||||
else
|
||||
sockin_process(so);
|
||||
mutex_exit(softnet_lock);
|
||||
mutex_enter(&su_mtx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -249,7 +302,6 @@ sockin_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
||||
switch (req) {
|
||||
case PRU_ATTACH:
|
||||
{
|
||||
struct sockin_unit *su;
|
||||
int news;
|
||||
|
||||
sosetlock(so);
|
||||
@ -259,29 +311,26 @@ sockin_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
||||
break;
|
||||
}
|
||||
|
||||
su = kmem_alloc(sizeof(*su), KM_NOSLEEP);
|
||||
if (!su) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
news = rumpuser_net_socket(PF_INET, so->so_proto->pr_type,
|
||||
0, &error);
|
||||
if (news == -1) {
|
||||
kmem_free(su, sizeof(*su));
|
||||
if (news == -1)
|
||||
break;
|
||||
}
|
||||
so->so_internal = (void *)(intptr_t)news;
|
||||
su->su_so = so;
|
||||
|
||||
mutex_enter(&su_mtx);
|
||||
LIST_INSERT_HEAD(&su_ent, su, su_entries);
|
||||
nsock++;
|
||||
rebuild = true;
|
||||
mutex_exit(&su_mtx);
|
||||
if ((error = registersock(so, news)) != 0)
|
||||
rumpuser_close(news, &error);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PRU_ACCEPT:
|
||||
/* we do all the work in the worker thread */
|
||||
break;
|
||||
|
||||
case PRU_BIND:
|
||||
rumpuser_net_bind(SO2S(so), mtod(nam, const struct sockaddr *),
|
||||
sizeof(struct sockaddr_in), &error);
|
||||
break;
|
||||
|
||||
case PRU_CONNECT:
|
||||
/* don't bother to connect udp sockets, always sendmsg */
|
||||
if (so->so_proto->pr_type == SOCK_DGRAM)
|
||||
@ -294,6 +343,10 @@ sockin_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
||||
soisconnected(so);
|
||||
break;
|
||||
|
||||
case PRU_LISTEN:
|
||||
rumpuser_net_listen(SO2S(so), so->so_qlimit, &error);
|
||||
break;
|
||||
|
||||
case PRU_SEND:
|
||||
{
|
||||
struct sockaddr *saddr;
|
||||
|
Loading…
Reference in New Issue
Block a user