From d374e81efdc3cba56fdda9df539773070ca00dfe Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sun, 30 Oct 2005 19:44:40 +0000 Subject: [PATCH] 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 ++++++----- sys/netatm/atm_aal5.c | 8 ++++--- sys/netatm/atm_cm.c | 5 +++-- sys/netatm/atm_socket.c | 6 ++++-- sys/netatm/atm_var.h | 4 ++-- sys/netatm/ipatm/ipatm_load.c | 2 +- .../bluetooth/include/ng_btsocket_l2cap.h | 2 +- .../bluetooth/include/ng_btsocket_rfcomm.h | 2 +- .../bluetooth/socket/ng_btsocket_l2cap.c | 4 ++-- .../bluetooth/socket/ng_btsocket_rfcomm.c | 4 ++-- sys/netinet/tcp_usrreq.c | 8 +++---- sys/netipx/spx_usrreq.c | 7 ++++--- sys/sys/param.h | 2 +- sys/sys/protosw.h | 5 +++-- sys/sys/socketvar.h | 2 +- 18 files changed, 49 insertions(+), 49 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 16fa1f8ad8e..9ce6f2797a3 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 a94e7cb25f0..32375aac8b9 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 16fa1f8ad8e..9ce6f2797a3 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 ac23154c871..286f07ce11a 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); diff --git a/sys/netatm/atm_aal5.c b/sys/netatm/atm_aal5.c index 6d625e0bf38..2367eb98189 100644 --- a/sys/netatm/atm_aal5.c +++ b/sys/netatm/atm_aal5.c @@ -69,7 +69,8 @@ static int atm_aal5_attach(struct socket *, int, struct thread *td); static int atm_aal5_detach(struct socket *); static int atm_aal5_bind(struct socket *, struct sockaddr *, struct thread *td); -static int atm_aal5_listen(struct socket *, struct thread *td); +static int atm_aal5_listen(struct socket *, int backlog, + struct thread *td); static int atm_aal5_connect(struct socket *, struct sockaddr *, struct thread *td); static int atm_aal5_accept(struct socket *, struct sockaddr **); @@ -328,13 +329,14 @@ atm_aal5_bind(so, addr, td) * */ static int -atm_aal5_listen(so, td) +atm_aal5_listen(so, backlog, td) struct socket *so; + int backlog; struct thread *td; { ATM_INTRO("listen"); - err = atm_sock_listen(so, &atm_aal5_endpt); + err = atm_sock_listen(so, &atm_aal5_endpt, backlog); ATM_OUTRO(); } diff --git a/sys/netatm/atm_cm.c b/sys/netatm/atm_cm.c index 60bf48234da..12b9f53cfe5 100644 --- a/sys/netatm/atm_cm.c +++ b/sys/netatm/atm_cm.c @@ -536,12 +536,13 @@ done: * */ int -atm_cm_listen(so, epp, token, ap, copp) +atm_cm_listen(so, epp, token, ap, copp, backlog) struct socket *so; Atm_endpoint *epp; void *token; Atm_attributes *ap; Atm_connection **copp; + int backlog; { Atm_connection *cop; int s, err = 0; @@ -737,7 +738,7 @@ atm_cm_listen(so, epp, token, ap, copp) cop->co_state = COS_LISTEN; LINK2TAIL(cop, Atm_connection, atm_listen_queue, co_next); if (so != NULL) - solisten_proto(so); + solisten_proto(so, backlog); donex: (void) splx(s); diff --git a/sys/netatm/atm_socket.c b/sys/netatm/atm_socket.c index 7da8f3e6c58..2cdab95ebb3 100644 --- a/sys/netatm/atm_socket.c +++ b/sys/netatm/atm_socket.c @@ -335,9 +335,10 @@ atm_sock_bind(so, addr) * */ int -atm_sock_listen(so, epp) +atm_sock_listen(so, epp, backlog) struct socket *so; Atm_endpoint *epp; + int backlog; { Atm_pcb *atp = sotoatmpcb(so); @@ -350,7 +351,8 @@ atm_sock_listen(so, epp) /* * Start listening for incoming calls */ - return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn)); + return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn, + backlog)); } diff --git a/sys/netatm/atm_var.h b/sys/netatm/atm_var.h index 3332c927b13..4bc6d9707bc 100644 --- a/sys/netatm/atm_var.h +++ b/sys/netatm/atm_var.h @@ -82,7 +82,7 @@ void atm_aal5_init(void); int atm_cm_connect(Atm_endpoint *, void *, Atm_attributes *, Atm_connection **); int atm_cm_listen(struct socket *, Atm_endpoint *, void *, - Atm_attributes *, Atm_connection **); + Atm_attributes *, Atm_connection **, int); int atm_cm_addllc(Atm_endpoint *, void *, struct attr_llc *, Atm_connection *, Atm_connection **); int atm_cm_addparty(Atm_connection *, int, struct t_atm_sap *); @@ -152,7 +152,7 @@ void atm_sock_init(void); int atm_sock_attach(struct socket *, u_long, u_long); int atm_sock_detach(struct socket *); int atm_sock_bind(struct socket *, struct sockaddr *); -int atm_sock_listen(struct socket *, Atm_endpoint *); +int atm_sock_listen(struct socket *, Atm_endpoint *, int); int atm_sock_connect(struct socket *, struct sockaddr *, Atm_endpoint *); int atm_sock_disconnect(struct socket *); diff --git a/sys/netatm/ipatm/ipatm_load.c b/sys/netatm/ipatm/ipatm_load.c index 2e931cd015b..4376b6647b1 100644 --- a/sys/netatm/ipatm/ipatm_load.c +++ b/sys/netatm/ipatm/ipatm_load.c @@ -524,7 +524,7 @@ ipatm_start() */ if ((err = atm_cm_listen(NULL, &ipatm_endpt, (void *)(intptr_t)i, &ipatm_listeners[i].attr, - &ipatm_listeners[i].conn)) != 0) + &ipatm_listeners[i].conn, -1)) != 0) goto done; } diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h index ff04ce2aaf1..39c126dc5a0 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h @@ -195,7 +195,7 @@ int ng_btsocket_l2cap_control (struct socket *, u_long, caddr_t, int ng_btsocket_l2cap_ctloutput (struct socket *, struct sockopt *); int ng_btsocket_l2cap_detach (struct socket *); int ng_btsocket_l2cap_disconnect (struct socket *); -int ng_btsocket_l2cap_listen (struct socket *, struct thread *); +int ng_btsocket_l2cap_listen (struct socket *, int, struct thread *); int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr **); int ng_btsocket_l2cap_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h index 4dd1b828258..b280ae3a586 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h @@ -326,7 +326,7 @@ int ng_btsocket_rfcomm_control (struct socket *, u_long, caddr_t, int ng_btsocket_rfcomm_ctloutput (struct socket *, struct sockopt *); int ng_btsocket_rfcomm_detach (struct socket *); int ng_btsocket_rfcomm_disconnect (struct socket *); -int ng_btsocket_rfcomm_listen (struct socket *, struct thread *); +int ng_btsocket_rfcomm_listen (struct socket *, int, struct thread *); int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr **); int ng_btsocket_rfcomm_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c index 1a25fb38db5..631e6a28c2f 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c @@ -2406,7 +2406,7 @@ ng_btsocket_l2cap_disconnect(struct socket *so) */ int -ng_btsocket_l2cap_listen(struct socket *so, struct thread *td) +ng_btsocket_l2cap_listen(struct socket *so, int backlog, struct thread *td) { ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so); int error; @@ -2427,7 +2427,7 @@ ng_btsocket_l2cap_listen(struct socket *so, struct thread *td) error = EDESTADDRREQ; goto out; } - solisten_proto(so); + solisten_proto(so, backlog); out: SOCK_UNLOCK(so); return (error); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c index 672c6fae2db..96478dfc843 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c @@ -794,7 +794,7 @@ ng_btsocket_rfcomm_disconnect(struct socket *so) */ int -ng_btsocket_rfcomm_listen(struct socket *so, struct thread *td) +ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td) { ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); ng_btsocket_rfcomm_session_p s = NULL; @@ -858,7 +858,7 @@ ng_btsocket_rfcomm_listen(struct socket *so, struct thread *td) goto out; l2so = NULL; } - solisten_proto(so); + solisten_proto(so, backlog); out: SOCK_UNLOCK(so); mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 5a086ba603b..b49583e0630 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -290,7 +290,7 @@ tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td) * Prepare to accept connections. */ static int -tcp_usr_listen(struct socket *so, struct thread *td) +tcp_usr_listen(struct socket *so, int backlog, struct thread *td) { int error = 0; struct inpcb *inp; @@ -304,7 +304,7 @@ tcp_usr_listen(struct socket *so, struct thread *td) error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred); if (error == 0) { tp->t_state = TCPS_LISTEN; - solisten_proto(so); + solisten_proto(so, backlog); } SOCK_UNLOCK(so); COMMON_END(PRU_LISTEN); @@ -312,7 +312,7 @@ tcp_usr_listen(struct socket *so, struct thread *td) #ifdef INET6 static int -tcp6_usr_listen(struct socket *so, struct thread *td) +tcp6_usr_listen(struct socket *so, int backlog, struct thread *td) { int error = 0; struct inpcb *inp; @@ -330,7 +330,7 @@ tcp6_usr_listen(struct socket *so, struct thread *td) } if (error == 0) { tp->t_state = TCPS_LISTEN; - solisten_proto(so); + solisten_proto(so, backlog); } SOCK_UNLOCK(so); COMMON_END(PRU_LISTEN); diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 25042e62f45..30bc70a9c41 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -99,7 +99,7 @@ static int spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td); static int spx_detach(struct socket *so); static int spx_usr_disconnect(struct socket *so); -static int spx_listen(struct socket *so, struct thread *td); +static int spx_listen(struct socket *so, int backlog, struct thread *td); static int spx_rcvd(struct socket *so, int flags); static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags); static int spx_send(struct socket *so, int flags, struct mbuf *m, @@ -1518,8 +1518,9 @@ spx_usr_disconnect(so) } static int -spx_listen(so, td) +spx_listen(so, backlog, td) struct socket *so; + int backlog; struct thread *td; { int error; @@ -1538,7 +1539,7 @@ spx_listen(so, td) error = ipx_pcbbind(ipxp, NULL, td); if (error == 0) { cb->s_state = TCPS_LISTEN; - solisten_proto(so); + solisten_proto(so, backlog); } SOCK_UNLOCK(so); IPX_UNLOCK(ipxp); diff --git a/sys/sys/param.h b/sys/sys/param.h index ba4b9d4a7b3..8bda6ae4c4b 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 700003 /* Master, propagated to newvers */ +#define __FreeBSD_version 700004 /* Master, propagated to newvers */ #ifndef LOCORE #include diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 132b199c1f5..bcf263f51f7 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -208,7 +208,8 @@ struct pr_usrreqs { struct ifnet *ifp, struct thread *td); int (*pru_detach)(struct socket *so); int (*pru_disconnect)(struct socket *so); - int (*pru_listen)(struct socket *so, struct thread *td); + int (*pru_listen)(struct socket *so, int backlog, + struct thread *td); int (*pru_peeraddr)(struct socket *so, struct sockaddr **nam); int (*pru_rcvd)(struct socket *so, int flags); int (*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags); @@ -257,7 +258,7 @@ int pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td); int pru_detach_notsupp(struct socket *so); int pru_disconnect_notsupp(struct socket *so); -int pru_listen_notsupp(struct socket *so, struct thread *td); +int pru_listen_notsupp(struct socket *so, int backlog, struct thread *td); int pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam); int pru_rcvd_notsupp(struct socket *so, int flags); int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags); diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 5311a60cb60..32e01495b5b 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -514,7 +514,7 @@ void soisconnecting(struct socket *so); void soisdisconnected(struct socket *so); void soisdisconnecting(struct socket *so); int solisten(struct socket *so, int backlog, struct thread *td); -void solisten_proto(struct socket *so); +void solisten_proto(struct socket *so, int backlog); int solisten_proto_check(struct socket *so); struct socket * sonewconn(struct socket *head, int connstatus);