Lines Matching +full:shutdown +full:- +full:ack

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
66 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_stop_all_cookie_timers()
67 if (net->rxt_timer.type == SCTP_TIMER_TYPE_COOKIE) { in sctp_stop_all_cookie_timers()
69 stcb->sctp_ep, in sctp_stop_all_cookie_timers()
72 } else if (net->rxt_timer.type == SCTP_TIMER_TYPE_INIT) { in sctp_stop_all_cookie_timers()
74 stcb->sctp_ep, in sctp_stop_all_cookie_timers()
99 init = &cp->init; in sctp_handle_init()
100 if (ntohl(init->initiate_tag) == 0) { in sctp_handle_init()
103 if ((ntohl(init->a_rwnd) < SCTP_MIN_RWND) || in sctp_handle_init()
104 (ntohs(init->num_inbound_streams) == 0) || in sctp_handle_init()
105 (ntohs(init->num_outbound_streams) == 0)) { in sctp_handle_init()
108 sctp_send_abort(m, iphlen, src, dst, sh, init->initiate_tag, op_err, in sctp_handle_init()
109 mflowtype, mflowid, inp->fibnum, in sctp_handle_init()
114 offset + ntohs(cp->ch.chunk_length))) { in sctp_handle_init()
118 sctp_send_abort(m, iphlen, src, dst, sh, init->initiate_tag, op_err, in sctp_handle_init()
119 mflowtype, mflowid, inp->fibnum, in sctp_handle_init()
125 ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || in sctp_handle_init()
126 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_handle_init()
133 * just send back the INIT-ACK and hope that the app did in sctp_handle_init()
138 * state :-) in sctp_handle_init()
144 mflowtype, mflowid, inp->fibnum, in sctp_handle_init()
151 SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending SHUTDOWN-ACK\n"); in sctp_handle_init()
155 SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n"); in sctp_handle_init()
168 * process peer "INIT/INIT-ACK" chunk returns value < 0 on error
186 asoc = &stcb->asoc; in sctp_is_there_unsent_data()
188 if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) { in sctp_is_there_unsent_data()
190 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_is_there_unsent_data()
192 sp = TAILQ_FIRST(&stcb->asoc.strmout[i].outqueue); in sctp_is_there_unsent_data()
196 if ((sp->msg_is_complete) && in sctp_is_there_unsent_data()
197 (sp->length == 0) && in sctp_is_there_unsent_data()
198 (sp->sender_all_done)) { in sctp_is_there_unsent_data()
204 if (sp->put_last_out == 0) { in sctp_is_there_unsent_data()
205 SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n"); in sctp_is_there_unsent_data()
207 sp->sender_all_done, in sctp_is_there_unsent_data()
208 sp->length, in sctp_is_there_unsent_data()
209 sp->msg_is_complete, in sctp_is_there_unsent_data()
210 sp->put_last_out); in sctp_is_there_unsent_data()
212 atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1); in sctp_is_there_unsent_data()
213 TAILQ_REMOVE(&stcb->asoc.strmout[i].outqueue, sp, next); in sctp_is_there_unsent_data()
214 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, &asoc->strmout[i], sp); in sctp_is_there_unsent_data()
215 if (sp->net) { in sctp_is_there_unsent_data()
216 sctp_free_remote_addr(sp->net); in sctp_is_there_unsent_data()
217 sp->net = NULL; in sctp_is_there_unsent_data()
219 if (sp->data) { in sctp_is_there_unsent_data()
220 sctp_m_freem(sp->data); in sctp_is_there_unsent_data()
221 sp->data = NULL; in sctp_is_there_unsent_data()
224 if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) { in sctp_is_there_unsent_data()
248 init = &cp->init; in sctp_process_init()
249 asoc = &stcb->asoc; in sctp_process_init()
251 asoc->peer_vtag = ntohl(init->initiate_tag); in sctp_process_init()
252 asoc->peers_rwnd = ntohl(init->a_rwnd); in sctp_process_init()
254 asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1; in sctp_process_init()
256 if (!TAILQ_EMPTY(&asoc->nets)) { in sctp_process_init()
258 TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) { in sctp_process_init()
259 lnet->ssthresh = asoc->peers_rwnd; in sctp_process_init()
265 if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) { in sctp_process_init()
272 newcnt = ntohs(init->num_inbound_streams); in sctp_process_init()
273 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { in sctp_process_init()
274 if (chk->rec.data.sid >= newcnt) { in sctp_process_init()
275 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); in sctp_process_init()
276 asoc->send_queue_cnt--; in sctp_process_init()
277 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) { in sctp_process_init()
278 asoc->strmout[chk->rec.data.sid].chunks_on_queues--; in sctp_process_init()
281 panic("No chunks on the queues for sid %u.", chk->rec.data.sid); in sctp_process_init()
284 if (chk->data != NULL) { in sctp_process_init()
288 if (chk->data) { in sctp_process_init()
289 sctp_m_freem(chk->data); in sctp_process_init()
290 chk->data = NULL; in sctp_process_init()
297 if (asoc->strmout) { in sctp_process_init()
298 for (i = newcnt; i < asoc->pre_open_streams; i++) { in sctp_process_init()
299 outs = &asoc->strmout[i]; in sctp_process_init()
300 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { in sctp_process_init()
301 atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1); in sctp_process_init()
302 TAILQ_REMOVE(&outs->outqueue, sp, next); in sctp_process_init()
303 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp); in sctp_process_init()
306 if (sp->data) { in sctp_process_init()
307 sctp_m_freem(sp->data); in sctp_process_init()
308 sp->data = NULL; in sctp_process_init()
310 if (sp->net) { in sctp_process_init()
311 sctp_free_remote_addr(sp->net); in sctp_process_init()
312 sp->net = NULL; in sctp_process_init()
318 outs->state = SCTP_STREAM_CLOSED; in sctp_process_init()
322 asoc->pre_open_streams = newcnt; in sctp_process_init()
324 asoc->streamoutcnt = asoc->pre_open_streams; in sctp_process_init()
325 if (asoc->strmout) { in sctp_process_init()
326 for (i = 0; i < asoc->streamoutcnt; i++) { in sctp_process_init()
327 asoc->strmout[i].state = SCTP_STREAM_OPEN; in sctp_process_init()
330 /* EY - nr_sack: initialize highest tsn in nr_mapping_array */ in sctp_process_init()
331 asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map; in sctp_process_init()
333 sctp_log_map(0, 5, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); in sctp_process_init()
336 asoc->str_reset_seq_in = asoc->asconf_seq_in + 1; in sctp_process_init()
338 asoc->mapping_array_base_tsn = ntohl(init->initial_tsn); in sctp_process_init()
339 asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in; in sctp_process_init()
341 asoc->advanced_peer_ack_point = asoc->last_acked_seq; in sctp_process_init()
344 if (asoc->strmin != NULL) { in sctp_process_init()
346 for (i = 0; i < asoc->streamincnt; i++) { in sctp_process_init()
347 sctp_clean_up_stream(stcb, &asoc->strmin[i].inqueue); in sctp_process_init()
348 sctp_clean_up_stream(stcb, &asoc->strmin[i].uno_inqueue); in sctp_process_init()
350 SCTP_FREE(asoc->strmin, SCTP_M_STRMI); in sctp_process_init()
352 if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) { in sctp_process_init()
353 asoc->streamincnt = ntohs(init->num_outbound_streams); in sctp_process_init()
355 asoc->streamincnt = asoc->max_inbound_streams; in sctp_process_init()
357 SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt * in sctp_process_init()
359 if (asoc->strmin == NULL) { in sctp_process_init()
362 return (-1); in sctp_process_init()
364 for (i = 0; i < asoc->streamincnt; i++) { in sctp_process_init()
365 asoc->strmin[i].sid = i; in sctp_process_init()
366 asoc->strmin[i].last_mid_delivered = 0xffffffff; in sctp_process_init()
367 TAILQ_INIT(&asoc->strmin[i].inqueue); in sctp_process_init()
368 TAILQ_INIT(&asoc->strmin[i].uno_inqueue); in sctp_process_init()
369 asoc->strmin[i].pd_api_started = 0; in sctp_process_init()
370 asoc->strmin[i].delivery_started = 0; in sctp_process_init()
374 * association when the COOKIE is processed or the INIT-ACK is in sctp_process_init()
386 * INIT-ACK message processing/consumption returns value < 0 on error
412 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_init_ack()
415 vrf_id, net->port); in sctp_process_init_ack()
417 return (-1); in sctp_process_init_ack()
435 cause->cause.code = htons(SCTP_CAUSE_MISSING_PARAM); in sctp_process_init_ack()
436 cause->cause.length = htons(len); in sctp_process_init_ack()
437 cause->num_missing_params = htonl(1); in sctp_process_init_ack()
438 cause->type[0] = htons(SCTP_STATE_COOKIE); in sctp_process_init_ack()
440 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_init_ack()
443 vrf_id, net->port); in sctp_process_init_ack()
445 return (-3); in sctp_process_init_ack()
447 asoc = &stcb->asoc; in sctp_process_init_ack()
448 asoc->peer_supports_nat = (uint8_t)nat_friendly; in sctp_process_init_ack()
449 /* process the peer's parameters in the INIT-ACK */ in sctp_process_init_ack()
456 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_init_ack()
459 vrf_id, net->port); in sctp_process_init_ack()
461 return (-1); in sctp_process_init_ack()
463 initack_limit = offset + ntohs(cp->ch.chunk_length); in sctp_process_init_ack()
467 initack_limit, src, dst, NULL, stcb->asoc.port)) < 0) { in sctp_process_init_ack()
476 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_init_ack()
479 vrf_id, net->port); in sctp_process_init_ack()
481 return (-1); in sctp_process_init_ack()
484 if (asoc->asconf_supported == 0) { in sctp_process_init_ack()
487 TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) { in sctp_process_init_ack()
488 TAILQ_REMOVE(&asoc->asconf_queue, param, next); in sctp_process_init_ack()
493 stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs, in sctp_process_init_ack()
494 stcb->asoc.local_hmacs); in sctp_process_init_ack()
503 stcb->asoc.overall_error_count, in sctp_process_init_ack()
515 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, stcb, in sctp_process_init_ack()
516 asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3); in sctp_process_init_ack()
519 if (asoc->overall_error_count == 0) { in sctp_process_init_ack()
520 sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, in sctp_process_init_ack()
523 stcb->asoc.overall_error_count = 0; in sctp_process_init_ack()
524 net->error_count = 0; in sctp_process_init_ack()
539 if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) { in sctp_handle_heartbeat_ack()
545 switch (cp->heartbeat.hb_info.addr_family) { in sctp_handle_heartbeat_ack()
548 if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) { in sctp_handle_heartbeat_ack()
549 store.sin.sin_family = cp->heartbeat.hb_info.addr_family; in sctp_handle_heartbeat_ack()
550 store.sin.sin_len = cp->heartbeat.hb_info.addr_len; in sctp_handle_heartbeat_ack()
551 store.sin.sin_port = stcb->rport; in sctp_handle_heartbeat_ack()
552 memcpy(&store.sin.sin_addr, cp->heartbeat.hb_info.address, in sctp_handle_heartbeat_ack()
561 if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) { in sctp_handle_heartbeat_ack()
562 store.sin6.sin6_family = cp->heartbeat.hb_info.addr_family; in sctp_handle_heartbeat_ack()
563 store.sin6.sin6_len = cp->heartbeat.hb_info.addr_len; in sctp_handle_heartbeat_ack()
564 store.sin6.sin6_port = stcb->rport; in sctp_handle_heartbeat_ack()
565 memcpy(&store.sin6.sin6_addr, cp->heartbeat.hb_info.address, sizeof(struct in6_addr)); in sctp_handle_heartbeat_ack()
579 if ((r_net && (r_net->dest_state & SCTP_ADDR_UNCONFIRMED)) && in sctp_handle_heartbeat_ack()
580 (r_net->heartbeat_random1 == cp->heartbeat.hb_info.random_value1) && in sctp_handle_heartbeat_ack()
581 (r_net->heartbeat_random2 == cp->heartbeat.hb_info.random_value2)) { in sctp_handle_heartbeat_ack()
586 r_net->dest_state &= ~SCTP_ADDR_UNCONFIRMED; in sctp_handle_heartbeat_ack()
587 if (r_net->dest_state & SCTP_ADDR_REQ_PRIMARY) { in sctp_handle_heartbeat_ack()
588 stcb->asoc.primary_destination = r_net; in sctp_handle_heartbeat_ack()
589 r_net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY; in sctp_handle_heartbeat_ack()
590 f_net = TAILQ_FIRST(&stcb->asoc.nets); in sctp_handle_heartbeat_ack()
598 TAILQ_REMOVE(&stcb->asoc.nets, r_net, sctp_next); in sctp_handle_heartbeat_ack()
599 TAILQ_INSERT_HEAD(&stcb->asoc.nets, r_net, sctp_next); in sctp_handle_heartbeat_ack()
605 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, in sctp_handle_heartbeat_ack()
607 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net); in sctp_handle_heartbeat_ack()
611 stcb->asoc.overall_error_count, in sctp_handle_heartbeat_ack()
616 stcb->asoc.overall_error_count = 0; in sctp_handle_heartbeat_ack()
617 old_error_counter = r_net->error_count; in sctp_handle_heartbeat_ack()
618 r_net->error_count = 0; in sctp_handle_heartbeat_ack()
619 r_net->hb_responded = 1; in sctp_handle_heartbeat_ack()
620 tv.tv_sec = cp->heartbeat.hb_info.time_value_1; in sctp_handle_heartbeat_ack()
621 tv.tv_usec = cp->heartbeat.hb_info.time_value_2; in sctp_handle_heartbeat_ack()
623 sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, in sctp_handle_heartbeat_ack()
625 if ((r_net->dest_state & SCTP_ADDR_REACHABLE) == 0) { in sctp_handle_heartbeat_ack()
626 r_net->dest_state |= SCTP_ADDR_REACHABLE; in sctp_handle_heartbeat_ack()
630 if (r_net->dest_state & SCTP_ADDR_PF) { in sctp_handle_heartbeat_ack()
631 r_net->dest_state &= ~SCTP_ADDR_PF; in sctp_handle_heartbeat_ack()
632 stcb->asoc.cc_functions.sctp_cwnd_update_exit_pf(stcb, net); in sctp_handle_heartbeat_ack()
635 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, in sctp_handle_heartbeat_ack()
637 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net); in sctp_handle_heartbeat_ack()
639 if (r_net == stcb->asoc.primary_destination) { in sctp_handle_heartbeat_ack()
640 if (stcb->asoc.alternate) { in sctp_handle_heartbeat_ack()
642 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_handle_heartbeat_ack()
643 stcb->asoc.alternate = NULL; in sctp_handle_heartbeat_ack()
648 if ((sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_handle_heartbeat_ack()
650 sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_handle_heartbeat_ack()
652 sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_handle_heartbeat_ack()
655 stcb->sctp_ep, stcb, NULL, in sctp_handle_heartbeat_ack()
657 if (sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_handle_heartbeat_ack()
660 stcb->asoc.primary_destination); in sctp_handle_heartbeat_ack()
662 if (sctp_is_mobility_feature_on(stcb->sctp_ep, in sctp_handle_heartbeat_ack()
665 stcb->asoc.deleted_primary); in sctp_handle_heartbeat_ack()
667 sctp_delete_prim_timer(stcb->sctp_ep, stcb); in sctp_handle_heartbeat_ack()
676 * Return 0 means we want you to proceed with the abort non-zero in sctp_handle_nat_colliding_state()
684 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_handle_nat_colliding_state()
688 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_handle_nat_colliding_state()
692 new_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1); in sctp_handle_nat_colliding_state()
696 stcb->asoc.my_vtag = new_vtag; in sctp_handle_nat_colliding_state()
697 …head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashaso… in sctp_handle_nat_colliding_state()
704 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_nat_colliding_state()
708 * treat like a case where the cookie expired i.e.: - dump in sctp_handle_nat_colliding_state()
709 * current cookie. - generate a new vtag. - resend init. in sctp_handle_nat_colliding_state()
715 sctp_toss_old_cookies(stcb, &stcb->asoc); in sctp_handle_nat_colliding_state()
716 stcb->asoc.my_vtag = new_vtag; in sctp_handle_nat_colliding_state()
717 …head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashaso… in sctp_handle_nat_colliding_state()
724 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_nat_colliding_state()
735 * return 0 means we want you to proceed with the abort non-zero in sctp_handle_nat_missing_state()
738 if (stcb->asoc.auth_supported == 0) { in sctp_handle_nat_missing_state()
758 len = ntohs(abort->ch.chunk_length); in sctp_handle_abort()
767 error = ntohs(cause->code); in sctp_handle_abort()
770 abort->ch.chunk_flags); in sctp_handle_abort()
776 abort->ch.chunk_flags); in sctp_handle_abort()
785 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, in sctp_handle_abort()
798 (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, in sctp_handle_abort()
811 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_start_net_timers()
817 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net); in sctp_start_net_timers()
818 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); in sctp_start_net_timers()
819 if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) && in sctp_start_net_timers()
826 sctp_chunk_output(stcb->sctp_ep, stcb, in sctp_start_net_timers()
841 asoc = &stcb->asoc; in sctp_check_data_from_peer()
842 if (SCTP_TSN_GT(asoc->highest_tsn_inside_map, asoc->cumulative_tsn) || in sctp_check_data_from_peer()
843 SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn)) { in sctp_check_data_from_peer()
848 for (i = 0; i < asoc->streamincnt; i++) { in sctp_check_data_from_peer()
849 if (!TAILQ_EMPTY(&asoc->strmin[i].inqueue) || in sctp_check_data_from_peer()
850 !TAILQ_EMPTY(&asoc->strmin[i].uno_inqueue)) { in sctp_check_data_from_peer()
859 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INPUT + SCTP_LOC_9; in sctp_check_data_from_peer()
860 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_check_data_from_peer()
871 SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_shutdown: handling SHUTDOWN\n"); in sctp_handle_shutdown()
878 if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_shutdown_chunk)) { in sctp_handle_shutdown()
879 /* Shutdown NOT the expected size */ in sctp_handle_shutdown()
891 if (stcb->sctp_socket) { in sctp_handle_shutdown()
898 * shutdown in sctp_handle_shutdown()
903 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); in sctp_handle_shutdown()
908 * stop the shutdown timer, since we WILL move to in sctp_handle_shutdown()
909 * SHUTDOWN-ACK-SENT. in sctp_handle_shutdown()
911 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, in sctp_handle_shutdown()
917 if (!TAILQ_EMPTY(&stcb->asoc.send_queue) || in sctp_handle_shutdown()
918 !TAILQ_EMPTY(&stcb->asoc.sent_queue) || in sctp_handle_shutdown()
924 /* send SHUTDOWN-ACK */ in sctp_handle_shutdown()
925 /* move to SHUTDOWN-ACK-SENT state */ in sctp_handle_shutdown()
935 stcb->sctp_ep, stcb, net); in sctp_handle_shutdown()
950 "sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n"); in sctp_handle_shutdown_ack()
958 /* unexpected SHUTDOWN-ACK... do OOTB handling... */ in sctp_handle_shutdown_ack()
965 /* unexpected SHUTDOWN-ACK... so ignore... */ in sctp_handle_shutdown_ack()
974 if (!TAILQ_EMPTY(&stcb->asoc.send_queue) || in sctp_handle_shutdown_ack()
975 !TAILQ_EMPTY(&stcb->asoc.sent_queue) || in sctp_handle_shutdown_ack()
977 panic("Queues are not empty when handling SHUTDOWN-ACK"); in sctp_handle_shutdown_ack()
981 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, in sctp_handle_shutdown_ack()
983 /* send SHUTDOWN-COMPLETE */ in sctp_handle_shutdown_ack()
986 if (stcb->sctp_socket) { in sctp_handle_shutdown_ack()
987 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_handle_shutdown_ack()
988 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { in sctp_handle_shutdown_ack()
989 SCTP_SB_CLEAR(stcb->sctp_socket->so_snd); in sctp_handle_shutdown_ack()
995 (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, in sctp_handle_shutdown_ack()
1009 stcb->asoc.prsctp_supported = 0; in sctp_process_unrecog_chunk()
1029 /* pr-sctp draft */ in sctp_process_unrecog_param()
1031 stcb->asoc.prsctp_supported = 0; in sctp_process_unrecog_param()
1035 /* draft-ietf-tsvwg-addip-sctp */ in sctp_process_unrecog_param()
1037 stcb->asoc.peer_supports_nat = 0; in sctp_process_unrecog_param()
1042 stcb->asoc.asconf_supported = 0; in sctp_process_unrecog_param()
1049 stcb->asoc.asconf_supported = 0; in sctp_process_unrecog_param()
1069 asoc = &stcb->asoc; in sctp_handle_error()
1072 remaining_length = ntohs(ch->chunk_length); in sctp_handle_error()
1077 remaining_length -= sizeof(struct sctp_chunkhdr); in sctp_handle_error()
1084 cause_code = ntohs(cause->code); in sctp_handle_error()
1085 cause_length = ntohs(cause->length); in sctp_handle_error()
1088 SCTPDBG(SCTP_DEBUG_INPUT1, "Bogus length in cause - bytes left: %u cause length: %u\n", in sctp_handle_error()
1106 ch->chunk_flags); in sctp_handle_error()
1113 ch->chunk_flags); in sctp_handle_error()
1129 asoc->stale_cookie_count++; in sctp_handle_error()
1130 if (asoc->stale_cookie_count > asoc->max_init_times) { in sctp_handle_error()
1132 (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, in sctp_handle_error()
1134 return (-1); in sctp_handle_error()
1137 stale_time = ntohl(stale_cookie->stale_time); in sctp_handle_error()
1141 timevalsub(&now, &asoc->time_entered); in sctp_handle_error()
1150 * non-zero. in sctp_handle_error()
1155 asoc->cookie_preserve_req = (uint32_t)stale_time; in sctp_handle_error()
1156 if (asoc->overall_error_count == 0) { in sctp_handle_error()
1157 sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, in sctp_handle_error()
1160 asoc->overall_error_count = 0; in sctp_handle_error()
1162 sctp_toss_old_cookies(stcb, &stcb->asoc); in sctp_handle_error()
1165 (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered); in sctp_handle_error()
1166 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_error()
1187 sctp_process_unrecog_chunk(stcb, unrec_chunk->ch.chunk_type); in sctp_handle_error()
1196 sctp_process_unrecog_param(stcb, ntohs(unrec_parameter->param_type)); in sctp_handle_error()
1212 * ASCONF-ACK. in sctp_handle_error()
1223 * OP-ERROR. in sctp_handle_error()
1233 remaining_length -= adjust; in sctp_handle_error()
1255 "sctp_handle_init_ack: handling INIT-ACK\n"); in sctp_handle_init_ack()
1260 return (-1); in sctp_handle_init_ack()
1262 /* Only process the INIT-ACK chunk in COOKIE WAIT state. */ in sctp_handle_init_ack()
1264 init_ack = &cp->init; in sctp_handle_init_ack()
1266 if ((ntohl(init_ack->initiate_tag) == 0) || in sctp_handle_init_ack()
1267 (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) || in sctp_handle_init_ack()
1268 (ntohs(init_ack->num_inbound_streams) == 0) || in sctp_handle_init_ack()
1269 (ntohs(init_ack->num_outbound_streams) == 0)) { in sctp_handle_init_ack()
1272 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_handle_init_ack()
1275 vrf_id, net->port); in sctp_handle_init_ack()
1277 return (-1); in sctp_handle_init_ack()
1279 if (stcb->asoc.primary_destination->dest_state & in sctp_handle_init_ack()
1283 * always consider it confirmed when the INIT-ACK is in sctp_handle_init_ack()
1287 stcb->asoc.primary_destination->dest_state &= in sctp_handle_init_ack()
1290 stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED); in sctp_handle_init_ack()
1297 return (-1); in sctp_handle_init_ack()
1300 SCTPDBG(SCTP_DEBUG_INPUT2, "moving to COOKIE-ECHOED state\n"); in sctp_handle_init_ack()
1306 stcb->asoc.overall_error_count, in sctp_handle_init_ack()
1311 stcb->asoc.overall_error_count = 0; in sctp_handle_init_ack()
1312 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); in sctp_handle_init_ack()
1317 sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, stcb->sctp_ep, in sctp_handle_init_ack()
1323 SCTPDBG(SCTP_DEBUG_INPUT1, "Leaving handle-init-ack end\n"); in sctp_handle_init_ack()
1326 return (-1); in sctp_handle_init_ack()
1342 * chain-- assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a
1344 * mbuf to the cookie-echo chunk
1375 /* I know that the TCB is non-NULL from the caller */ in sctp_process_cookie_existing()
1376 asoc = &stcb->asoc; in sctp_process_cookie_existing()
1377 for (how_indx = 0; how_indx < sizeof(asoc->cookie_how); how_indx++) { in sctp_process_cookie_existing()
1378 if (asoc->cookie_how[how_indx] == 0) in sctp_process_cookie_existing()
1381 if (how_indx < sizeof(asoc->cookie_how)) { in sctp_process_cookie_existing()
1382 asoc->cookie_how[how_indx] = 1; in sctp_process_cookie_existing()
1385 /* SHUTDOWN came in after sending INIT-ACK */ in sctp_process_cookie_existing()
1386 sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination); in sctp_process_cookie_existing()
1388 sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, in sctp_process_cookie_existing()
1389 mflowtype, mflowid, inp->fibnum, in sctp_process_cookie_existing()
1390 vrf_id, net->port); in sctp_process_cookie_existing()
1391 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1392 asoc->cookie_how[how_indx] = 2; in sctp_process_cookie_existing()
1398 * INIT should start after the cookie-echo header struct (chunk in sctp_process_cookie_existing()
1411 if (init_cp->ch.chunk_type != SCTP_INITIATION) { in sctp_process_cookie_existing()
1416 * find and validate the INIT-ACK chunk in the cookie (my info) the in sctp_process_cookie_existing()
1417 * INIT-ACK follows the INIT chunk in sctp_process_cookie_existing()
1419 initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length)); in sctp_process_cookie_existing()
1424 /* could not pull INIT-ACK chunk in cookie */ in sctp_process_cookie_existing()
1428 if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) { in sctp_process_cookie_existing()
1432 if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) && in sctp_process_cookie_existing()
1433 (ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag)) { in sctp_process_cookie_existing()
1438 if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) { in sctp_process_cookie_existing()
1439 /*- in sctp_process_cookie_existing()
1443 * <---INIT(tag=a)------ in sctp_process_cookie_existing()
1444 * ----INIT-ACK(tag=t)--> in sctp_process_cookie_existing()
1445 * ----INIT(tag=t)------> *1 in sctp_process_cookie_existing()
1446 * <---INIT-ACK(tag=a)--- in sctp_process_cookie_existing()
1447 * <----CE(tag=t)------------- *2 in sctp_process_cookie_existing()
1453 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1454 asoc->cookie_how[how_indx] = 17; in sctp_process_cookie_existing()
1469 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1470 asoc->cookie_how[how_indx] = 3; in sctp_process_cookie_existing()
1473 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1476 vrf_id, net->port); in sctp_process_cookie_existing()
1495 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_process_cookie_existing()
1496 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && in sctp_process_cookie_existing()
1501 * init/init-ack/cookie done before the in sctp_process_cookie_existing()
1502 * init-ack came back.. in sctp_process_cookie_existing()
1504 sctp_pcb_add_flags(stcb->sctp_ep, SCTP_PCB_FLAGS_CONNECTED); in sctp_process_cookie_existing()
1505 soisconnected(stcb->sctp_socket); in sctp_process_cookie_existing()
1509 net->hb_responded = 1; in sctp_process_cookie_existing()
1510 if (stcb->asoc.sctp_autoclose_ticks && in sctp_process_cookie_existing()
1519 * have simply lost the COOKIE-ACK in sctp_process_cookie_existing()
1526 initack_offset, src, dst, init_src, stcb->asoc.port)) < 0) { in sctp_process_cookie_existing()
1527 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1528 asoc->cookie_how[how_indx] = 4; in sctp_process_cookie_existing()
1534 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1537 vrf_id, net->port); in sctp_process_cookie_existing()
1540 /* respond with a COOKIE-ACK */ in sctp_process_cookie_existing()
1543 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1544 asoc->cookie_how[how_indx] = 5; in sctp_process_cookie_existing()
1548 if (ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag && in sctp_process_cookie_existing()
1549 ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag && in sctp_process_cookie_existing()
1550 cookie->tie_tag_my_vtag == 0 && in sctp_process_cookie_existing()
1551 cookie->tie_tag_peer_vtag == 0) { in sctp_process_cookie_existing()
1555 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1556 asoc->cookie_how[how_indx] = 6; in sctp_process_cookie_existing()
1565 (asoc->peer_supports_nat) && in sctp_process_cookie_existing()
1566 ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) && in sctp_process_cookie_existing()
1567 ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) || in sctp_process_cookie_existing()
1568 (asoc->peer_vtag == 0)))) { in sctp_process_cookie_existing()
1570 * Special case - Peer's support nat. We may have two init's in sctp_process_cookie_existing()
1572 * established.. i.e. we get INIT from host-1 behind the nat in sctp_process_cookie_existing()
1573 * and we respond tag-a, we get a INIT from host-2 behind in sctp_process_cookie_existing()
1574 * the nat and we get tag-a again. Then we bring up host-1 in sctp_process_cookie_existing()
1575 * (or 2's) assoc, Then comes the cookie from hsot-2 (or 1). in sctp_process_cookie_existing()
1581 mflowtype, mflowid, inp->fibnum, in sctp_process_cookie_existing()
1586 if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) && in sctp_process_cookie_existing()
1587 ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) || in sctp_process_cookie_existing()
1588 (asoc->peer_vtag == 0))) { in sctp_process_cookie_existing()
1591 * should be ok, re-accept peer info in sctp_process_cookie_existing()
1593 if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) { in sctp_process_cookie_existing()
1597 * when we first sent our INIT-ACK and when we later in sctp_process_cookie_existing()
1609 * exist :-) in sctp_process_cookie_existing()
1611 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1612 asoc->cookie_how[how_indx] = 7; in sctp_process_cookie_existing()
1617 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1618 asoc->cookie_how[how_indx] = 8; in sctp_process_cookie_existing()
1626 net->hb_responded = 1; in sctp_process_cookie_existing()
1627 if (stcb->asoc.sctp_autoclose_ticks && in sctp_process_cookie_existing()
1632 asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd); in sctp_process_cookie_existing()
1633 if (asoc->pre_open_streams < asoc->streamoutcnt) { in sctp_process_cookie_existing()
1634 asoc->pre_open_streams = asoc->streamoutcnt; in sctp_process_cookie_existing()
1637 if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) { in sctp_process_cookie_existing()
1647 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { in sctp_process_cookie_existing()
1648 if (chk->sent < SCTP_DATAGRAM_RESEND) { in sctp_process_cookie_existing()
1649 chk->sent = SCTP_DATAGRAM_RESEND; in sctp_process_cookie_existing()
1652 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); in sctp_process_cookie_existing()
1659 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1660 asoc->cookie_how[how_indx] = 9; in sctp_process_cookie_existing()
1663 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1666 vrf_id, net->port); in sctp_process_cookie_existing()
1671 initack_offset, src, dst, init_src, stcb->asoc.port)) < 0) { in sctp_process_cookie_existing()
1672 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1673 asoc->cookie_how[how_indx] = 10; in sctp_process_cookie_existing()
1679 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1682 vrf_id, net->port); in sctp_process_cookie_existing()
1689 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_process_cookie_existing()
1690 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && in sctp_process_cookie_existing()
1692 sctp_pcb_add_flags(stcb->sctp_ep, SCTP_PCB_FLAGS_CONNECTED); in sctp_process_cookie_existing()
1693 soisconnected(stcb->sctp_socket); in sctp_process_cookie_existing()
1712 * this call does is get only the COOKIE-ACK out and in sctp_process_cookie_existing()
1719 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1720 asoc->cookie_how[how_indx] = 11; in sctp_process_cookie_existing()
1724 if ((ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag && in sctp_process_cookie_existing()
1725 ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) && in sctp_process_cookie_existing()
1726 cookie->tie_tag_my_vtag == asoc->my_vtag_nonce && in sctp_process_cookie_existing()
1727 cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce && in sctp_process_cookie_existing()
1728 cookie->tie_tag_peer_vtag != 0) { in sctp_process_cookie_existing()
1731 if (asoc->peer_supports_nat) { in sctp_process_cookie_existing()
1754 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1755 asoc->cookie_how[how_indx] = 12; in sctp_process_cookie_existing()
1759 atomic_add_int(&stcb->asoc.refcnt, 1); in sctp_process_cookie_existing()
1770 if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) { in sctp_process_cookie_existing()
1777 if (asoc->pre_open_streams < asoc->streamoutcnt) { in sctp_process_cookie_existing()
1778 asoc->pre_open_streams = asoc->streamoutcnt; in sctp_process_cookie_existing()
1780 asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn); in sctp_process_cookie_existing()
1781 asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number; in sctp_process_cookie_existing()
1782 asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1; in sctp_process_cookie_existing()
1783 asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1; in sctp_process_cookie_existing()
1784 asoc->str_reset_seq_in = asoc->init_seq_number; in sctp_process_cookie_existing()
1785 asoc->advanced_peer_ack_point = asoc->last_acked_seq; in sctp_process_cookie_existing()
1786 asoc->send_sack = 1; in sctp_process_cookie_existing()
1787 asoc->data_pkts_seen = 0; in sctp_process_cookie_existing()
1788 asoc->last_data_chunk_from = NULL; in sctp_process_cookie_existing()
1789 asoc->last_control_chunk_from = NULL; in sctp_process_cookie_existing()
1790 asoc->last_net_cmt_send_started = NULL; in sctp_process_cookie_existing()
1791 if (asoc->mapping_array) { in sctp_process_cookie_existing()
1792 memset(asoc->mapping_array, 0, in sctp_process_cookie_existing()
1793 asoc->mapping_array_size); in sctp_process_cookie_existing()
1795 if (asoc->nr_mapping_array) { in sctp_process_cookie_existing()
1796 memset(asoc->nr_mapping_array, 0, in sctp_process_cookie_existing()
1797 asoc->mapping_array_size); in sctp_process_cookie_existing()
1801 SCTP_INP_WLOCK(stcb->sctp_ep); in sctp_process_cookie_existing()
1803 atomic_subtract_int(&stcb->asoc.refcnt, 1); in sctp_process_cookie_existing()
1806 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_process_cookie_existing()
1807 stcb->asoc.strmout[i].chunks_on_queues = 0; in sctp_process_cookie_existing()
1810 asoc->strmout[i].abandoned_sent[j] = 0; in sctp_process_cookie_existing()
1811 asoc->strmout[i].abandoned_unsent[j] = 0; in sctp_process_cookie_existing()
1814 asoc->strmout[i].abandoned_sent[0] = 0; in sctp_process_cookie_existing()
1815 asoc->strmout[i].abandoned_unsent[0] = 0; in sctp_process_cookie_existing()
1817 stcb->asoc.strmout[i].next_mid_ordered = 0; in sctp_process_cookie_existing()
1818 stcb->asoc.strmout[i].next_mid_unordered = 0; in sctp_process_cookie_existing()
1819 stcb->asoc.strmout[i].sid = i; in sctp_process_cookie_existing()
1820 stcb->asoc.strmout[i].last_msg_incomplete = 0; in sctp_process_cookie_existing()
1822 TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) { in sctp_process_cookie_existing()
1823 TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp); in sctp_process_cookie_existing()
1826 TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) { in sctp_process_cookie_existing()
1827 TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next); in sctp_process_cookie_existing()
1828 if (sq->data) { in sctp_process_cookie_existing()
1829 sctp_m_freem(sq->data); in sctp_process_cookie_existing()
1830 sq->data = NULL; in sctp_process_cookie_existing()
1832 sctp_free_remote_addr(sq->whoFrom); in sctp_process_cookie_existing()
1833 sq->whoFrom = NULL; in sctp_process_cookie_existing()
1834 sq->stcb = NULL; in sctp_process_cookie_existing()
1837 TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) { in sctp_process_cookie_existing()
1838 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); in sctp_process_cookie_existing()
1839 if (chk->data) { in sctp_process_cookie_existing()
1840 sctp_m_freem(chk->data); in sctp_process_cookie_existing()
1841 chk->data = NULL; in sctp_process_cookie_existing()
1843 if (chk->holds_key_ref) in sctp_process_cookie_existing()
1844 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_process_cookie_existing()
1845 sctp_free_remote_addr(chk->whoTo); in sctp_process_cookie_existing()
1849 asoc->ctrl_queue_cnt = 0; in sctp_process_cookie_existing()
1850 asoc->str_reset = NULL; in sctp_process_cookie_existing()
1851 asoc->stream_reset_outstanding = 0; in sctp_process_cookie_existing()
1852 TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { in sctp_process_cookie_existing()
1853 TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); in sctp_process_cookie_existing()
1854 if (chk->data) { in sctp_process_cookie_existing()
1855 sctp_m_freem(chk->data); in sctp_process_cookie_existing()
1856 chk->data = NULL; in sctp_process_cookie_existing()
1858 if (chk->holds_key_ref) in sctp_process_cookie_existing()
1859 sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED); in sctp_process_cookie_existing()
1860 sctp_free_remote_addr(chk->whoTo); in sctp_process_cookie_existing()
1864 TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) { in sctp_process_cookie_existing()
1865 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); in sctp_process_cookie_existing()
1868 TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) { in sctp_process_cookie_existing()
1869 TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next); in sctp_process_cookie_existing()
1870 if (aack->data != NULL) { in sctp_process_cookie_existing()
1871 sctp_m_freem(aack->data); in sctp_process_cookie_existing()
1875 asoc->rcv_edmid = cookie->rcv_edmid; in sctp_process_cookie_existing()
1877 /* process the INIT-ACK info (my info) */ in sctp_process_cookie_existing()
1878 asoc->my_vtag = ntohl(initack_cp->init.initiate_tag); in sctp_process_cookie_existing()
1879 asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd); in sctp_process_cookie_existing()
1883 /* re-insert to new vtag position */ in sctp_process_cookie_existing()
1884 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, in sctp_process_cookie_existing()
1892 SCTP_INP_WUNLOCK(stcb->sctp_ep); in sctp_process_cookie_existing()
1894 asoc->total_flight = 0; in sctp_process_cookie_existing()
1895 asoc->total_flight_count = 0; in sctp_process_cookie_existing()
1898 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1899 asoc->cookie_how[how_indx] = 13; in sctp_process_cookie_existing()
1902 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1905 vrf_id, net->port); in sctp_process_cookie_existing()
1912 net->hb_responded = 1; in sctp_process_cookie_existing()
1916 initack_offset, src, dst, init_src, stcb->asoc.port)) < 0) { in sctp_process_cookie_existing()
1917 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1918 asoc->cookie_how[how_indx] = 14; in sctp_process_cookie_existing()
1924 sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, in sctp_process_cookie_existing()
1927 vrf_id, net->port); in sctp_process_cookie_existing()
1930 /* respond with a COOKIE-ACK */ in sctp_process_cookie_existing()
1932 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1933 asoc->cookie_how[how_indx] = 15; in sctp_process_cookie_existing()
1935 (asoc->sctp_autoclose_ticks > 0)) { in sctp_process_cookie_existing()
1940 if (how_indx < sizeof(asoc->cookie_how)) in sctp_process_cookie_existing()
1941 asoc->cookie_how[how_indx] = 16; in sctp_process_cookie_existing()
1948 * handle a state cookie for a new association m: input packet mbuf chain--
1949 * assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a "split" mbuf
1951 * cookie-echo chunk length: length of the cookie chunk to: where the init
1975 * INIT should start after the cookie-echo header struct (chunk in sctp_process_cookie_new()
1988 if (init_cp->ch.chunk_type != SCTP_INITIATION) { in sctp_process_cookie_new()
1992 initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length)); in sctp_process_cookie_new()
1994 * find and validate the INIT-ACK chunk in the cookie (my info) the in sctp_process_cookie_new()
1995 * INIT-ACK follows the INIT chunk in sctp_process_cookie_new()
2001 /* could not pull INIT-ACK chunk in cookie */ in sctp_process_cookie_new()
2002 SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: could not pull INIT-ACK chunk hdr\n"); in sctp_process_cookie_new()
2005 if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) { in sctp_process_cookie_new()
2017 * now that we know the INIT/INIT-ACK are in place, create a new TCB in sctp_process_cookie_new()
2028 ntohl(initack_cp->init.initiate_tag), in sctp_process_cookie_new()
2029 ntohl(initack_cp->init.initial_tsn), vrf_id, in sctp_process_cookie_new()
2030 ntohs(initack_cp->init.num_outbound_streams), in sctp_process_cookie_new()
2047 asoc = &stcb->asoc; in sctp_process_cookie_new()
2049 asoc->scope.ipv4_local_scope = cookie->ipv4_scope; in sctp_process_cookie_new()
2050 asoc->scope.site_scope = cookie->site_scope; in sctp_process_cookie_new()
2051 asoc->scope.local_scope = cookie->local_scope; in sctp_process_cookie_new()
2052 asoc->scope.loopback_scope = cookie->loopback_scope; in sctp_process_cookie_new()
2054 if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) || in sctp_process_cookie_new()
2055 (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) { in sctp_process_cookie_new()
2072 asoc->rcv_edmid = cookie->rcv_edmid; in sctp_process_cookie_new()
2073 /* process the INIT-ACK info (my info) */ in sctp_process_cookie_new()
2074 asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd); in sctp_process_cookie_new()
2093 /* pull the local authentication parameters from the cookie/init-ack */ in sctp_process_cookie_new()
2096 initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk))); in sctp_process_cookie_new()
2108 "COOKIE-ECHO: AUTH failed\n"); in sctp_process_cookie_new()
2114 stcb->asoc.authenticated = 1; in sctp_process_cookie_new()
2127 /* warning, we re-use sin, sin6, sa_store here! */ in sctp_process_cookie_new()
2129 switch (cookie->laddr_type) { in sctp_process_cookie_new()
2136 store.sin.sin_addr.s_addr = cookie->laddress[0]; in sctp_process_cookie_new()
2145 store.sin6.sin6_scope_id = cookie->scope_id; in sctp_process_cookie_new()
2146 memcpy(&store.sin6.sin6_addr, cookie->laddress, sizeof(struct in6_addr)); in sctp_process_cookie_new()
2164 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_process_cookie_new()
2165 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && in sctp_process_cookie_new()
2171 * INIT/INIT-ACK/COOKIE arrived. But of course then it in sctp_process_cookie_new()
2177 sctp_pcb_add_flags(stcb->sctp_ep, SCTP_PCB_FLAGS_CONNECTED); in sctp_process_cookie_new()
2178 soisconnected(stcb->sctp_socket); in sctp_process_cookie_new()
2179 } else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && in sctp_process_cookie_new()
2188 if (stcb->asoc.sctp_autoclose_ticks && in sctp_process_cookie_new()
2192 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); in sctp_process_cookie_new()
2199 (*netp)->hb_responded = 1; in sctp_process_cookie_new()
2201 /* respond with a COOKIE-ACK */ in sctp_process_cookie_new()
2206 * AFTER the cookie-ack is sent in sctp_process_cookie_new()
2210 initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)), in sctp_process_cookie_new()
2211 &store.sa, cookie->local_scope, cookie->site_scope, in sctp_process_cookie_new()
2212 cookie->ipv4_scope, cookie->loopback_scope); in sctp_process_cookie_new()
2220 * need to send back an ABORT-TRY-AGAIN-WITH-NEW-TAG No middle box bit!
2224 if ((stcb->asoc.my_vtag == tag) && (stcb->rport == rport) && (inp == stcb->sctp_ep)) {
2225 -- SEND ABORT - TRY AGAIN --
2231 * handles a COOKIE-ECHO message stcb: modified to either a new or left as
2232 * existing (non-NULL) TCB
2269 "sctp_handle_cookie: handling COOKIE-ECHO\n"); in sctp_handle_cookie_echo()
2274 cookie = &cp->cookie; in sctp_handle_cookie_echo()
2276 cookie_len = ntohs(cp->ch.chunk_length); in sctp_handle_cookie_echo()
2284 if ((cookie->peerport != sh->src_port) || in sctp_handle_cookie_echo()
2285 (cookie->myport != sh->dest_port) || in sctp_handle_cookie_echo()
2286 (cookie->my_vtag != sh->v_tag)) { in sctp_handle_cookie_echo()
2292 * opposite byte order of the machine :-> in sctp_handle_cookie_echo()
2300 sig_offset = offset + cookie_len - SCTP_SIGNATURE_SIZE; in sctp_handle_cookie_echo()
2316 atomic_add_int(&l_stcb->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2323 atomic_subtract_int(&l_stcb->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2325 if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { in sctp_handle_cookie_echo()
2330 ep = &(*inp_p)->sctp_ep; in sctp_handle_cookie_echo()
2332 if ((cookie->time_entered.tv_sec < ep->time_of_secret_change) && in sctp_handle_cookie_echo()
2333 (ep->current_secret_number != ep->last_secret_number)) { in sctp_handle_cookie_echo()
2336 (uint8_t *)ep->secret_key[(int)ep->last_secret_number], in sctp_handle_cookie_echo()
2341 (uint8_t *)ep->secret_key[(int)ep->current_secret_number], in sctp_handle_cookie_echo()
2355 if ((cookie->time_entered.tv_sec == ep->time_of_secret_change) && in sctp_handle_cookie_echo()
2356 (ep->current_secret_number != ep->last_secret_number)) { in sctp_handle_cookie_echo()
2359 (uint8_t *)ep->secret_key[(int)ep->last_secret_number], in sctp_handle_cookie_echo()
2391 if (sctp_ticks_to_msecs(cookie->cookie_life) > SCTP_MAX_COOKIE_LIFE) { in sctp_handle_cookie_echo()
2395 time_entered.tv_sec = cookie->time_entered.tv_sec; in sctp_handle_cookie_echo()
2396 time_entered.tv_usec = cookie->time_entered.tv_usec; in sctp_handle_cookie_echo()
2413 time_expires.tv_sec = time_entered.tv_sec + sctp_ticks_to_secs(cookie->cookie_life); in sctp_handle_cookie_echo()
2431 cause->cause.code = htons(SCTP_CAUSE_STALE_COOKIE); in sctp_handle_cookie_echo()
2432 cause->cause.length = htons(sizeof(struct sctp_error_stale_cookie)); in sctp_handle_cookie_echo()
2440 if (UINT32_MAX - staleness >= (uint32_t)diff.tv_usec) { in sctp_handle_cookie_echo()
2445 cause->stale_time = htonl(staleness); in sctp_handle_cookie_echo()
2446 sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err, in sctp_handle_cookie_echo()
2447 mflowtype, mflowid, l_inp->fibnum, in sctp_handle_cookie_echo()
2453 * asoc. This will only happen if we were in the COOKIE-WAIT state in sctp_handle_cookie_echo()
2456 * had for him. In this case we will have one of the tie-tags set at in sctp_handle_cookie_echo()
2461 switch (cookie->addr_type) { in sctp_handle_cookie_echo()
2467 sin6.sin6_port = sh->src_port; in sctp_handle_cookie_echo()
2468 sin6.sin6_scope_id = cookie->scope_id; in sctp_handle_cookie_echo()
2469 memcpy(&sin6.sin6_addr.s6_addr, cookie->address, in sctp_handle_cookie_echo()
2479 sin.sin_port = sh->src_port; in sctp_handle_cookie_echo()
2480 sin.sin_addr.s_addr = cookie->address[0]; in sctp_handle_cookie_echo()
2517 * raise it back out to balance it all :-) in sctp_handle_cookie_echo()
2519 SCTP_INP_INCR_REF((*stcb)->sctp_ep); in sctp_handle_cookie_echo()
2520 if ((*stcb)->sctp_ep != l_inp) { in sctp_handle_cookie_echo()
2522 (void *)(*stcb)->sctp_ep, (void *)l_inp); in sctp_handle_cookie_echo()
2528 cookie_len -= SCTP_SIGNATURE_SIZE; in sctp_handle_cookie_echo()
2538 /* this is abnormal... cookie-echo on existing TCB */ in sctp_handle_cookie_echo()
2552 /* still no TCB... must be bad cookie-echo */ in sctp_handle_cookie_echo()
2556 (*netp)->flowtype = mflowtype; in sctp_handle_cookie_echo()
2557 (*netp)->flowid = mflowid; in sctp_handle_cookie_echo()
2561 * INIT-ACK to. in sctp_handle_cookie_echo()
2576 if (netl->dest_state & SCTP_ADDR_UNCONFIRMED) { in sctp_handle_cookie_echo()
2577 netl->dest_state &= ~SCTP_ADDR_UNCONFIRMED; in sctp_handle_cookie_echo()
2584 if ((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { in sctp_handle_cookie_echo()
2586 (((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { in sctp_handle_cookie_echo()
2607 oso = (*inp_p)->sctp_socket; in sctp_handle_cookie_echo()
2608 atomic_add_int(&(*stcb)->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2610 CURVNET_SET(oso->so_vnet); in sctp_handle_cookie_echo()
2615 atomic_subtract_int(&(*stcb)->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2631 inp = (struct sctp_inpcb *)so->so_pcb; in sctp_handle_cookie_echo()
2638 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE | in sctp_handle_cookie_echo()
2642 (SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) | in sctp_handle_cookie_echo()
2644 inp->sctp_features = (*inp_p)->sctp_features; in sctp_handle_cookie_echo()
2645 inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features; in sctp_handle_cookie_echo()
2646 inp->sctp_socket = so; in sctp_handle_cookie_echo()
2647 inp->sctp_frag_point = (*inp_p)->sctp_frag_point; in sctp_handle_cookie_echo()
2648 inp->max_cwnd = (*inp_p)->max_cwnd; in sctp_handle_cookie_echo()
2649 inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off; in sctp_handle_cookie_echo()
2650 inp->ecn_supported = (*inp_p)->ecn_supported; in sctp_handle_cookie_echo()
2651 inp->prsctp_supported = (*inp_p)->prsctp_supported; in sctp_handle_cookie_echo()
2652 inp->auth_supported = (*inp_p)->auth_supported; in sctp_handle_cookie_echo()
2653 inp->asconf_supported = (*inp_p)->asconf_supported; in sctp_handle_cookie_echo()
2654 inp->reconfig_supported = (*inp_p)->reconfig_supported; in sctp_handle_cookie_echo()
2655 inp->nrsack_supported = (*inp_p)->nrsack_supported; in sctp_handle_cookie_echo()
2656 inp->pktdrop_supported = (*inp_p)->pktdrop_supported; in sctp_handle_cookie_echo()
2657 inp->partial_delivery_point = (*inp_p)->partial_delivery_point; in sctp_handle_cookie_echo()
2658 inp->sctp_context = (*inp_p)->sctp_context; in sctp_handle_cookie_echo()
2659 inp->local_strreset_support = (*inp_p)->local_strreset_support; in sctp_handle_cookie_echo()
2660 inp->fibnum = (*inp_p)->fibnum; in sctp_handle_cookie_echo()
2665 if (inp->sctp_ep.local_hmacs) in sctp_handle_cookie_echo()
2666 sctp_free_hmaclist(inp->sctp_ep.local_hmacs); in sctp_handle_cookie_echo()
2667 inp->sctp_ep.local_hmacs = in sctp_handle_cookie_echo()
2668 sctp_copy_hmaclist((*inp_p)->sctp_ep.local_hmacs); in sctp_handle_cookie_echo()
2669 if (inp->sctp_ep.local_auth_chunks) in sctp_handle_cookie_echo()
2670 sctp_free_chunklist(inp->sctp_ep.local_auth_chunks); in sctp_handle_cookie_echo()
2671 inp->sctp_ep.local_auth_chunks = in sctp_handle_cookie_echo()
2672 sctp_copy_chunklist((*inp_p)->sctp_ep.local_auth_chunks); in sctp_handle_cookie_echo()
2680 * This is where the one-2-one socket is put into in sctp_handle_cookie_echo()
2688 atomic_add_int(&(*stcb)->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2694 atomic_subtract_int(&(*stcb)->asoc.refcnt, 1); in sctp_handle_cookie_echo()
2701 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_handle_cookie_echo()
2741 /* cp must not be used, others call this without a c-ack :-) */ in sctp_handle_cookie_ack()
2746 "sctp_handle_cookie_ack: handling COOKIE-ACK\n"); in sctp_handle_cookie_ack()
2751 asoc = &stcb->asoc; in sctp_handle_cookie_ack()
2754 asoc->overall_error_count, in sctp_handle_cookie_ack()
2770 if (asoc->overall_error_count == 0) { in sctp_handle_cookie_ack()
2771 sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, in sctp_handle_cookie_ack()
2778 asoc->overall_error_count = 0; in sctp_handle_cookie_ack()
2779 net->hb_responded = 1; in sctp_handle_cookie_ack()
2780 (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered); in sctp_handle_cookie_ack()
2782 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || in sctp_handle_cookie_ack()
2783 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { in sctp_handle_cookie_ack()
2784 sctp_pcb_add_flags(stcb->sctp_ep, SCTP_PCB_FLAGS_CONNECTED); in sctp_handle_cookie_ack()
2785 if ((stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) == 0) { in sctp_handle_cookie_ack()
2786 soisconnected(stcb->sctp_socket); in sctp_handle_cookie_ack()
2790 if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) && in sctp_handle_cookie_ack()
2791 TAILQ_EMPTY(&asoc->send_queue) && in sctp_handle_cookie_ack()
2792 TAILQ_EMPTY(&asoc->sent_queue) && in sctp_handle_cookie_ack()
2793 (asoc->stream_queue_cnt == 0)) { in sctp_handle_cookie_ack()
2799 stcb->sctp_ep, stcb, net); in sctp_handle_cookie_ack()
2801 stcb->sctp_ep, stcb, NULL); in sctp_handle_cookie_ack()
2802 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); in sctp_handle_cookie_ack()
2805 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { in sctp_handle_cookie_ack()
2813 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, in sctp_handle_cookie_ack()
2816 if (stcb->asoc.sctp_autoclose_ticks && in sctp_handle_cookie_ack()
2817 sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTOCLOSE)) { in sctp_handle_cookie_ack()
2819 stcb->sctp_ep, stcb, NULL); in sctp_handle_cookie_ack()
2826 if ((sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DO_ASCONF)) && in sctp_handle_cookie_ack()
2827 (stcb->asoc.asconf_supported == 1) && in sctp_handle_cookie_ack()
2828 (!TAILQ_EMPTY(&stcb->asoc.asconf_queue))) { in sctp_handle_cookie_ack()
2831 stcb->sctp_ep, stcb, in sctp_handle_cookie_ack()
2832 stcb->asoc.primary_destination); in sctp_handle_cookie_ack()
2834 sctp_send_asconf(stcb, stcb->asoc.primary_destination, in sctp_handle_cookie_ack()
2841 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { in sctp_handle_cookie_ack()
2842 if (chk->whoTo != NULL) { in sctp_handle_cookie_ack()
2847 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo); in sctp_handle_cookie_ack()
2863 len = ntohs(cp->ch.chunk_length); in sctp_handle_ecn_echo()
2871 tsn = ntohl(cp->tsn); in sctp_handle_ecn_echo()
2872 pkt_cnt = ntohl(cp->num_pkts_since_cwr); in sctp_handle_ecn_echo()
2873 lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead); in sctp_handle_ecn_echo()
2875 window_data_tsn = stcb->asoc.sending_seq - 1; in sctp_handle_ecn_echo()
2877 window_data_tsn = lchk->rec.data.tsn; in sctp_handle_ecn_echo()
2882 TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) { in sctp_handle_ecn_echo()
2883 if (lchk->rec.data.tsn == tsn) { in sctp_handle_ecn_echo()
2884 net = lchk->whoTo; in sctp_handle_ecn_echo()
2885 net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send; in sctp_handle_ecn_echo()
2888 if (SCTP_TSN_GT(lchk->rec.data.tsn, tsn)) { in sctp_handle_ecn_echo()
2898 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { in sctp_handle_ecn_echo()
2899 if (tsn == net->last_cwr_tsn) { in sctp_handle_ecn_echo()
2910 net = TAILQ_FIRST(&stcb->asoc.nets); in sctp_handle_ecn_echo()
2922 if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) && in sctp_handle_ecn_echo()
2925 * JRS - Use the congestion control given in the pluggable in sctp_handle_ecn_echo()
2928 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt); in sctp_handle_ecn_echo()
2933 net->cwr_window_tsn = window_data_tsn; in sctp_handle_ecn_echo()
2934 net->ecn_ce_pkt_cnt += pkt_cnt; in sctp_handle_ecn_echo()
2935 net->lost_cnt = pkt_cnt; in sctp_handle_ecn_echo()
2936 net->last_cwr_tsn = tsn; in sctp_handle_ecn_echo()
2939 if (SCTP_TSN_GT(tsn, net->last_cwr_tsn) && in sctp_handle_ecn_echo()
2947 if (pkt_cnt > net->lost_cnt) { in sctp_handle_ecn_echo()
2949 cnt = (pkt_cnt - net->lost_cnt); in sctp_handle_ecn_echo()
2950 net->ecn_ce_pkt_cnt += cnt; in sctp_handle_ecn_echo()
2952 net->lost_cnt = pkt_cnt; in sctp_handle_ecn_echo()
2953 net->last_cwr_tsn = tsn; in sctp_handle_ecn_echo()
2956 * are in-window yet of the initial CE the peer saw. in sctp_handle_ecn_echo()
2958 stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 1, cnt); in sctp_handle_ecn_echo()
2967 sctp_send_cwr(stcb, net, net->last_cwr_tsn, override_bit); in sctp_handle_ecn_echo()
2983 cwr_tsn = ntohl(cp->tsn); in sctp_handle_ecn_cwr()
2984 override = cp->ch.chunk_flags & SCTP_CWR_REDUCE_OVERRIDE; in sctp_handle_ecn_cwr()
2985 TAILQ_FOREACH_SAFE(chk, &stcb->asoc.control_send_queue, sctp_next, nchk) { in sctp_handle_ecn_cwr()
2986 if (chk->rec.chunk_id.id != SCTP_ECN_ECHO) { in sctp_handle_ecn_cwr()
2989 if ((override == 0) && (chk->whoTo != net)) { in sctp_handle_ecn_cwr()
2993 ecne = mtod(chk->data, struct sctp_ecne_chunk *); in sctp_handle_ecn_cwr()
2994 if (SCTP_TSN_GE(cwr_tsn, ntohl(ecne->tsn))) { in sctp_handle_ecn_cwr()
2996 stcb->asoc.ecn_echo_cnt_onq--; in sctp_handle_ecn_cwr()
2997 TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk, in sctp_handle_ecn_cwr()
2999 stcb->asoc.ctrl_queue_cnt--; in sctp_handle_ecn_cwr()
3000 sctp_m_freem(chk->data); in sctp_handle_ecn_cwr()
3001 chk->data = NULL; in sctp_handle_ecn_cwr()
3016 "sctp_handle_shutdown_complete: handling SHUTDOWN-COMPLETE\n"); in sctp_handle_shutdown_complete()
3022 /* unexpected SHUTDOWN-COMPLETE... so ignore... */ in sctp_handle_shutdown_complete()
3024 "sctp_handle_shutdown_complete: not in SCTP_STATE_SHUTDOWN_ACK_SENT --- ignore\n"); in sctp_handle_shutdown_complete()
3029 if (stcb->sctp_socket) { in sctp_handle_shutdown_complete()
3033 if (!TAILQ_EMPTY(&stcb->asoc.send_queue) || in sctp_handle_shutdown_complete()
3034 !TAILQ_EMPTY(&stcb->asoc.sent_queue) || in sctp_handle_shutdown_complete()
3036 panic("Queues are not empty when handling SHUTDOWN-COMPLETE"); in sctp_handle_shutdown_complete()
3040 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, in sctp_handle_shutdown_complete()
3045 "sctp_handle_shutdown_complete: calls free-asoc\n"); in sctp_handle_shutdown_complete()
3046 (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, in sctp_handle_shutdown_complete()
3055 switch (desc->chunk_type) { in process_chunk_drop()
3063 tsn = ntohl(desc->tsn_ifany); in process_chunk_drop()
3064 TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) { in process_chunk_drop()
3065 if (tp1->rec.data.tsn == tsn) { in process_chunk_drop()
3069 if (SCTP_TSN_GT(tp1->rec.data.tsn, tsn)) { in process_chunk_drop()
3081 TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) { in process_chunk_drop()
3082 if (tp1->rec.data.tsn == tsn) { in process_chunk_drop()
3091 if ((tp1) && (tp1->sent < SCTP_DATAGRAM_ACKED)) { in process_chunk_drop()
3096 if ((stcb->asoc.peers_rwnd == 0) && in process_chunk_drop()
3101 if (stcb->asoc.peers_rwnd == 0 && in process_chunk_drop()
3106 if ((uint32_t)SCTP_BUF_LEN(tp1->data) < in process_chunk_drop()
3110 return (-1); in process_chunk_drop()
3112 if (memcmp(mtod(tp1->data, caddr_t)+SCTP_DATA_CHUNK_OVERHEAD(stcb), in process_chunk_drop()
3113 desc->data_bytes, SCTP_NUM_DB_TO_VERIFY) != 0) { in process_chunk_drop()
3116 return (-1); in process_chunk_drop()
3118 if (tp1->do_rtt) { in process_chunk_drop()
3123 if (tp1->whoTo->rto_needed == 0) { in process_chunk_drop()
3124 tp1->whoTo->rto_needed = 1; in process_chunk_drop()
3126 tp1->do_rtt = 0; in process_chunk_drop()
3129 if (tp1->sent != SCTP_DATAGRAM_RESEND) in process_chunk_drop()
3130 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); in process_chunk_drop()
3133 * we will be getting gap ack reports behind in process_chunk_drop()
3136 tp1->rec.data.doing_fast_retransmit = 1; in process_chunk_drop()
3141 if (TAILQ_EMPTY(&stcb->asoc.send_queue)) { in process_chunk_drop()
3142 tp1->rec.data.fast_retran_tsn = stcb->asoc.sending_seq; in process_chunk_drop()
3144 tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.tsn; in process_chunk_drop()
3148 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in process_chunk_drop()
3149 stcb, tp1->whoTo, in process_chunk_drop()
3151 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in process_chunk_drop()
3152 stcb, tp1->whoTo); in process_chunk_drop()
3157 tp1->whoTo->flight_size, in process_chunk_drop()
3158 tp1->book_size, in process_chunk_drop()
3160 tp1->rec.data.tsn); in process_chunk_drop()
3162 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in process_chunk_drop()
3166 tp1->sent = SCTP_DATAGRAM_RESEND; in process_chunk_drop()
3172 TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) { in process_chunk_drop()
3173 if (tp1->sent == SCTP_DATAGRAM_RESEND) in process_chunk_drop()
3176 TAILQ_FOREACH(tp1, &stcb->asoc.control_send_queue, in process_chunk_drop()
3178 if (tp1->sent == SCTP_DATAGRAM_RESEND) in process_chunk_drop()
3181 if (audit != stcb->asoc.sent_queue_retran_cnt) { in process_chunk_drop()
3183 audit, stcb->asoc.sent_queue_retran_cnt); in process_chunk_drop()
3185 stcb->asoc.sent_queue_retran_cnt = audit; in process_chunk_drop()
3195 TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue, in process_chunk_drop()
3197 if (asconf->rec.chunk_id.id == SCTP_ASCONF) { in process_chunk_drop()
3202 if (asconf->sent != SCTP_DATAGRAM_RESEND) in process_chunk_drop()
3203 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); in process_chunk_drop()
3204 asconf->sent = SCTP_DATAGRAM_RESEND; in process_chunk_drop()
3205 asconf->snd_count--; in process_chunk_drop()
3211 stcb->asoc.dropped_special_cnt++; in process_chunk_drop()
3212 if (stcb->asoc.dropped_special_cnt < SCTP_RETRY_DROPPED_THRESH) { in process_chunk_drop()
3217 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, in process_chunk_drop()
3220 sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in process_chunk_drop()
3230 if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) { in process_chunk_drop()
3249 TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue, in process_chunk_drop()
3251 if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) { in process_chunk_drop()
3256 if (cookie->sent != SCTP_DATAGRAM_RESEND) in process_chunk_drop()
3257 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); in process_chunk_drop()
3258 cookie->sent = SCTP_DATAGRAM_RESEND; in process_chunk_drop()
3267 /* resend last asconf ack */ in process_chunk_drop()
3272 send_forward_tsn(stcb, &stcb->asoc); in process_chunk_drop()
3303 if (temp >= stcb->asoc.streamincnt) { in sctp_reset_in_stream()
3306 stcb->asoc.strmin[temp].last_mid_delivered = 0xffffffff; in sctp_reset_in_stream()
3310 for (i = 0; i < stcb->asoc.streamincnt; i++) { in sctp_reset_in_stream()
3311 stcb->asoc.strmin[i].last_mid_delivered = 0xffffffff; in sctp_reset_in_stream()
3326 if (temp >= stcb->asoc.streamoutcnt) { in sctp_reset_out_streams()
3330 stcb->asoc.strmout[temp].next_mid_ordered = 0; in sctp_reset_out_streams()
3331 stcb->asoc.strmout[temp].next_mid_unordered = 0; in sctp_reset_out_streams()
3334 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_reset_out_streams()
3335 stcb->asoc.strmout[i].next_mid_ordered = 0; in sctp_reset_out_streams()
3336 stcb->asoc.strmout[i].next_mid_unordered = 0; in sctp_reset_out_streams()
3351 if (temp >= stcb->asoc.streamoutcnt) { in sctp_reset_clear_pending()
3355 stcb->asoc.strmout[temp].state = SCTP_STREAM_OPEN; in sctp_reset_clear_pending()
3358 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_reset_clear_pending()
3359 stcb->asoc.strmout[i].state = SCTP_STREAM_OPEN; in sctp_reset_clear_pending()
3373 asoc = &stcb->asoc; in sctp_find_stream_reset()
3374 chk = asoc->str_reset; in sctp_find_stream_reset()
3375 if (TAILQ_EMPTY(&asoc->control_send_queue) || in sctp_find_stream_reset()
3377 asoc->stream_reset_outstanding = 0; in sctp_find_stream_reset()
3380 if (chk->data == NULL) { in sctp_find_stream_reset()
3387 clen = chk->send_size; in sctp_find_stream_reset()
3388 ch = mtod(chk->data, struct sctp_chunkhdr *); in sctp_find_stream_reset()
3390 if (ntohl(r->request_seq) == seq) { in sctp_find_stream_reset()
3394 len = SCTP_SIZE32(ntohs(r->ph.param_length)); in sctp_find_stream_reset()
3398 if (ntohl(r->request_seq) == seq) { in sctp_find_stream_reset()
3412 asoc = &stcb->asoc; in sctp_clean_up_stream_reset()
3413 chk = asoc->str_reset; in sctp_clean_up_stream_reset()
3417 asoc->str_reset = NULL; in sctp_clean_up_stream_reset()
3418 sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, in sctp_clean_up_stream_reset()
3420 TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); in sctp_clean_up_stream_reset()
3421 asoc->ctrl_queue_cnt--; in sctp_clean_up_stream_reset()
3422 if (chk->data) { in sctp_clean_up_stream_reset()
3423 sctp_m_freem(chk->data); in sctp_clean_up_stream_reset()
3424 chk->data = NULL; in sctp_clean_up_stream_reset()
3436 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_stream_reset_response()
3443 if (asoc->stream_reset_outstanding == 0) { in sctp_handle_stream_reset_response()
3447 if (seq == stcb->asoc.str_reset_seq_out) { in sctp_handle_stream_reset_response()
3450 stcb->asoc.str_reset_seq_out++; in sctp_handle_stream_reset_response()
3451 type = ntohs(req_param->ph.param_type); in sctp_handle_stream_reset_response()
3452 lparam_len = ntohs(req_param->ph.param_length); in sctp_handle_stream_reset_response()
3457 number_entries = (lparam_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t); in sctp_handle_stream_reset_response()
3458 asoc->stream_reset_out_is_outstanding = 0; in sctp_handle_stream_reset_response()
3459 if (asoc->stream_reset_outstanding) in sctp_handle_stream_reset_response()
3460 asoc->stream_reset_outstanding--; in sctp_handle_stream_reset_response()
3463 sctp_reset_out_streams(stcb, number_entries, req_out_param->list_of_streams); in sctp_handle_stream_reset_response()
3465 …sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, req_out_param->list_of_str… in sctp_handle_stream_reset_response()
3471 asoc->stream_reset_outstanding++; in sctp_handle_stream_reset_response()
3472 stcb->asoc.str_reset_seq_out--; in sctp_handle_stream_reset_response()
3473 asoc->stream_reset_out_is_outstanding = 1; in sctp_handle_stream_reset_response()
3476 …sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, req_out_param->list_of_str… in sctp_handle_stream_reset_response()
3479 sctp_reset_clear_pending(stcb, number_entries, req_out_param->list_of_streams); in sctp_handle_stream_reset_response()
3483 number_entries = (lparam_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t); in sctp_handle_stream_reset_response()
3484 if (asoc->stream_reset_outstanding) in sctp_handle_stream_reset_response()
3485 asoc->stream_reset_outstanding--; in sctp_handle_stream_reset_response()
3488 number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED); in sctp_handle_stream_reset_response()
3491 number_entries, req_in_param->list_of_streams, SCTP_SO_NOT_LOCKED); in sctp_handle_stream_reset_response()
3497 num_stream = stcb->asoc.strm_pending_add_size; in sctp_handle_stream_reset_response()
3498 if (num_stream > (stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt)) { in sctp_handle_stream_reset_response()
3500 num_stream = stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt; in sctp_handle_stream_reset_response()
3502 stcb->asoc.strm_pending_add_size = 0; in sctp_handle_stream_reset_response()
3503 if (asoc->stream_reset_outstanding) in sctp_handle_stream_reset_response()
3504 asoc->stream_reset_outstanding--; in sctp_handle_stream_reset_response()
3509 for (i = asoc->streamoutcnt; i < (asoc->streamoutcnt + num_stream); i++) { in sctp_handle_stream_reset_response()
3510 asoc->strmout[i].state = SCTP_STREAM_OPEN; in sctp_handle_stream_reset_response()
3512 asoc->streamoutcnt += num_stream; in sctp_handle_stream_reset_response()
3520 if (asoc->stream_reset_outstanding) in sctp_handle_stream_reset_response()
3521 asoc->stream_reset_outstanding--; in sctp_handle_stream_reset_response()
3531 * c) Adopt the new out-tsn in sctp_handle_stream_reset_response()
3541 if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) { in sctp_handle_stream_reset_response()
3546 asoc->stream_reset_outstanding--; in sctp_handle_stream_reset_response()
3549 fwdtsn.new_cumulative_tsn = htonl(ntohl(resp->senders_next_tsn) - 1); in sctp_handle_stream_reset_response()
3554 stcb->asoc.highest_tsn_inside_map = (ntohl(resp->senders_next_tsn) - 1); in sctp_handle_stream_reset_response()
3556 sctp_log_map(0, 7, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); in sctp_handle_stream_reset_response()
3559 stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map; in sctp_handle_stream_reset_response()
3560 stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn); in sctp_handle_stream_reset_response()
3561 memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size); in sctp_handle_stream_reset_response()
3563 stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map; in sctp_handle_stream_reset_response()
3564 memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size); in sctp_handle_stream_reset_response()
3566 stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn); in sctp_handle_stream_reset_response()
3567 stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn; in sctp_handle_stream_reset_response()
3579 if (asoc->stream_reset_outstanding == 0) { in sctp_handle_stream_reset_response()
3584 if (asoc->stream_reset_outstanding == 0) { in sctp_handle_stream_reset_response()
3601 * peer wants me to send a str-reset to him for my outgoing seq's if in sctp_handle_str_reset_request_in()
3604 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_str_reset_request_in()
3606 seq = ntohl(req->request_seq); in sctp_handle_str_reset_request_in()
3607 if (asoc->str_reset_seq_in == seq) { in sctp_handle_str_reset_request_in()
3608 asoc->last_reset_action[1] = asoc->last_reset_action[0]; in sctp_handle_str_reset_request_in()
3609 if ((asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ) == 0) { in sctp_handle_str_reset_request_in()
3610 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_in()
3613 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_in()
3614 } else if (stcb->asoc.stream_reset_out_is_outstanding == 0) { in sctp_handle_str_reset_request_in()
3615 len = ntohs(req->ph.param_length); in sctp_handle_str_reset_request_in()
3616 number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t)); in sctp_handle_str_reset_request_in()
3619 temp = ntohs(req->list_of_streams[i]); in sctp_handle_str_reset_request_in()
3620 if (temp >= stcb->asoc.streamoutcnt) { in sctp_handle_str_reset_request_in()
3621 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_in()
3624 req->list_of_streams[i] = temp; in sctp_handle_str_reset_request_in()
3627 if (stcb->asoc.strmout[req->list_of_streams[i]].state == SCTP_STREAM_OPEN) { in sctp_handle_str_reset_request_in()
3628 stcb->asoc.strmout[req->list_of_streams[i]].state = SCTP_STREAM_RESET_PENDING; in sctp_handle_str_reset_request_in()
3633 for (i = 0; i < stcb->asoc.streamoutcnt; i++) { in sctp_handle_str_reset_request_in()
3634 if (stcb->asoc.strmout[i].state == SCTP_STREAM_OPEN) in sctp_handle_str_reset_request_in()
3635 stcb->asoc.strmout[i].state = SCTP_STREAM_RESET_PENDING; in sctp_handle_str_reset_request_in()
3638 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED; in sctp_handle_str_reset_request_in()
3641 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS; in sctp_handle_str_reset_request_in()
3644 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_request_in()
3645 asoc->str_reset_seq_in++; in sctp_handle_str_reset_request_in()
3646 } else if (asoc->str_reset_seq_in - 1 == seq) { in sctp_handle_str_reset_request_in()
3647 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_request_in()
3648 } else if (asoc->str_reset_seq_in - 2 == seq) { in sctp_handle_str_reset_request_in()
3649 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]); in sctp_handle_str_reset_request_in()
3663 * A) reset my str-seq's on in and out. B) Select a receive next, in sctp_handle_str_reset_request_tsn()
3664 * and set cum-ack to it. Also process this selected number as a in sctp_handle_str_reset_request_tsn()
3665 * fwd-tsn as well. C) set in the response my next sending seq. in sctp_handle_str_reset_request_tsn()
3668 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_str_reset_request_tsn()
3672 seq = ntohl(req->request_seq); in sctp_handle_str_reset_request_tsn()
3673 if (asoc->str_reset_seq_in == seq) { in sctp_handle_str_reset_request_tsn()
3674 asoc->last_reset_action[1] = stcb->asoc.last_reset_action[0]; in sctp_handle_str_reset_request_tsn()
3675 if ((asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ) == 0) { in sctp_handle_str_reset_request_tsn()
3676 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_tsn()
3681 fwdtsn.new_cumulative_tsn = htonl(stcb->asoc.highest_tsn_inside_map + 1); in sctp_handle_str_reset_request_tsn()
3686 asoc->highest_tsn_inside_map += SCTP_STREAM_RESET_TSN_DELTA; in sctp_handle_str_reset_request_tsn()
3688 sctp_log_map(0, 10, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); in sctp_handle_str_reset_request_tsn()
3690 asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->highest_tsn_inside_map; in sctp_handle_str_reset_request_tsn()
3691 asoc->mapping_array_base_tsn = asoc->highest_tsn_inside_map + 1; in sctp_handle_str_reset_request_tsn()
3692 memset(asoc->mapping_array, 0, asoc->mapping_array_size); in sctp_handle_str_reset_request_tsn()
3693 asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map; in sctp_handle_str_reset_request_tsn()
3694 memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size); in sctp_handle_str_reset_request_tsn()
3695 atomic_add_int(&asoc->sending_seq, 1); in sctp_handle_str_reset_request_tsn()
3697 asoc->last_sending_seq[1] = asoc->last_sending_seq[0]; in sctp_handle_str_reset_request_tsn()
3698 asoc->last_sending_seq[0] = asoc->sending_seq; in sctp_handle_str_reset_request_tsn()
3699 asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0]; in sctp_handle_str_reset_request_tsn()
3700 asoc->last_base_tsnsent[0] = asoc->mapping_array_base_tsn; in sctp_handle_str_reset_request_tsn()
3703 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED; in sctp_handle_str_reset_request_tsn()
3706 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0], in sctp_handle_str_reset_request_tsn()
3707 asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]); in sctp_handle_str_reset_request_tsn()
3708 asoc->str_reset_seq_in++; in sctp_handle_str_reset_request_tsn()
3709 } else if (asoc->str_reset_seq_in - 1 == seq) { in sctp_handle_str_reset_request_tsn()
3710 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0], in sctp_handle_str_reset_request_tsn()
3711 asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]); in sctp_handle_str_reset_request_tsn()
3712 } else if (asoc->str_reset_seq_in - 2 == seq) { in sctp_handle_str_reset_request_tsn()
3713 sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1], in sctp_handle_str_reset_request_tsn()
3714 asoc->last_sending_seq[1], asoc->last_base_tsnsent[1]); in sctp_handle_str_reset_request_tsn()
3728 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_str_reset_request_out()
3730 seq = ntohl(req->request_seq); in sctp_handle_str_reset_request_out()
3733 if (asoc->str_reset_seq_in == seq) { in sctp_handle_str_reset_request_out()
3734 len = ntohs(req->ph.param_length); in sctp_handle_str_reset_request_out()
3735 number_entries = ((len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t)); in sctp_handle_str_reset_request_out()
3743 tsn = ntohl(req->send_reset_at_tsn); in sctp_handle_str_reset_request_out()
3746 asoc->last_reset_action[1] = asoc->last_reset_action[0]; in sctp_handle_str_reset_request_out()
3747 if ((asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ) == 0) { in sctp_handle_str_reset_request_out()
3748 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_out()
3750 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_out()
3751 } else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) { in sctp_handle_str_reset_request_out()
3753 sctp_reset_in_stream(stcb, number_entries, req->list_of_streams); in sctp_handle_str_reset_request_out()
3754 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED; in sctp_handle_str_reset_request_out()
3768 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_request_out()
3769 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_request_out()
3772 liste->seq = seq; in sctp_handle_str_reset_request_out()
3773 liste->tsn = tsn; in sctp_handle_str_reset_request_out()
3774 liste->number_entries = number_entries; in sctp_handle_str_reset_request_out()
3775 memcpy(&liste->list_of_streams, req->list_of_streams, number_entries * sizeof(uint16_t)); in sctp_handle_str_reset_request_out()
3776 TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp); in sctp_handle_str_reset_request_out()
3777 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_IN_PROGRESS; in sctp_handle_str_reset_request_out()
3779 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_request_out()
3780 asoc->str_reset_seq_in++; in sctp_handle_str_reset_request_out()
3781 } else if ((asoc->str_reset_seq_in - 1) == seq) { in sctp_handle_str_reset_request_out()
3786 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_request_out()
3787 } else if ((asoc->str_reset_seq_in - 2) == seq) { in sctp_handle_str_reset_request_out()
3792 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]); in sctp_handle_str_reset_request_out()
3804 * max-streams we will allow it. in sctp_handle_str_reset_add_strm()
3808 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_str_reset_add_strm()
3812 seq = ntohl(str_add->request_seq); in sctp_handle_str_reset_add_strm()
3813 num_stream = ntohs(str_add->number_of_streams); in sctp_handle_str_reset_add_strm()
3815 if (asoc->str_reset_seq_in == seq) { in sctp_handle_str_reset_add_strm()
3816 num_stream += stcb->asoc.streamincnt; in sctp_handle_str_reset_add_strm()
3817 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0]; in sctp_handle_str_reset_add_strm()
3818 if ((asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ) == 0) { in sctp_handle_str_reset_add_strm()
3819 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_add_strm()
3820 } else if ((num_stream > stcb->asoc.max_inbound_streams) || in sctp_handle_str_reset_add_strm()
3824 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_add_strm()
3826 /* Ok, we can do that :-) */ in sctp_handle_str_reset_add_strm()
3830 oldstrm = stcb->asoc.strmin; in sctp_handle_str_reset_add_strm()
3831 SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *, in sctp_handle_str_reset_add_strm()
3834 if (stcb->asoc.strmin == NULL) { in sctp_handle_str_reset_add_strm()
3835 stcb->asoc.strmin = oldstrm; in sctp_handle_str_reset_add_strm()
3839 for (i = 0; i < stcb->asoc.streamincnt; i++) { in sctp_handle_str_reset_add_strm()
3840 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue); in sctp_handle_str_reset_add_strm()
3841 TAILQ_INIT(&stcb->asoc.strmin[i].uno_inqueue); in sctp_handle_str_reset_add_strm()
3842 stcb->asoc.strmin[i].sid = i; in sctp_handle_str_reset_add_strm()
3843 stcb->asoc.strmin[i].last_mid_delivered = oldstrm[i].last_mid_delivered; in sctp_handle_str_reset_add_strm()
3844 stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started; in sctp_handle_str_reset_add_strm()
3845 stcb->asoc.strmin[i].pd_api_started = oldstrm[i].pd_api_started; in sctp_handle_str_reset_add_strm()
3849 TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].inqueue, ctl, next_instrm); in sctp_handle_str_reset_add_strm()
3853 TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].uno_inqueue, ctl, next_instrm); in sctp_handle_str_reset_add_strm()
3857 for (i = stcb->asoc.streamincnt; i < num_stream; i++) { in sctp_handle_str_reset_add_strm()
3858 TAILQ_INIT(&stcb->asoc.strmin[i].inqueue); in sctp_handle_str_reset_add_strm()
3859 TAILQ_INIT(&stcb->asoc.strmin[i].uno_inqueue); in sctp_handle_str_reset_add_strm()
3860 stcb->asoc.strmin[i].sid = i; in sctp_handle_str_reset_add_strm()
3861 stcb->asoc.strmin[i].last_mid_delivered = 0xffffffff; in sctp_handle_str_reset_add_strm()
3862 stcb->asoc.strmin[i].pd_api_started = 0; in sctp_handle_str_reset_add_strm()
3863 stcb->asoc.strmin[i].delivery_started = 0; in sctp_handle_str_reset_add_strm()
3867 stcb->asoc.streamincnt = num_stream; in sctp_handle_str_reset_add_strm()
3868 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED; in sctp_handle_str_reset_add_strm()
3871 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_add_strm()
3872 asoc->str_reset_seq_in++; in sctp_handle_str_reset_add_strm()
3873 } else if ((asoc->str_reset_seq_in - 1) == seq) { in sctp_handle_str_reset_add_strm()
3878 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_add_strm()
3879 } else if ((asoc->str_reset_seq_in - 2) == seq) { in sctp_handle_str_reset_add_strm()
3884 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]); in sctp_handle_str_reset_add_strm()
3896 * max-streams we will allow it. in sctp_handle_str_reset_add_out_strm()
3900 struct sctp_association *asoc = &stcb->asoc; in sctp_handle_str_reset_add_out_strm()
3903 seq = ntohl(str_add->request_seq); in sctp_handle_str_reset_add_out_strm()
3904 num_stream = ntohs(str_add->number_of_streams); in sctp_handle_str_reset_add_out_strm()
3906 if (asoc->str_reset_seq_in == seq) { in sctp_handle_str_reset_add_out_strm()
3907 stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0]; in sctp_handle_str_reset_add_out_strm()
3908 if ((asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ) == 0) { in sctp_handle_str_reset_add_out_strm()
3909 asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_add_out_strm()
3910 } else if (stcb->asoc.stream_reset_outstanding) { in sctp_handle_str_reset_add_out_strm()
3912 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS; in sctp_handle_str_reset_add_out_strm()
3914 /* Ok, we can do that :-) */ in sctp_handle_str_reset_add_out_strm()
3917 mychk = stcb->asoc.streamoutcnt; in sctp_handle_str_reset_add_out_strm()
3920 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED; in sctp_handle_str_reset_add_out_strm()
3922 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_add_out_strm()
3925 stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED; in sctp_handle_str_reset_add_out_strm()
3928 sctp_add_stream_reset_result(chk, seq, stcb->asoc.last_reset_action[0]); in sctp_handle_str_reset_add_out_strm()
3929 asoc->str_reset_seq_in++; in sctp_handle_str_reset_add_out_strm()
3930 } else if ((asoc->str_reset_seq_in - 1) == seq) { in sctp_handle_str_reset_add_out_strm()
3935 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]); in sctp_handle_str_reset_add_out_strm()
3936 } else if ((asoc->str_reset_seq_in - 2) == seq) { in sctp_handle_str_reset_add_out_strm()
3941 sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]); in sctp_handle_str_reset_add_out_strm()
3966 /* now it may be a reset or a reset-response */ in sctp_handle_stream_reset()
3967 remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr); in sctp_handle_stream_reset()
3974 chk->copy_by_ref = 0; in sctp_handle_stream_reset()
3975 chk->rec.chunk_id.id = SCTP_STREAM_RESET; in sctp_handle_stream_reset()
3976 chk->rec.chunk_id.can_take_data = 0; in sctp_handle_stream_reset()
3977 chk->flags = 0; in sctp_handle_stream_reset()
3978 chk->asoc = &stcb->asoc; in sctp_handle_stream_reset()
3979 chk->no_fr_allowed = 0; in sctp_handle_stream_reset()
3980 chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr); in sctp_handle_stream_reset()
3981 chk->book_size_scale = 0; in sctp_handle_stream_reset()
3982 chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); in sctp_handle_stream_reset()
3983 if (chk->data == NULL) { in sctp_handle_stream_reset()
3985 if (chk->data) { in sctp_handle_stream_reset()
3986 sctp_m_freem(chk->data); in sctp_handle_stream_reset()
3987 chk->data = NULL; in sctp_handle_stream_reset()
3992 SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); in sctp_handle_stream_reset()
3995 chk->sent = SCTP_DATAGRAM_UNSENT; in sctp_handle_stream_reset()
3996 chk->snd_count = 0; in sctp_handle_stream_reset()
3997 chk->whoTo = NULL; in sctp_handle_stream_reset()
3999 ch = mtod(chk->data, struct sctp_chunkhdr *); in sctp_handle_stream_reset()
4000 ch->chunk_type = SCTP_STREAM_RESET; in sctp_handle_stream_reset()
4001 ch->chunk_flags = 0; in sctp_handle_stream_reset()
4002 ch->chunk_length = htons(chk->send_size); in sctp_handle_stream_reset()
4003 SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size); in sctp_handle_stream_reset()
4011 param_len = ntohs(ph->param_length); in sctp_handle_stream_reset()
4023 ptype = ntohs(ph->param_type); in sctp_handle_stream_reset()
4042 if (stcb->asoc.stream_reset_outstanding) { in sctp_handle_stream_reset()
4043 seq = ntohl(req_out->response_seq); in sctp_handle_stream_reset()
4044 if (seq == stcb->asoc.str_reset_seq_out) { in sctp_handle_stream_reset()
4045 /* implicit ack */ in sctp_handle_stream_reset()
4093 seq = ntohl(resp->response_seq); in sctp_handle_stream_reset()
4094 result = ntohl(resp->result); in sctp_handle_stream_reset()
4104 remaining_length -= SCTP_SIZE32(param_len); in sctp_handle_stream_reset()
4114 TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, in sctp_handle_stream_reset()
4117 stcb->asoc.ctrl_queue_cnt++; in sctp_handle_stream_reset()
4142 pktdrp_flags = cp->ch.chunk_flags; in sctp_handle_packet_dropped()
4143 pktdrp_len = ntohs(cp->ch.chunk_length); in sctp_handle_packet_dropped()
4146 if (ntohs(cp->trunc_len) <= pktdrp_len - sizeof(struct sctp_pktdrop_chunk)) { in sctp_handle_packet_dropped()
4151 limit -= sizeof(struct sctp_pktdrop_chunk); in sctp_handle_packet_dropped()
4171 chk_hdr = (struct sctp_chunkhdr *)(cp->data + offset); in sctp_handle_packet_dropped()
4172 desc.chunk_type = chk_hdr->chunk_type; in sctp_handle_packet_dropped()
4174 chk_len = (uint32_t)ntohs(chk_hdr->chunk_length); in sctp_handle_packet_dropped()
4180 if (stcb->asoc.idata_supported) { in sctp_handle_packet_dropped()
4200 data_chunk = (struct sctp_data_chunk *)(cp->data + offset); in sctp_handle_packet_dropped()
4202 desc.tsn_ifany = data_chunk->dp.tsn; in sctp_handle_packet_dropped()
4207 if (!stcb->asoc.idata_supported) { in sctp_handle_packet_dropped()
4227 idata_chunk = (struct sctp_idata_chunk *)(cp->data + offset); in sctp_handle_packet_dropped()
4229 desc.tsn_ifany = idata_chunk->dp.tsn; in sctp_handle_packet_dropped()
4247 /* Now update any rwnd --- possibly */ in sctp_handle_packet_dropped()
4254 bottle_bw = ntohl(cp->bottle_bw); in sctp_handle_packet_dropped()
4255 on_queue = ntohl(cp->current_onq); in sctp_handle_packet_dropped()
4259 a_rwnd = bottle_bw - on_queue; in sctp_handle_packet_dropped()
4264 stcb->asoc.peers_rwnd = 0; in sctp_handle_packet_dropped()
4266 if (a_rwnd > stcb->asoc.total_flight) { in sctp_handle_packet_dropped()
4267 stcb->asoc.peers_rwnd = in sctp_handle_packet_dropped()
4268 a_rwnd - stcb->asoc.total_flight; in sctp_handle_packet_dropped()
4270 stcb->asoc.peers_rwnd = 0; in sctp_handle_packet_dropped()
4272 if (stcb->asoc.peers_rwnd < in sctp_handle_packet_dropped()
4273 stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_handle_packet_dropped()
4275 stcb->asoc.peers_rwnd = 0; in sctp_handle_packet_dropped()
4285 (stcb->asoc.sat_t3_loss_recovery == 0) && in sctp_handle_packet_dropped()
4286 (stcb->asoc.sat_network)) { in sctp_handle_packet_dropped()
4292 stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped(stcb, in sctp_handle_packet_dropped()
4298 * handles all control chunks in a packet inputs: - m: mbuf chain, assumed to
4299 * still contain IP/SCTP header - stcb: is the tcb found for this packet -
4300 * offset: offset into the mbuf chain to first chunkhdr - length: is the
4301 * length of the complete packet outputs: - length: modified to remaining
4302 * length after control processing - netp: modified to new sctp_nets after
4303 * cookie-echo processing - return NULL to discard the packet (ie. no asoc,
4330 * d-mtu-ceiling for now (2k) and that should hopefully work ... in sctp_process_control()
4346 if (ntohs(ch->chunk_length) < sizeof(*ch)) { in sctp_process_control()
4348 ntohs(ch->chunk_length)); in sctp_process_control()
4355 vtag_in = ntohl(sh->v_tag); in sctp_process_control()
4357 if (ch->chunk_type == SCTP_INITIATION) { in sctp_process_control()
4359 ntohs(ch->chunk_length), vtag_in); in sctp_process_control()
4361 /* protocol error- silently discard... */ in sctp_process_control()
4368 } else if (ch->chunk_type != SCTP_COOKIE_ECHO) { in sctp_process_control()
4374 if ((ch->chunk_type == SCTP_AUTHENTICATION) && in sctp_process_control()
4376 (inp->auth_supported == 1)) { in sctp_process_control()
4380 auth_len = ntohs(ch->chunk_length); in sctp_process_control()
4397 if (ch->chunk_type == SCTP_COOKIE_ECHO) { in sctp_process_control()
4404 if (ch->chunk_type == SCTP_ASCONF && stcb == NULL) { in sctp_process_control()
4413 asconf_len = ntohs(asconf_ch->chunk_length); in sctp_process_control()
4425 } while (asconf_ch != NULL && asconf_ch->chunk_type == SCTP_ASCONF); in sctp_process_control()
4452 stcb->asoc.authenticated = 1; in sctp_process_control()
4462 mflowtype, mflowid, inp->fibnum, in sctp_process_control()
4467 asoc = &stcb->asoc; in sctp_process_control()
4468 /* ABORT and SHUTDOWN can use either v_tag... */ in sctp_process_control()
4469 if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) || in sctp_process_control()
4470 (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) || in sctp_process_control()
4471 (ch->chunk_type == SCTP_PACKET_DROPPED)) { in sctp_process_control()
4472 /* Take the T-bit always into account. */ in sctp_process_control()
4473 if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) && in sctp_process_control()
4474 (vtag_in == asoc->my_vtag)) || in sctp_process_control()
4475 (((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) && in sctp_process_control()
4476 (asoc->peer_vtag != htonl(0)) && in sctp_process_control()
4477 (vtag_in == asoc->peer_vtag))) { in sctp_process_control()
4489 if (vtag_in != asoc->my_vtag) { in sctp_process_control()
4493 vtag_in, asoc->my_vtag); in sctp_process_control()
4506 if (((ch->chunk_type == SCTP_SELECTIVE_ACK) || in sctp_process_control()
4507 (ch->chunk_type == SCTP_NR_SELECTIVE_ACK) || in sctp_process_control()
4508 (ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) && in sctp_process_control()
4510 /* implied cookie-ack.. we must have lost the ack */ in sctp_process_control()
4518 chk_length = ntohs(ch->chunk_length); in sctp_process_control()
4520 ch->chunk_type, chk_length); in sctp_process_control()
4521 SCTP_LTRACE_CHK(inp, stcb, ch->chunk_type, chk_length); in sctp_process_control()
4529 * INIT and INIT-ACK only gets the init ack "header" portion in sctp_process_control()
4533 switch (ch->chunk_type) { in sctp_process_control()
4555 if (((netp != NULL) && (*netp != NULL)) || (ch->chunk_type == SCTP_ASCONF)) { in sctp_process_control()
4562 stcb->asoc.last_control_chunk_from = *netp; in sctp_process_control()
4566 sctp_audit_log(0xB0, ch->chunk_type); in sctp_process_control()
4571 sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) && in sctp_process_control()
4572 !stcb->asoc.authenticated) { in sctp_process_control()
4577 switch (ch->chunk_type) { in sctp_process_control()
4582 (length - *offset > (int)SCTP_SIZE32(chk_length))) { in sctp_process_control()
4594 mflowtype, mflowid, inp->fibnum, in sctp_process_control()
4617 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_process_control()
4619 if ((stcb != NULL) && (stcb->asoc.total_output_queue_size)) { in sctp_process_control()
4630 /* The INIT-ACK chunk must be the only chunk. */ in sctp_process_control()
4632 (length - *offset > (int)SCTP_SIZE32(chk_length))) { in sctp_process_control()
4645 ret = -1; in sctp_process_control()
4656 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED); in sctp_process_control()
4670 ch->chunk_type == SCTP_SELECTIVE_ACK ? "SCTP_SACK" : "SCTP_NR_SACK"); in sctp_process_control()
4674 (ch->chunk_type == SCTP_SELECTIVE_ACK) ? "SCTP_SACK" : "SCTP_NR_SACK"); in sctp_process_control()
4677 if (ch->chunk_type == SCTP_SELECTIVE_ACK) { in sctp_process_control()
4683 if (stcb->asoc.nrsack_supported == 0) { in sctp_process_control()
4692 /*- in sctp_process_control()
4693 * If we have sent a shutdown-ack, we will pay no in sctp_process_control()
4699 flags = ch->chunk_flags; in sctp_process_control()
4700 if (ch->chunk_type == SCTP_SELECTIVE_ACK) { in sctp_process_control()
4704 cum_ack = ntohl(sack->sack.cum_tsn_ack); in sctp_process_control()
4705 num_seg = ntohs(sack->sack.num_gap_ack_blks); in sctp_process_control()
4707 num_dup = ntohs(sack->sack.num_dup_tsns); in sctp_process_control()
4708 a_rwnd = ntohl(sack->sack.a_rwnd); in sctp_process_control()
4721 cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack); in sctp_process_control()
4722 num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks); in sctp_process_control()
4723 num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks); in sctp_process_control()
4724 num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns); in sctp_process_control()
4725 a_rwnd = ntohl(nr_sack->nr_sack.a_rwnd); in sctp_process_control()
4736 (ch->chunk_type == SCTP_SELECTIVE_ACK) ? "SCTP_SACK" : "SCTP_NR_SACK", in sctp_process_control()
4738 stcb->asoc.seen_a_sack_this_pkt = 1; in sctp_process_control()
4739 if ((stcb->asoc.pr_sctp_cnt == 0) && in sctp_process_control()
4741 SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) && in sctp_process_control()
4742 (stcb->asoc.saw_sack_with_frags == 0) && in sctp_process_control()
4743 (stcb->asoc.saw_sack_with_nr_frags == 0) && in sctp_process_control()
4744 (!TAILQ_EMPTY(&stcb->asoc.sent_queue))) { in sctp_process_control()
4768 if (TAILQ_EMPTY(&stcb->asoc.send_queue) && in sctp_process_control()
4769 TAILQ_EMPTY(&stcb->asoc.sent_queue) && in sctp_process_control()
4770 (stcb->asoc.stream_queue_cnt == 0)) { in sctp_process_control()
4845 if ((stcb != NULL) && (stcb->asoc.total_output_queue_size > 0)) { in sctp_process_control()
4848 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_process_control()
4858 /*- in sctp_process_control()
4861 * listening responded to a INIT-ACK and then in sctp_process_control()
4877 (((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) && in sctp_process_control()
4878 inp->sctp_socket->sol_qlen >= inp->sctp_socket->sol_qlimit))) { in sctp_process_control()
4879 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && in sctp_process_control()
4894 if (inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | in sctp_process_control()
4955 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { in sctp_process_control()
4956 if (chk->whoTo != NULL) { in sctp_process_control()
4961 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo); in sctp_process_control()
4970 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_process_control()
4972 if ((stcb) && (stcb->asoc.total_output_queue_size)) { in sctp_process_control()
4990 if (stcb->asoc.ecn_supported == 0) { in sctp_process_control()
5005 if (stcb->asoc.ecn_supported == 0) { in sctp_process_control()
5017 (length - *offset > (int)SCTP_SIZE32(chk_length))) { in sctp_process_control()
5032 if (stcb->asoc.asconf_supported == 0) { in sctp_process_control()
5045 if (stcb->asoc.asconf_supported == 0) { in sctp_process_control()
5055 stcb->asoc.overall_error_count, in sctp_process_control()
5060 stcb->asoc.overall_error_count = 0; in sctp_process_control()
5070 ch->chunk_type == SCTP_FORWARD_CUM_TSN ? "FORWARD_TSN" : "I_FORWARD_TSN"); in sctp_process_control()
5074 if (stcb->asoc.prsctp_supported == 0) { in sctp_process_control()
5080 if (((stcb->asoc.idata_supported == 1) && (ch->chunk_type == SCTP_FORWARD_CUM_TSN)) || in sctp_process_control()
5081 ((stcb->asoc.idata_supported == 0) && (ch->chunk_type == SCTP_IFORWARD_CUM_TSN))) { in sctp_process_control()
5082 if (ch->chunk_type == SCTP_FORWARD_CUM_TSN) { in sctp_process_control()
5083 …SCTP_SNPRINTF(msg, sizeof(msg), "%s", "FORWARD-TSN chunk received when I-FORWARD-TSN was negotiate… in sctp_process_control()
5085 …SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-FORWARD-TSN chunk received when FORWARD-TSN was negotiate… in sctp_process_control()
5093 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { in sctp_process_control()
5103 stcb->asoc.last_data_chunk_from = stcb->asoc.last_control_chunk_from; in sctp_process_control()
5117 if (stcb->asoc.reconfig_supported == 0) { in sctp_process_control()
5134 if (stcb->asoc.pktdrop_supported == 0) { in sctp_process_control()
5158 if (stcb->asoc.auth_supported == 0) { in sctp_process_control()
5179 stcb->asoc.authenticated = 1; in sctp_process_control()
5186 if ((ch->chunk_type & 0x40) && in sctp_process_control()
5197 len = min(SCTP_SIZE32(chk_length), (uint32_t)(length - *offset)); in sctp_process_control()
5199 cause->code = htons(SCTP_CAUSE_UNRECOG_CHUNK); in sctp_process_control()
5200 cause->length = htons((uint16_t)(len + sizeof(struct sctp_gen_error_cause))); in sctp_process_control()
5215 if ((ch->chunk_type & 0x80) == 0) { in sctp_process_control()
5221 } /* switch (ch->chunk_type) */ in sctp_process_control()
5277 cksum_in_hdr = sh->checksum; in sctp_common_input_processing()
5282 sh->checksum = 0; in sctp_common_input_processing()
5284 sh->checksum = cksum_in_hdr; in sctp_common_input_processing()
5321 if ((ch->chunk_type != SCTP_INITIATION) && in sctp_common_input_processing()
5322 (net != NULL) && (net->port != port)) { in sctp_common_input_processing()
5323 if (net->port == 0) { in sctp_common_input_processing()
5328 net->mtu -= sizeof(struct udphdr); in sctp_common_input_processing()
5329 if (stcb->asoc.smallest_mtu > net->mtu) { in sctp_common_input_processing()
5330 sctp_pathmtu_adjustment(stcb, net->mtu, true); in sctp_common_input_processing()
5337 net->mtu += sizeof(struct udphdr); in sctp_common_input_processing()
5340 net->port = port; in sctp_common_input_processing()
5344 net->flowtype = mflowtype; in sctp_common_input_processing()
5345 net->flowid = mflowid; in sctp_common_input_processing()
5349 if (stcb->asoc.pktdrop_supported) { in sctp_common_input_processing()
5372 if (stcb->asoc.rcv_edmid == SCTP_EDMID_NONE) { in sctp_common_input_processing()
5375 KASSERT(stcb->asoc.rcv_edmid == SCTP_EDMID_LOWER_LAYER_DTLS, in sctp_common_input_processing()
5376 ("Unexpected EDMID %u", stcb->asoc.rcv_edmid)); in sctp_common_input_processing()
5382 if (sh->dest_port == htons(0)) { in sctp_common_input_processing()
5394 if ((ch->chunk_type != SCTP_INITIATION) && in sctp_common_input_processing()
5395 (net != NULL) && (net->port != port)) { in sctp_common_input_processing()
5396 if (net->port == 0) { in sctp_common_input_processing()
5398 net->mtu -= sizeof(struct udphdr); in sctp_common_input_processing()
5399 if (stcb->asoc.smallest_mtu > net->mtu) { in sctp_common_input_processing()
5400 sctp_pathmtu_adjustment(stcb, net->mtu, true); in sctp_common_input_processing()
5404 net->mtu += sizeof(struct udphdr); in sctp_common_input_processing()
5407 net->port = port; in sctp_common_input_processing()
5411 net->flowtype = mflowtype; in sctp_common_input_processing()
5412 net->flowid = mflowid; in sctp_common_input_processing()
5420 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { in sctp_common_input_processing()
5427 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { in sctp_common_input_processing()
5431 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { in sctp_common_input_processing()
5434 (ch->chunk_type != SCTP_INIT))) { in sctp_common_input_processing()
5451 stcb->asoc.authenticated = 0; in sctp_common_input_processing()
5452 stcb->asoc.seen_a_sack_this_pkt = 0; in sctp_common_input_processing()
5454 (void *)stcb, stcb->asoc.state); in sctp_common_input_processing()
5456 if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) || in sctp_common_input_processing()
5457 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) { in sctp_common_input_processing()
5458 /*- in sctp_common_input_processing()
5471 mflowtype, mflowid, inp->fibnum, in sctp_common_input_processing()
5486 * This covers us if the cookie-echo was there and in sctp_common_input_processing()
5489 inp = stcb->sctp_ep; in sctp_common_input_processing()
5491 if ((ch->chunk_type != SCTP_INITIATION) && in sctp_common_input_processing()
5492 (net != NULL) && (net->port != port)) { in sctp_common_input_processing()
5493 if (net->port == 0) { in sctp_common_input_processing()
5495 net->mtu -= sizeof(struct udphdr); in sctp_common_input_processing()
5496 if (stcb->asoc.smallest_mtu > net->mtu) { in sctp_common_input_processing()
5497 sctp_pathmtu_adjustment(stcb, net->mtu, true); in sctp_common_input_processing()
5501 net->mtu += sizeof(struct udphdr); in sctp_common_input_processing()
5504 net->port = port; in sctp_common_input_processing()
5510 * no control chunks, so pre-process DATA chunks (these in sctp_common_input_processing()
5520 sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) { in sctp_common_input_processing()
5537 if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) { in sctp_common_input_processing()
5566 sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) && in sctp_common_input_processing()
5567 !stcb->asoc.authenticated) { in sctp_common_input_processing()
5586 * shows us the cookie-ack was lost. Imply it was in sctp_common_input_processing()
5599 mflowtype, mflowid, inp->fibnum, in sctp_common_input_processing()
5638 (stcb->asoc.ecn_supported == 1) && in sctp_common_input_processing()
5648 if (SCTP_TSN_GT(stcb->asoc.highest_tsn_inside_nr_map, stcb->asoc.highest_tsn_inside_map)) { in sctp_common_input_processing()
5649 highest_tsn = stcb->asoc.highest_tsn_inside_nr_map; in sctp_common_input_processing()
5651 highest_tsn = stcb->asoc.highest_tsn_inside_map; in sctp_common_input_processing()
5653 was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn); in sctp_common_input_processing()
5654 stcb->asoc.send_sack = 1; in sctp_common_input_processing()
5657 stcb->asoc.send_sack = 1; in sctp_common_input_processing()
5667 stcb->asoc.peers_rwnd, in sctp_common_input_processing()
5668 TAILQ_EMPTY(&stcb->asoc.control_send_queue), in sctp_common_input_processing()
5669 stcb->asoc.total_flight); in sctp_common_input_processing()
5670 un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight); in sctp_common_input_processing()
5671 if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) { in sctp_common_input_processing()
5672 cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq; in sctp_common_input_processing()
5674 if (!TAILQ_EMPTY(&stcb->asoc.asconf_send_queue) || in sctp_common_input_processing()
5676 stcb->asoc.trigger_reset || in sctp_common_input_processing()
5678 (stcb->asoc.peers_rwnd > 0 || stcb->asoc.total_flight == 0))) { in sctp_common_input_processing()
5692 /* reduce ref-count */ in sctp_common_input_processing()
5737 m->m_pkthdr.len, in sctp_input_with_port()
5738 if_name(m->m_pkthdr.rcvif), in sctp_input_with_port()
5739 (int)m->m_pkthdr.csum_flags, CSUM_BITS); in sctp_input_with_port()
5740 mflowid = m->m_pkthdr.flowid; in sctp_input_with_port()
5756 offset -= sizeof(struct sctp_chunkhdr); in sctp_input_with_port()
5760 src.sin_port = sh->src_port; in sctp_input_with_port()
5761 src.sin_addr = ip->ip_src; in sctp_input_with_port()
5765 dst.sin_port = sh->dest_port; in sctp_input_with_port()
5766 dst.sin_addr = ip->ip_dst; in sctp_input_with_port()
5767 length = ntohs(ip->ip_len); in sctp_input_with_port()
5782 ecn_bits = ip->ip_tos; in sctp_input_with_port()
5783 if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { in sctp_input_with_port()
5826 flowid = m->m_pkthdr.flowid; in sctp_input()
5841 tag = htonl(sh->v_tag); in sctp_input()
5842 flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port); in sctp_input()
5843 m->m_pkthdr.flowid = flowid; in sctp_input()