Use the pru_flush infrastructure to avoid a panic
PR: 122710 MFC after: 1 week
This commit is contained in:
parent
276ca5012c
commit
eadccaccf0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178202
@ -2182,6 +2182,20 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
|
||||
/* out of memory or ?? */
|
||||
return (NULL);
|
||||
}
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (sctp_logging_level & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
struct mbuf *mat;
|
||||
|
||||
mat = m_sig;
|
||||
while (mat) {
|
||||
if (SCTP_BUF_IS_EXTENDED(mat)) {
|
||||
sctp_log_mb(mat, SCTP_MBUF_SPLIT);
|
||||
}
|
||||
mat = SCTP_BUF_NEXT(mat);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* compute the signature/digest for the cookie
|
||||
*/
|
||||
@ -2795,7 +2809,7 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp,
|
||||
}
|
||||
}
|
||||
/* stop the timer */
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_22);
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_22);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
|
||||
/* free the TCB */
|
||||
SCTPDBG(SCTP_DEBUG_INPUT2,
|
||||
@ -4807,6 +4821,19 @@ __attribute__((noinline))
|
||||
SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, SCTP_SIZE32(chk_length),
|
||||
M_DONTWAIT);
|
||||
if (SCTP_BUF_NEXT(mm)) {
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
if (sctp_logging_level & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
struct mbuf *mat;
|
||||
|
||||
mat = SCTP_BUF_NEXT(mm);
|
||||
while (mat) {
|
||||
if (SCTP_BUF_IS_EXTENDED(mat)) {
|
||||
sctp_log_mb(mat, SCTP_MBUF_ICOPY);
|
||||
}
|
||||
mat = SCTP_BUF_NEXT(mat);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sctp_queue_op_err(stcb, mm);
|
||||
} else {
|
||||
sctp_m_freem(mm);
|
||||
|
@ -918,6 +918,37 @@ sctp_disconnect(struct socket *so)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sctp_flush(struct socket *so, int how)
|
||||
{
|
||||
/*
|
||||
* We will just clear out the values and let subsequent close clear
|
||||
* out the data, if any. Note if the user did a shutdown(SHUT_RD)
|
||||
* they will not be able to read the data, the socket will block
|
||||
* that from happening.
|
||||
*/
|
||||
if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) {
|
||||
/*
|
||||
* First make sure the sb will be happy, we don't use these
|
||||
* except maybe the count
|
||||
*/
|
||||
so->so_rcv.sb_cc = 0;
|
||||
so->so_rcv.sb_mbcnt = 0;
|
||||
so->so_rcv.sb_mb = NULL;
|
||||
}
|
||||
if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) {
|
||||
/*
|
||||
* First make sure the sb will be happy, we don't use these
|
||||
* except maybe the count
|
||||
*/
|
||||
so->so_snd.sb_cc = 0;
|
||||
so->so_snd.sb_mbcnt = 0;
|
||||
so->so_snd.sb_mb = NULL;
|
||||
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sctp_shutdown(struct socket *so)
|
||||
{
|
||||
@ -4008,10 +4039,11 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
SCTP_INP_INCR_REF(inp);
|
||||
SCTP_ASOC_CREATE_LOCK(inp);
|
||||
create_lock_on = 1;
|
||||
|
||||
SCTP_INP_INCR_REF(inp);
|
||||
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
|
||||
/* Should I really unlock ? */
|
||||
@ -4063,7 +4095,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
} else {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
}
|
||||
}
|
||||
if (stcb != NULL) {
|
||||
@ -4433,6 +4465,7 @@ struct pr_usrreqs sctp_usrreqs = {
|
||||
.pru_close = sctp_close,
|
||||
.pru_detach = sctp_close,
|
||||
.pru_sopoll = sopoll_generic,
|
||||
.pru_flush = sctp_flush,
|
||||
.pru_disconnect = sctp_disconnect,
|
||||
.pru_listen = sctp_listen,
|
||||
.pru_peeraddr = sctp_peeraddr,
|
||||
|
@ -307,6 +307,8 @@ void sctp_init __P((void));
|
||||
|
||||
void sctp_pcbinfo_cleanup(void);
|
||||
|
||||
int sctp_flush(struct socket *, int);
|
||||
|
||||
int sctp_shutdown __P((struct socket *));
|
||||
void sctp_notify
|
||||
__P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
|
||||
|
Loading…
Reference in New Issue
Block a user