summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/sctp_input.c')
-rw-r--r--freebsd/sys/netinet/sctp_input.c154
1 files changed, 88 insertions, 66 deletions
diff --git a/freebsd/sys/netinet/sctp_input.c b/freebsd/sys/netinet/sctp_input.c
index ee206551..c7e86e78 100644
--- a/freebsd/sys/netinet/sctp_input.c
+++ b/freebsd/sys/netinet/sctp_input.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#if defined(INET) || defined(INET6)
#include <netinet/udp.h>
#endif
+#include <netinet/in_kdtrace.h>
#include <sys/smp.h>
@@ -192,7 +193,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
goto outnow;
}
if ((stcb != NULL) &&
- (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending SHUTDOWN-ACK\n");
sctp_send_shutdown_ack(stcb, NULL);
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
@@ -307,6 +308,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) {
sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_INITIALIZATION);
}
+
}
}
SCTP_TCB_SEND_LOCK(stcb);
@@ -493,6 +495,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
SCTP_FREE(param, SCTP_M_ASC_ADDR);
}
}
+
stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
stcb->asoc.local_hmacs);
if (op_err) {
@@ -555,6 +558,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
}
return (retval);
}
+
return (0);
}
@@ -572,6 +576,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
/* Invalid length */
return;
}
+
memset(&store, 0, sizeof(store));
switch (cp->heartbeat.hb_info.addr_family) {
#ifdef INET
@@ -711,15 +716,15 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
*/
struct sctpasochead *head;
- if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) ||
- (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) {
/* generate a new vtag and send init */
LIST_REMOVE(stcb, sctp_asocs);
stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
@@ -733,15 +738,14 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
SCTP_INP_INFO_WUNLOCK();
return (1);
}
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
/*
* treat like a case where the cookie expired i.e.: - dump
* current cookie. - generate a new vtag. - resend init.
*/
/* generate a new vtag and send init */
LIST_REMOVE(stcb, sctp_asocs);
- stcb->asoc.state &= ~SCTP_STATE_COOKIE_ECHOED;
- stcb->asoc.state |= SCTP_STATE_COOKIE_WAIT;
+ SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, &stcb->asoc);
stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
@@ -823,8 +827,8 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
/* free the tcb */
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
- if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
- (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
#ifdef SCTP_ASOCLOG_OF_TSNS
@@ -838,7 +842,7 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
+ SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -893,15 +897,15 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
if (stcb == NULL)
return;
asoc = &stcb->asoc;
- if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
- (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
return;
}
if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_shutdown_chunk)) {
/* Shutdown NOT the expected size */
return;
}
- old_state = SCTP_GET_STATE(asoc);
+ old_state = SCTP_GET_STATE(stcb);
sctp_update_acked(stcb, cp, abort_flag);
if (*abort_flag) {
return;
@@ -957,11 +961,10 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
}
/* goto SHUTDOWN_RECEIVED state to block new requests */
if (stcb->sctp_socket) {
- if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
- (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);
+ if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
+ (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
+ (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT)) {
+ SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_RECEIVED);
/*
* notify upper layer that peer has initiated a
* shutdown
@@ -972,7 +975,7 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
}
}
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_SENT) {
/*
* stop the shutdown timer, since we WILL move to
* SHUTDOWN-ACK-SENT.
@@ -992,13 +995,12 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
/* no outstanding data to send, so move on... */
/* send SHUTDOWN-ACK */
/* move to SHUTDOWN-ACK-SENT state */
- if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
- (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
- SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
- if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
- SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
+ if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
+ SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_ACK_SENT);
sctp_stop_timers_for_shutdown(stcb);
sctp_send_shutdown_ack(stcb, net);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
@@ -1027,15 +1029,15 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
asoc = &stcb->asoc;
/* process according to association state */
- if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
- (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
/* unexpected SHUTDOWN-ACK... do OOTB handling... */
sctp_send_shutdown_complete(stcb, net, 1);
SCTP_TCB_UNLOCK(stcb);
return;
}
- if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
- (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
+ if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
+ (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
/* unexpected SHUTDOWN-ACK... so ignore... */
SCTP_TCB_UNLOCK(stcb);
return;
@@ -1231,7 +1233,7 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
* waiting.
*/
if ((cause_length >= sizeof(struct sctp_error_stale_cookie)) &&
- (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
struct sctp_error_stale_cookie *stale_cookie;
stale_cookie = (struct sctp_error_stale_cookie *)cause;
@@ -1264,8 +1266,7 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
}
/* blast back to INIT state */
sctp_toss_old_cookies(stcb, &stcb->asoc);
- asoc->state &= ~SCTP_STATE_COOKIE_ECHOED;
- asoc->state |= SCTP_STATE_COOKIE_WAIT;
+ SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
sctp_stop_all_cookie_timers(stcb);
sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
}
@@ -1416,7 +1417,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
return (-1);
}
/* process according to association state... */
- switch (stcb->asoc.state & SCTP_STATE_MASK) {
+ switch (SCTP_GET_STATE(stcb)) {
case SCTP_STATE_COOKIE_WAIT:
/* this is the expected state for this chunk */
/* process the INIT-ACK parameters */
@@ -1442,7 +1443,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
}
/* update our state */
SCTPDBG(SCTP_DEBUG_INPUT2, "moving to COOKIE-ECHOED state\n");
- SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_ECHOED);
+ SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_ECHOED);
/* reset the RTO calc */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
@@ -1536,7 +1537,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
if (how_indx < sizeof(asoc->cookie_how)) {
asoc->cookie_how[how_indx] = 1;
}
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
/* SHUTDOWN came in after sending INIT-ACK */
sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
@@ -1605,7 +1606,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
- switch (SCTP_GET_STATE(asoc)) {
+ switch (SCTP_GET_STATE(stcb)) {
case SCTP_STATE_COOKIE_WAIT:
case SCTP_STATE_COOKIE_ECHOED:
/*
@@ -1629,12 +1630,12 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
stcb, net,
SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
/* update current state */
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
else
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
@@ -1718,6 +1719,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
asoc->cookie_how[how_indx] = 5;
return (stcb);
}
+
if (ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag &&
cookie->tie_tag_my_vtag == 0 &&
@@ -1733,7 +1735,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
* If nat support, and the below and stcb is established, send back
* a ABORT(colliding state) if we are established.
*/
- if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) &&
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) &&
(asoc->peer_supports_nat) &&
((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
@@ -1838,8 +1840,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
asoc->cookie_how[how_indx] = 10;
return (NULL);
}
- if ((asoc->state & SCTP_STATE_COOKIE_WAIT) ||
- (asoc->state & SCTP_STATE_COOKIE_ECHOED)) {
+ if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
*notification = SCTP_NOTIFY_ASSOC_UP;
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
@@ -1867,17 +1869,17 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_UNLOCK(so, 1);
#endif
}
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
else
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
- } else if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
+ } else if (SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
SCTP_STAT_INCR_COUNTER32(sctps_restartestab);
} else {
SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
}
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
@@ -1937,24 +1939,24 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* notify upper layer */
*notification = SCTP_NOTIFY_ASSOC_RESTART;
atomic_add_int(&stcb->asoc.refcnt, 1);
- if ((SCTP_GET_STATE(asoc) != SCTP_STATE_OPEN) &&
- (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
- (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
+ if ((SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) &&
+ (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
+ (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT)) {
SCTP_STAT_INCR_GAUGE32(sctps_currestab);
}
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
SCTP_STAT_INCR_GAUGE32(sctps_restartestab);
- } else if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
+ } else if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) {
SCTP_STAT_INCR_GAUGE32(sctps_collisionestab);
}
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
- } else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
+ } else if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) {
/* move to OPEN state, if not in SHUTDOWN_SENT */
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
}
asoc->pre_open_streams =
ntohs(initack_cp->init.num_outbound_streams);
@@ -2293,6 +2295,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
stcb->asoc.authenticated = 1;
}
}
+
/*
* if we're doing ASCONFs, check to see if we have any new local
* addresses that need to get added to the peer (eg. addresses
@@ -2342,7 +2345,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* update current state */
SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
stcb->sctp_ep, stcb, asoc->primary_destination);
@@ -2590,6 +2593,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
(uint32_t)offset, cookie_offset, sig_offset);
return (NULL);
}
+
/*
* check the cookie timestamps to be sure it's not stale
*/
@@ -2710,6 +2714,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
}
}
+
cookie_len -= SCTP_SIGNATURE_SIZE;
if (*stcb == NULL) {
/* this is the "normal" case... get a new TCB */
@@ -2877,7 +2882,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
* the accept state waiting for the accept!
*/
if (*stcb) {
- (*stcb)->asoc.state |= SCTP_STATE_IN_ACCEPT_QUEUE;
+ SCTP_ADD_SUBSTATE(*stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
}
sctp_move_pcb_and_assoc(*inp_p, inp, *stcb);
@@ -2912,6 +2917,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
(*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
}
+
/*
* Pull it from the incomplete queue and wake the
* guy
@@ -2952,6 +2958,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
if ((stcb == NULL) || (net == NULL)) {
return;
}
+
asoc = &stcb->asoc;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
@@ -2963,10 +2970,10 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
asoc->overall_error_count = 0;
sctp_stop_all_cookie_timers(stcb);
/* process according to association state */
- if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED) {
/* state change only needed when I am in right state */
SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
- SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
+ SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
sctp_start_net_timers(stcb);
if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
@@ -3018,6 +3025,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
*/
goto closed_socket;
}
+
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
stcb, net);
@@ -3224,7 +3232,6 @@ static void
sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSED,
struct sctp_tcb *stcb, struct sctp_nets *net)
{
- struct sctp_association *asoc;
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
#endif
@@ -3234,9 +3241,8 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
if (stcb == NULL)
return;
- asoc = &stcb->asoc;
/* process according to association state */
- if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
+ if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
/* unexpected SHUTDOWN-COMPLETE... so ignore... */
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_shutdown_complete: not in SCTP_STATE_SHUTDOWN_ACK_SENT --- ignore\n");
@@ -3248,8 +3254,8 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
}
#ifdef INVARIANTS
- if (!TAILQ_EMPTY(&asoc->send_queue) ||
- !TAILQ_EMPTY(&asoc->sent_queue) ||
+ if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
+ !TAILQ_EMPTY(&stcb->asoc.sent_queue) ||
sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
}
@@ -3796,6 +3802,7 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
sctp_log_map(0, 7, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
}
+
stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
@@ -4395,6 +4402,7 @@ sctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
if (trunc_len > limit) {
trunc_len = limit;
}
+
/* now the chunks themselves */
while ((ch != NULL) && (chlen >= sizeof(struct sctp_chunkhdr))) {
desc.chunk_type = ch->chunk_type;
@@ -4654,6 +4662,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*/
SCTP_INP_DECR_REF(inp);
}
+
/* now go back and verify any auth chunk to be sure */
if (auth_skipped && (stcb != NULL)) {
struct sctp_auth_chunk *auth;
@@ -4748,11 +4757,12 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
if (((ch->chunk_type == SCTP_SELECTIVE_ACK) ||
(ch->chunk_type == SCTP_NR_SELECTIVE_ACK) ||
(ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
- (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
+ (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
/* implied cookie-ack.. we must have lost the ack */
sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb,
*netp);
}
+
process_control_chunks:
while (IS_SCTP_CONTROL(ch)) {
/* validate chunk length */
@@ -4792,6 +4802,7 @@ process_control_chunks:
}
return (NULL);
}
+
num_chunks++;
/* Save off the last place we got a control from */
if (stcb != NULL) {
@@ -4811,7 +4822,6 @@ process_control_chunks:
/* check to see if this chunk required auth, but isn't */
if ((stcb != NULL) &&
- (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) &&
!stcb->asoc.authenticated) {
/* "silently" ignore */
@@ -4941,7 +4951,7 @@ process_control_chunks:
break;
}
}
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
+ if (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
/*-
* If we have sent a shutdown-ack, we will pay no
* attention to a sack sent in to us since
@@ -5159,6 +5169,7 @@ process_control_chunks:
goto abend;
}
}
+
if (netp != NULL) {
struct sctp_tcb *locked_stcb;
@@ -5331,6 +5342,7 @@ process_control_chunks:
*offset = length;
return (stcb);
}
+
if (stcb != NULL) {
int abort_flag = 0;
@@ -5393,6 +5405,7 @@ process_control_chunks:
*offset = length;
return (stcb);
}
+
if ((ch != NULL) && (stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
if (stcb->asoc.pktdrop_supported == 0) {
goto unknown_chunk;
@@ -5559,6 +5572,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
net->flowtype = mflowtype;
net->flowid = mflowid;
}
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
if ((inp != NULL) && (stcb != NULL)) {
sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
@@ -5599,6 +5613,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
net->flowid = mflowid;
}
if (inp == NULL) {
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
SCTP_STAT_INCR(sctps_noport);
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
goto out;
@@ -5647,6 +5662,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/
SCTP_TCB_UNLOCK(stcb);
stcb = NULL;
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __func__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
@@ -5655,6 +5671,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
vrf_id, port);
goto out;
}
+
}
if (IS_SCTP_CONTROL(ch)) {
/* process the control portion of the SCTP packet */
@@ -5700,14 +5717,15 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* chunks
*/
if ((stcb != NULL) &&
- (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
/* "silently" ignore */
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
SCTP_STAT_INCR(sctps_recvauthmissing);
goto out;
}
if (stcb == NULL) {
/* out of the blue DATA chunk */
+ SCTP_PROBE5(receive, NULL, NULL, m, NULL, sh);
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s", __FILE__, __LINE__, __func__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
msg);
@@ -5718,11 +5736,13 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
/* v_tag mismatch! */
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
SCTP_STAT_INCR(sctps_badvtag);
goto out;
}
}
+ SCTP_PROBE5(receive, NULL, stcb, m, stcb, sh);
if (stcb == NULL) {
/*
* no valid TCB for this packet, or we found it's a bad
@@ -5731,6 +5751,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/
goto out;
}
+
/*
* DATA chunk processing
*/
@@ -5742,7 +5763,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/
if ((length > offset) &&
(stcb != NULL) &&
- (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) &&
!stcb->asoc.authenticated) {
/* "silently" ignore */
@@ -5759,7 +5779,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* not get here unless we really did have a tag, so we don't
* abort if this happens, just dump the chunk silently.
*/
- switch (SCTP_GET_STATE(&stcb->asoc)) {
+ switch (SCTP_GET_STATE(stcb)) {
case SCTP_STATE_COOKIE_ECHOED:
/*
* we consider data with valid tags in this state
@@ -5810,6 +5830,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* process_data
*/
}
+
/* take care of ecn */
if ((data_processed == 1) &&
(stcb->asoc.ecn_supported == 1) &&
@@ -5817,6 +5838,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
/* Yep, we need to add a ECNE */
sctp_send_ecn_echo(stcb, net, high_tsn);
}
+
if ((data_processed == 0) && (fwd_tsn_seen)) {
int was_a_gap;
uint32_t highest_tsn;