summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-10-16 14:05:51 +0000
committerrrs <rrs@FreeBSD.org>2007-10-16 14:05:51 +0000
commitca7dd6ed00d7b8c0203672071f42019bf8f2e91c (patch)
tree169ea5af0b4fe0690954c3c0bf963a4a2d5dbf1d /sys/netinet/sctp_input.c
parente348108e8d4da58dae544d842822f5ac998adda6 (diff)
downloadFreeBSD-src-ca7dd6ed00d7b8c0203672071f42019bf8f2e91c.zip
FreeBSD-src-ca7dd6ed00d7b8c0203672071f42019bf8f2e91c.tar.gz
- fix sctp_ifn initial refcount issue (prevents deletion)
- fix a bug during cookie collision that prevented an association from coming up in a specific restart case. - Fix it so the shutdown-pending flag gets removed (this is more for correctness then needed) when we enter shutdown-sent or shutdown-ack-sent states. - Fix a bug that caused the receiver to sometimes NOT send a SACK when a duplicate TSN arrived. Without this fix it was possible for the association to fall down if the - Deleted primary destination is also stored when SCTP_MOBILITY_BASE. (Previously, it is stored when only SCTP_MOBILITY_FASTHANDOFF) - Fix a locking issue where we might call send_initiate_ack() and incorrectly state the lock held/not held. Also fix it so that when we release the lock the inp cannot be deleted on us. - Add the debug option that can cause the stack to panic instead of aborting an assoc. This does not and should never show up in options but is useful for debugging unexpected aborts. - Add cumack_log sent to track sending cumack information for the debug case where we are running a special log per assoc. - Added extra () aroudn sctp_sbspace macro to avoid compile warnings. MFC after: 1 week
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r--sys/netinet/sctp_input.c65
1 files changed, 23 insertions, 42 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 10f305c..ea7456f 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -168,7 +168,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
/* send an INIT-ACK w/cookie */
SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp, vrf_id,
- SCTP_HOLDS_LOCK);
+ ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
outnow:
if (stcb == NULL) {
SCTP_INP_RUNLOCK(inp);
@@ -739,6 +739,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_RECEIVED);
+ SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
/*
* notify upper layer that peer has initiated a
* shutdown
@@ -774,7 +775,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
-
+ SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_7);
/* start SHUTDOWN timer */
@@ -4387,51 +4388,31 @@ process_control_chunks:
* closed. We opened and bound.. and are now no
* longer listening.
*/
- if (inp->sctp_socket->so_qlimit == 0) {
- if ((stcb) && (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
- /*
- * special case, is this a retran'd
- * COOKIE-ECHO or a restarting assoc
- * that is a peeled off or
- * one-to-one style socket.
- */
- goto process_cookie_anyway;
- }
- sctp_abort_association(inp, stcb, m, iphlen,
- sh, NULL, vrf_id);
- *offset = length;
- return (NULL);
- } else if (inp->sctp_socket->so_qlimit) {
- /* we are accepting so check limits like TCP */
- if (inp->sctp_socket->so_qlen >=
- inp->sctp_socket->so_qlimit) {
- /* no space */
+
+ if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
+ (sctp_abort_if_one_2_one_hits_limit)) {
struct mbuf *oper;
struct sctp_paramhdr *phdr;
- if (sctp_abort_if_one_2_one_hits_limit) {
- oper = NULL;
- oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
- 0, M_DONTWAIT, 1, MT_DATA);
- if (oper) {
- SCTP_BUF_LEN(oper) =
- sizeof(struct sctp_paramhdr);
- phdr = mtod(oper,
- struct sctp_paramhdr *);
- phdr->param_type =
- htons(SCTP_CAUSE_OUT_OF_RESC);
- phdr->param_length =
- htons(sizeof(struct sctp_paramhdr));
- }
- sctp_abort_association(inp, stcb, m,
- iphlen, sh, oper, vrf_id);
+ oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
+ 0, M_DONTWAIT, 1, MT_DATA);
+ if (oper) {
+ SCTP_BUF_LEN(oper) =
+ sizeof(struct sctp_paramhdr);
+ phdr = mtod(oper,
+ struct sctp_paramhdr *);
+ phdr->param_type =
+ htons(SCTP_CAUSE_OUT_OF_RESC);
+ phdr->param_length =
+ htons(sizeof(struct sctp_paramhdr));
}
- *offset = length;
- return (NULL);
+ sctp_abort_association(inp, stcb, m,
+ iphlen, sh, oper, vrf_id);
}
- }
- process_cookie_anyway:
- {
+ *offset = length;
+ return (NULL);
+ } else {
struct mbuf *ret_buf;
struct sctp_inpcb *linp;
OpenPOWER on IntegriCloud