Cleanup the handling of control chunks. While there fix some minor

bug related to clearing the assoc retransmit counter and the dup TSN
handling of NR-SACK chunks.

MFC after:	3 days
This commit is contained in:
Michael Tuexen 2017-11-12 21:43:33 +00:00
parent 1ec7755286
commit 469a65d1f8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=325746

View File

@ -633,6 +633,14 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_4);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
old_error_counter = r_net->error_count;
r_net->error_count = 0;
r_net->hb_responded = 1;
@ -2925,7 +2933,14 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
return;
}
asoc = &stcb->asoc;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
asoc->overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
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) {
@ -4718,14 +4733,6 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
(ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
/* implied cookie-ack.. we must have lost the ack */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb,
*netp);
}
@ -4859,7 +4866,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
case SCTP_PAD_CHUNK:
break;
case SCTP_INITIATION_ACK:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n");
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT_ACK\n");
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
/* We are not interested anymore */
if ((stcb != NULL) && (stcb->asoc.total_output_queue_size)) {
@ -4890,7 +4897,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*offset = length;
return (stcb);
}
if ((netp) && (*netp)) {
if ((netp != NULL) && (*netp != NULL)) {
ret = sctp_handle_init_ack(m, iphlen, *offset,
src, dst, sh,
(struct sctp_init_ack_chunk *)ch,
@ -4915,109 +4922,35 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
return (stcb);
break;
case SCTP_SELECTIVE_ACK:
{
struct sctp_sack_chunk *sack;
int abort_now = 0;
uint32_t a_rwnd, cum_ack;
uint16_t num_seg, num_dup;
uint8_t flags;
int offset_seg, offset_dup;
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
SCTP_STAT_INCR(sctps_recvsacks);
if (stcb == NULL) {
SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
break;
}
if (chk_length < sizeof(struct sctp_sack_chunk)) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
break;
}
if (SCTP_GET_STATE(&stcb->asoc) == 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
* we don't care anymore.
*/
break;
}
sack = (struct sctp_sack_chunk *)ch;
flags = ch->chunk_flags;
cum_ack = ntohl(sack->sack.cum_tsn_ack);
num_seg = ntohs(sack->sack.num_gap_ack_blks);
num_dup = ntohs(sack->sack.num_dup_tsns);
a_rwnd = (uint32_t)ntohl(sack->sack.a_rwnd);
if (sizeof(struct sctp_sack_chunk) +
num_seg * sizeof(struct sctp_gap_ack_block) +
num_dup * sizeof(uint32_t) != chk_length) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
break;
}
offset_seg = *offset + sizeof(struct sctp_sack_chunk);
offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
cum_ack, num_seg, a_rwnd);
stcb->asoc.seen_a_sack_this_pkt = 1;
if ((stcb->asoc.pr_sctp_cnt == 0) &&
(num_seg == 0) &&
SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
(stcb->asoc.saw_sack_with_frags == 0) &&
(stcb->asoc.saw_sack_with_nr_frags == 0) &&
(!TAILQ_EMPTY(&stcb->asoc.sent_queue))
) {
/*
* We have a SIMPLE sack having no
* prior segments and data on sent
* queue to be acked.. Use the
* faster path sack processing. We
* also allow window update sacks
* with no missing segments to go
* this way too.
*/
sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now, ecne_seen);
} else {
if (netp && *netp)
sctp_handle_sack(m, offset_seg, offset_dup, stcb,
num_seg, 0, num_dup, &abort_now, flags,
cum_ack, a_rwnd, ecne_seen);
}
if (abort_now) {
/* ABORT signal from sack processing */
*offset = length;
return (NULL);
}
if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
(stcb->asoc.stream_queue_cnt == 0)) {
sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
}
}
break;
/*
* EY - nr_sack: If the received chunk is an
* nr_sack chunk
*/
case SCTP_NR_SELECTIVE_ACK:
{
struct sctp_nr_sack_chunk *nr_sack;
int abort_now = 0;
uint32_t a_rwnd, cum_ack;
uint16_t num_seg, num_nr_seg, num_dup;
uint8_t flags;
int offset_seg, offset_dup;
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
SCTPDBG(SCTP_DEBUG_INPUT3, "%s\n",
ch->chunk_type == SCTP_SELECTIVE_ACK ? "SCTP_SACK" : "SCTP_NR_SACK");
SCTP_STAT_INCR(sctps_recvsacks);
if (stcb == NULL) {
SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing %s chunk\n",
(ch->chunk_type == SCTP_SELECTIVE_ACK) ? "SCTP_SACK" : "SCTP_NR_SACK");
break;
}
if (stcb->asoc.nrsack_supported == 0) {
goto unknown_chunk;
}
if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR-SACK chunk, too small\n");
break;
if (ch->chunk_type == SCTP_SELECTIVE_ACK) {
if (chk_length < sizeof(struct sctp_sack_chunk)) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
break;
}
} else {
if (stcb->asoc.nrsack_supported == 0) {
goto unknown_chunk;
}
if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR_SACK chunk, too small\n");
break;
}
}
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
/*-
@ -5027,22 +4960,44 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*/
break;
}
nr_sack = (struct sctp_nr_sack_chunk *)ch;
flags = ch->chunk_flags;
cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
a_rwnd = (uint32_t)ntohl(nr_sack->nr_sack.a_rwnd);
if (sizeof(struct sctp_nr_sack_chunk) +
(num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
num_dup * sizeof(uint32_t) != chk_length) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
break;
if (ch->chunk_type == SCTP_SELECTIVE_ACK) {
struct sctp_sack_chunk *sack;
sack = (struct sctp_sack_chunk *)ch;
cum_ack = ntohl(sack->sack.cum_tsn_ack);
num_seg = ntohs(sack->sack.num_gap_ack_blks);
num_nr_seg = 0;
num_dup = ntohs(sack->sack.num_dup_tsns);
a_rwnd = ntohl(sack->sack.a_rwnd);
if (sizeof(struct sctp_sack_chunk) +
num_seg * sizeof(struct sctp_gap_ack_block) +
num_dup * sizeof(uint32_t) != chk_length) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
break;
}
offset_seg = *offset + sizeof(struct sctp_sack_chunk);
offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
} else {
struct sctp_nr_sack_chunk *nr_sack;
nr_sack = (struct sctp_nr_sack_chunk *)ch;
cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
a_rwnd = ntohl(nr_sack->nr_sack.a_rwnd);
if (sizeof(struct sctp_nr_sack_chunk) +
(num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
num_dup * sizeof(uint32_t) != chk_length) {
SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
break;
}
offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
offset_dup = offset_seg + (num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block);
}
offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
SCTPDBG(SCTP_DEBUG_INPUT3, "%s process cum_ack:%x num_seg:%d a_rwnd:%d\n",
(ch->chunk_type == SCTP_SELECTIVE_ACK) ? "SCTP_SACK" : "SCTP_NR_SACK",
cum_ack, num_seg, a_rwnd);
stcb->asoc.seen_a_sack_this_pkt = 1;
if ((stcb->asoc.pr_sctp_cnt == 0) &&
@ -5063,10 +5018,11 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
sctp_express_handle_sack(stcb, cum_ack, a_rwnd,
&abort_now, ecne_seen);
} else {
if (netp && *netp)
if ((netp != NULL) && (*netp != NULL)) {
sctp_handle_sack(m, offset_seg, offset_dup, stcb,
num_seg, num_nr_seg, num_dup, &abort_now, flags,
cum_ack, a_rwnd, ecne_seen);
}
}
if (abort_now) {
/* ABORT signal from sack processing */
@ -5078,47 +5034,28 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
(stcb->asoc.stream_queue_cnt == 0)) {
sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
}
break;
}
break;
case SCTP_HEARTBEAT_REQUEST:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT\n");
if ((stcb) && netp && *netp) {
if ((stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
SCTP_STAT_INCR(sctps_recvheartbeat);
sctp_send_heartbeat_ack(stcb, m, *offset,
chk_length, *netp);
/* He's alive so give him credit */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
}
break;
case SCTP_HEARTBEAT_ACK:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT-ACK\n");
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT_ACK\n");
if ((stcb == NULL) || (chk_length != sizeof(struct sctp_heartbeat_chunk))) {
/* Its not ours */
*offset = length;
return (stcb);
}
/* He's alive so give him credit */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
SCTP_STAT_INCR(sctps_recvheartbeatack);
if (netp && *netp)
if ((netp != NULL) && (*netp != NULL)) {
sctp_handle_heartbeat_ack((struct sctp_heartbeat_chunk *)ch,
stcb, *netp);
}
break;
case SCTP_ABORT_ASSOCIATION:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n",
@ -5141,7 +5078,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*offset = length;
return (stcb);
}
if (netp && *netp) {
if ((netp != NULL) && (*netp != NULL)) {
int abort_flag = 0;
sctp_handle_shutdown((struct sctp_shutdown_chunk *)ch,
@ -5153,24 +5090,25 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
}
break;
case SCTP_SHUTDOWN_ACK:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK, stcb %p\n", (void *)stcb);
if ((stcb) && (netp) && (*netp))
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN_ACK, stcb %p\n", (void *)stcb);
if ((stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
sctp_handle_shutdown_ack((struct sctp_shutdown_ack_chunk *)ch, stcb, *netp);
}
*offset = length;
return (NULL);
break;
case SCTP_OPERATION_ERROR:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_OP-ERR\n");
if ((stcb) && netp && *netp && sctp_handle_error(ch, stcb, *netp) < 0) {
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_OP_ERR\n");
if ((stcb != NULL) && (netp != NULL) && (*netp != NULL) &&
sctp_handle_error(ch, stcb, *netp) < 0) {
*offset = length;
return (NULL);
}
break;
case SCTP_COOKIE_ECHO:
SCTPDBG(SCTP_DEBUG_INPUT3,
"SCTP_COOKIE-ECHO, stcb %p\n", (void *)stcb);
if ((stcb) && (stcb->asoc.total_output_queue_size)) {
"SCTP_COOKIE_ECHO, stcb %p\n", (void *)stcb);
if ((stcb != NULL) && (stcb->asoc.total_output_queue_size > 0)) {
;
} else {
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
@ -5224,7 +5162,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
linp = inp;
}
if (linp) {
if (linp != NULL) {
SCTP_ASOC_CREATE_LOCK(linp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
@ -5232,7 +5170,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
goto abend;
}
}
if (netp) {
if (netp != NULL) {
struct sctp_tcb *locked_stcb;
locked_stcb = stcb;
@ -5260,7 +5198,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
} else {
ret_buf = NULL;
}
if (linp) {
if (linp != NULL) {
SCTP_ASOC_CREATE_UNLOCK(linp);
}
if (ret_buf == NULL) {
@ -5290,7 +5228,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
}
break;
case SCTP_COOKIE_ACK:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", (void *)stcb);
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE_ACK, stcb %p\n", (void *)stcb);
if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) {
return (stcb);
}
@ -5316,75 +5254,43 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
return (NULL);
}
}
/* He's alive so give him credit */
if ((stcb) && netp && *netp) {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
if ((netp != NULL) && (*netp != NULL)) {
sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, *netp);
}
break;
case SCTP_ECN_ECHO:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-ECHO\n");
/* He's alive so give him credit */
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN_ECHO\n");
if ((stcb == NULL) || (chk_length != sizeof(struct sctp_ecne_chunk))) {
/* Its not ours */
*offset = length;
return (stcb);
}
if (stcb) {
if (stcb->asoc.ecn_supported == 0) {
goto unknown_chunk;
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch,
stcb);
ecne_seen = 1;
if (stcb->asoc.ecn_supported == 0) {
goto unknown_chunk;
}
sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch, stcb);
ecne_seen = 1;
break;
case SCTP_ECN_CWR:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-CWR\n");
/* He's alive so give him credit */
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN_CWR\n");
if ((stcb == NULL) || (chk_length != sizeof(struct sctp_cwr_chunk))) {
*offset = length;
return (stcb);
}
if (stcb) {
if (stcb->asoc.ecn_supported == 0) {
goto unknown_chunk;
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
if (stcb->asoc.ecn_supported == 0) {
goto unknown_chunk;
}
sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
break;
case SCTP_SHUTDOWN_COMPLETE:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE, stcb %p\n", (void *)stcb);
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN_COMPLETE, stcb %p\n", (void *)stcb);
/* must be first and only chunk */
if ((num_chunks > 1) ||
(length - *offset > (int)SCTP_SIZE32(chk_length))) {
*offset = length;
return (stcb);
}
if ((stcb) && netp && *netp) {
if ((stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
sctp_handle_shutdown_complete((struct sctp_shutdown_complete_chunk *)ch,
stcb, *netp);
}
@ -5393,32 +5299,23 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
break;
case SCTP_ASCONF:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF\n");
/* He's alive so give him credit */
if (stcb) {
if (stcb != NULL) {
if (stcb->asoc.asconf_supported == 0) {
goto unknown_chunk;
}
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_asconf(m, *offset, src,
(struct sctp_asconf_chunk *)ch, stcb, asconf_cnt == 0);
asconf_cnt++;
}
break;
case SCTP_ASCONF_ACK:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF-ACK\n");
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF_ACK\n");
if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) {
/* Its not ours */
*offset = length;
return (stcb);
}
if ((stcb) && netp && *netp) {
if ((stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
if (stcb->asoc.asconf_supported == 0) {
goto unknown_chunk;
}
@ -5439,27 +5336,18 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
break;
case SCTP_FORWARD_CUM_TSN:
case SCTP_IFORWARD_CUM_TSN:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD-TSN\n");
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD_TSN\n");
if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) {
/* Its not ours */
*offset = length;
return (stcb);
}
/* He's alive so give him credit */
if (stcb) {
if (stcb != NULL) {
int abort_flag = 0;
if (stcb->asoc.prsctp_supported == 0) {
goto unknown_chunk;
}
stcb->asoc.overall_error_count = 0;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
*fwd_tsn_seen = 1;
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
/* We are not interested anymore */
@ -5489,17 +5377,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
if (abort_flag) {
*offset = length;
return (NULL);
} else {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
}
}
break;
case SCTP_STREAM_RESET:
@ -5526,7 +5404,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*offset = length;
return (stcb);
}
if (ch && (stcb) && netp && (*netp)) {
if ((ch != NULL) && (stcb != NULL) && (netp != NULL) && (*netp != NULL)) {
if (stcb->asoc.pktdrop_supported == 0) {
goto unknown_chunk;
}
@ -5625,7 +5503,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
}
} /* while */
if (asconf_cnt > 0 && stcb != NULL) {
if ((asconf_cnt > 0) && (stcb != NULL)) {
sctp_send_asconf_ack(stcb);
}
return (stcb);
@ -5903,14 +5781,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* shows us the cookie-ack was lost. Imply it was
* there.
*/
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
0,
SCTP_FROM_SCTP_INPUT,
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, net);
break;
case SCTP_STATE_COOKIE_WAIT: