From 49831ed8da06ffadf684484671b4561c9ac55f9f Mon Sep 17 00:00:00 2001 From: rwatson Date: Sun, 30 Oct 2005 19:44:40 +0000 Subject: Push the assignment of a new or updated so_qlimit from solisten() following the protocol pru_listen() call to solisten_proto(), so that it occurs under the socket lock acquisition that also sets SO_ACCEPTCONN. This requires passing the new backlog parameter to the protocol, which also allows the protocol to be aware of changes in queue limit should it wish to do something about the new queue limit. This continues a move towards the socket layer acting as a library for the protocol. Bump __FreeBSD_version due to a change in the in-kernel protocol interface. This change has been tested with IPv4 and UNIX domain sockets, but not other protocols. --- sys/kern/uipc_sockbuf.c | 2 +- sys/kern/uipc_socket.c | 21 ++++++--------------- sys/kern/uipc_socket2.c | 2 +- sys/kern/uipc_usrreq.c | 12 +++++++----- 4 files changed, 15 insertions(+), 22 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 16fa1f8..9ce6f27 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -1340,7 +1340,7 @@ pru_disconnect_notsupp(struct socket *so) } int -pru_listen_notsupp(struct socket *so, struct thread *td) +pru_listen_notsupp(struct socket *so, int backlog, struct thread *td) { return EOPNOTSUPP; } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index a94e7cb..32375aa 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -294,21 +294,8 @@ solisten(so, backlog, td) int backlog; struct thread *td; { - int error; - - error = (*so->so_proto->pr_usrreqs->pru_listen)(so, td); - if (error) - return (error); - /* - * XXXRW: The following state adjustment should occur in - * solisten_proto(), but we don't currently pass the backlog request - * to the protocol via pru_listen(). - */ - if (backlog < 0 || backlog > somaxconn) - backlog = somaxconn; - so->so_qlimit = backlog; - return (0); + return ((*so->so_proto->pr_usrreqs->pru_listen)(so, backlog, td)); } int @@ -325,12 +312,16 @@ solisten_proto_check(so) } void -solisten_proto(so) +solisten_proto(so, backlog) struct socket *so; + int backlog; { SOCK_LOCK_ASSERT(so); + if (backlog < 0 || backlog > somaxconn) + backlog = somaxconn; + so->so_qlimit = backlog; so->so_options |= SO_ACCEPTCONN; } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 16fa1f8..9ce6f27 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1340,7 +1340,7 @@ pru_disconnect_notsupp(struct socket *so) } int -pru_listen_notsupp(struct socket *so, struct thread *td) +pru_listen_notsupp(struct socket *so, int backlog, struct thread *td) { return EOPNOTSUPP; } diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index ac23154..286f07c 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -126,7 +126,8 @@ static void unp_mark(struct file *); static void unp_discard(struct file *); static void unp_freerights(struct file **, int); static int unp_internalize(struct mbuf **, struct thread *); -static int unp_listen(struct socket *, struct unpcb *, struct thread *); +static int unp_listen(struct socket *, struct unpcb *, int, + struct thread *); static int uipc_abort(struct socket *so) @@ -275,7 +276,7 @@ uipc_disconnect(struct socket *so) } static int -uipc_listen(struct socket *so, struct thread *td) +uipc_listen(struct socket *so, int backlog, struct thread *td) { struct unpcb *unp; int error; @@ -286,7 +287,7 @@ uipc_listen(struct socket *so, struct thread *td) UNP_UNLOCK(); return (EINVAL); } - error = unp_listen(so, unp, td); + error = unp_listen(so, unp, backlog, td); UNP_UNLOCK(); return (error); } @@ -1803,7 +1804,8 @@ unp_dispose(struct mbuf *m) } static int -unp_listen(struct socket *so, struct unpcb *unp, struct thread *td) +unp_listen(struct socket *so, struct unpcb *unp, int backlog, + struct thread *td) { int error; @@ -1814,7 +1816,7 @@ unp_listen(struct socket *so, struct unpcb *unp, struct thread *td) if (error == 0) { cru2x(td->td_ucred, &unp->unp_peercred); unp->unp_flags |= UNP_HAVEPCCACHED; - solisten_proto(so); + solisten_proto(so, backlog); } SOCK_UNLOCK(so); return (error); -- cgit v1.1