From 63981c2b40be9eddd141974e16437ec735e9b95c Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Mon, 6 Aug 2007 15:46:46 +0000 Subject: [PATCH] - change number assignments for SHA225-512 (match artisync for bakeoff.. using the next sequential ones) - In cookie processing 1-2-1, we did not increment the stcb refcnt before releasing the tcb lock. We need to do this to keep the tcb from being freed by a abort or ?? unlikely but worth doing. Also get rid of unneed INP_WLOCK. - extra receive info included the rcvinfo which killed the padding/alignment. We now redefine all the fields properly so they both align properly both to 128 bytes. - A peeled off socket would not close without an error due to its misguided idea that sctp_disconnect() was not supported on it. This fixes it so it goes through the proper path. - When an assoc was being deleted after abort (via a timer) a small race condition exists where we might take a packet for the old assoc (since we are waiting for a cleanup timer). This state especially happens in mac. We now add a state in the asoc so these can properly handle the packet as OOTB. Approved by: re@freebsd.org(Ken Smith) --- sys/netinet/sctp_constants.h | 1 + sys/netinet/sctp_input.c | 12 ++++++++++++ sys/netinet/sctp_uio.h | 16 ++++++++++++---- sys/netinet/sctp_usrreq.c | 3 ++- sys/netinet/sctputil.c | 3 +++ 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index 7aee1a154b40..cf852a49199d 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -476,6 +476,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_STATE_CLOSED_SOCKET 0x0100 #define SCTP_STATE_ABOUT_TO_BE_FREED 0x0200 #define SCTP_STATE_PARTIAL_MSG_LEFT 0x0400 +#define SCTP_STATE_WAS_ABORTED 0x0800 #define SCTP_STATE_MASK 0x007f #define SCTP_GET_STATE(asoc) ((asoc)->state & SCTP_STATE_MASK) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index b0ca7f5bddaa..5a278c15753c 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -4514,6 +4514,18 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, /* always clear this before beginning a packet */ stcb->asoc.authenticated = 0; stcb->asoc.seen_a_sack_this_pkt = 0; + if (stcb->asoc.state & SCTP_STATE_WAS_ABORTED) { + /*- + * If we hit here, we had a ref count + * up when the assoc was aborted and the + * timer is clearing out the assoc, we should + * NOT respond to any packet.. its OOTB. + */ + SCTP_TCB_UNLOCK(stcb); + sctp_handle_ootb(m, iphlen, offset, sh, inp, NULL, + vrf_id); + goto out_now; + } } if (IS_SCTP_CONTROL(ch)) { /* process the control portion of the SCTP packet */ diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index e0c8441d75b0..1689a7cc93e9 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -105,7 +105,15 @@ struct sctp_sndrcvinfo { }; struct sctp_extrcvinfo { - struct sctp_sndrcvinfo sreinfo_sinfo; + uint16_t sinfo_stream; + uint16_t sinfo_ssn; + uint16_t sinfo_flags; + uint32_t sinfo_ppid; + uint32_t sinfo_context; + uint32_t sinfo_timetolive; + uint32_t sinfo_tsn; + uint32_t sinfo_cumtsn; + sctp_assoc_t sinfo_assoc_id; uint16_t sreinfo_next_flags; uint16_t sreinfo_next_stream; uint32_t sreinfo_next_aid; @@ -504,9 +512,9 @@ struct sctp_hmacalgo { #define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */ #define SCTP_AUTH_HMAC_ID_MD5 0x0002 /* deprecated */ #define SCTP_AUTH_HMAC_ID_SHA256 0x0003 -#define SCTP_AUTH_HMAC_ID_SHA224 0x8001 -#define SCTP_AUTH_HMAC_ID_SHA384 0x8002 -#define SCTP_AUTH_HMAC_ID_SHA512 0x8003 +#define SCTP_AUTH_HMAC_ID_SHA224 0x0004 +#define SCTP_AUTH_HMAC_ID_SHA384 0x0005 +#define SCTP_AUTH_HMAC_ID_SHA512 0x0006 /* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */ diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 240e96c47186..54b31b5382c0 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -734,7 +734,8 @@ sctp_disconnect(struct socket *so) return (ENOTCONN); } SCTP_INP_RLOCK(inp); - if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || + (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { if (SCTP_LIST_EMPTY(&inp->sctp_asoc_list)) { /* No connection */ SCTP_INP_RUNLOCK(inp); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index bf0eb29a09c0..573c3d380d5f 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3653,6 +3653,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_abort_notification(stcb, 0); /* get the assoc vrf id and table id */ vrf_id = stcb->asoc.vrf_id; + stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; } sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id); if (stcb != NULL) { @@ -3747,6 +3748,8 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, } } return; + } else { + stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; } vtag = stcb->asoc.peer_vtag; /* notify the ulp */