diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/sctp_input.c | 29 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 37 | ||||
-rw-r--r-- | sys/netinet/sctp_var.h | 2 |
3 files changed, 65 insertions, 3 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 5bad746..4e57cb1 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -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 @@ process_control_chunks: 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); diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 0c6bf6f..62cdeab 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -919,6 +919,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) { struct sctp_inpcb *inp; @@ -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, diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h index e2fe3f8..e977690 100644 --- a/sys/netinet/sctp_var.h +++ b/sys/netinet/sctp_var.h @@ -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 *, |