Use the SCTP_PCB_FLAGS_ACCEPTING flags to check for listeners.

While there, use a macro for checking the listen state to allow for
easier changes if required.

This done to help glebius@ with his listen changes.
This commit is contained in:
Michael Tuexen 2017-05-26 16:29:00 +00:00
parent 55b87d4621
commit 5d08768a2b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318958
6 changed files with 25 additions and 20 deletions

View File

@ -161,13 +161,11 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
*abort_no_unlock = 1;
goto outnow;
}
/* We are only accepting if we have a socket with positive
* so_qlimit. */
/* We are only accepting if we have a listening socket. */
if ((stcb == NULL) &&
((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_socket == NULL) ||
(inp->sctp_socket->so_qlimit == 0))) {
(!SCTP_IS_LISTENING(inp)))) {
/*
* FIX ME ?? What about TCP model and we have a
* match/restart case? Actually no fix is needed. the lookup
@ -1605,8 +1603,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_stop_all_cookie_timers(stcb);
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
(inp->sctp_socket->so_qlimit == 0)
) {
(!SCTP_IS_LISTENING(inp))) {
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
#endif
@ -1806,7 +1803,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
(inp->sctp_socket->so_qlimit == 0)) {
(!SCTP_IS_LISTENING(inp))) {
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
#endif
@ -2317,7 +2314,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
*notification = SCTP_NOTIFY_ASSOC_UP;
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
(inp->sctp_socket->so_qlimit == 0)) {
(!SCTP_IS_LISTENING(inp))) {
/*
* This is an endpoint that called connect() how it got a
* cookie that is NEW is a bit of a mystery. It must be that
@ -2343,7 +2340,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_UNLOCK(so, 1);
#endif
} else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(inp->sctp_socket->so_qlimit)) {
(SCTP_IS_LISTENING(inp))) {
/*
* We don't want to do anything with this one. Since it is
* the listening guy. The timer will get started for
@ -5205,7 +5202,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
* longer listening.
*/
if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
if ((stcb == NULL) &&
(!SCTP_IS_LISTENING(inp) ||
inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");

View File

@ -462,8 +462,6 @@ sctp_get_mbuf_for_msg(unsigned int space_needed,
#define SCTP_SHA256_UPDATE SHA256_Update
#define SCTP_SHA256_FINAL(x,y) SHA256_Final((caddr_t)x, y)
#endif
#define SCTP_DECREMENT_AND_CHECK_REFCOUNT(addr) (atomic_fetchadd_int(addr, -1) == 1)
#if defined(INVARIANTS)
#define SCTP_SAVE_ATOMIC_DECREMENT(addr, val) \
@ -484,3 +482,7 @@ sctp_get_mbuf_for_msg(unsigned int space_needed,
} \
}
#endif
#define SCTP_IS_LISTENING(inp) ((inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) != 0)
#endif

View File

@ -12595,7 +12595,7 @@ sctp_lower_sosend(struct socket *so,
(void *)addr,
sndlen);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(inp->sctp_socket->so_qlimit)) {
SCTP_IS_LISTENING(inp)) {
/* The listener can NOT send */
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_OUTPUT, ENOTCONN);
error = ENOTCONN;

View File

@ -1311,7 +1311,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
* it is the acceptor, then do the special_lookup to hash
* and find the real inp.
*/
if ((inp->sctp_socket) && (inp->sctp_socket->so_qlimit)) {
if ((inp->sctp_socket) && SCTP_IS_LISTENING(inp)) {
/* to is peer addr, from is my addr */
stcb = sctp_tcb_special_locate(inp_p, remote, local,
netp, inp->def_vrf_id);
@ -1884,7 +1884,7 @@ sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp)
if (tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
continue;
}
if (tinp->sctp_socket->so_qlimit) {
if (SCTP_IS_LISTENING(tinp)) {
continue;
}
SCTP_INP_WLOCK(tinp);

View File

@ -410,6 +410,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.socket = inp->sctp_socket;
so = inp->sctp_socket;
if ((so == NULL) ||
(!SCTP_IS_LISTENING(inp)) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
xinpcb.qlen = 0;
xinpcb.maxqlen = 0;

View File

@ -7039,7 +7039,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(tinp->sctp_socket->so_qlimit)) {
(SCTP_IS_LISTENING(tinp))) {
/*
* we have a listener already and
* its not this inp.
@ -7083,7 +7083,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
(tinp->sctp_socket->so_qlimit)) {
(SCTP_IS_LISTENING(tinp))) {
/*
* we have a listener already and its not
* this inp.
@ -7137,6 +7137,7 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
return (error);
}
}
SCTP_INP_WLOCK(inp);
SOCK_LOCK(so);
/* It appears for 7.0 and on, we must always call this. */
solisten_proto(so, backlog);
@ -7144,11 +7145,13 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
/* remove the ACCEPTCONN flag for one-to-many sockets */
so->so_options &= ~SO_ACCEPTCONN;
}
if (backlog == 0) {
/* turning off listen */
so->so_options &= ~SO_ACCEPTCONN;
if (backlog > 0) {
inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
} else {
inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
}
SOCK_UNLOCK(so);
SCTP_INP_WUNLOCK(inp);
return (error);
}