18c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*-
28c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
58c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *
68c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Redistribution and use in source and binary forms, with or without
78c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * modification, are permitted provided that the following conditions are met:
88c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *
98c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a) Redistributions of source code must retain the above copyright notice,
100ac02f34d6041cd0018437596a5a9a94685e6919tuexen *    this list of conditions and the following disclaimer.
118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *
128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * b) Redistributions in binary form must reproduce the above copyright
138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *    notice, this list of conditions and the following disclaimer in
140ac02f34d6041cd0018437596a5a9a94685e6919tuexen *    the documentation and/or other materials provided with the distribution.
158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *
168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * c) Neither the name of Cisco Systems, Inc. nor the names of its
178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *    contributors may be used to endorse or promote products derived
188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *    from this software without specific prior written permission.
198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *
208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THE POSSIBILITY OF SUCH DAMAGE.
318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __FreeBSD__
348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <sys/cdefs.h>
358975bd5397c2ec97f50e0b87b544054e0536bfe1t__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 271230 2014-09-07 18:05:37Z tuexen $");
368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_os.h>
398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_var.h>
408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_sysctl.h>
418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_pcb.h>
428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_header.h>
438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctputil.h>
448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_output.h>
458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_input.h>
468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_auth.h>
478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_indata.h>
488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_asconf.h>
498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_bsd_addr.h>
508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_timer.h>
518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_crc32.h>
5248830a703639020b04dbea0128bc37fd8a8ab35et#if defined(INET) || defined(INET6)
530ac02f34d6041cd0018437596a5a9a94685e6919tuexen#if !defined(__Userspace_os_Windows)
548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/udp.h>
5581616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif
566c632b3f6e570981666f8a3ff4be34eaf1735835t#endif
578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__)
588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <sys/smp.h>
598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__)
628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define APPLE_FILE_NO 2
638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *net;
7023273859c39742f09cc5ec7c9bf32ff225661e82tuexen
718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* This now not only stops all cookie timers
728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * it also stops any INIT timers as well. This
738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * will make sure that the timers are stopped in
748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * all collision cases.
758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_LOCK_ASSERT(stcb);
778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (net->rxt_timer.type == SCTP_TIMER_TYPE_COOKIE) {
798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE,
808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->sctp_ep,
818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb,
82b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen					net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_1);
838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (net->rxt_timer.type == SCTP_TIMER_TYPE_INIT) {
848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_stop(SCTP_TIMER_TYPE_INIT,
858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->sctp_ep,
868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb,
87b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen					net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_2);
888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* INIT handler */
938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
94e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexensctp_handle_init(struct mbuf *m, int iphlen, int offset,
95e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen                 struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
9651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                 struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
9751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                 struct sctp_tcb *stcb, int *abort_no_unlock,
9851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
9951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                 uint8_t use_mflowid, uint32_t mflowid,
10051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
10151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                 uint32_t vrf_id, uint16_t port)
1028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
1038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init *init;
1048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *op_err;
1058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_init: handling INIT tcb:%p\n",
107ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t		(void *)stcb);
1088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL) {
1098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_RLOCK(inp);
1108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
11123273859c39742f09cc5ec7c9bf32ff225661e82tuexen	/* validate length */
1128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
1138f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
114e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
11551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
11651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
11751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       vrf_id, port);
1198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
1238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* validate parameters */
12423273859c39742f09cc5ec7c9bf32ff225661e82tuexen	init = &cp->init;
1258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init->initiate_tag == 0) {
1268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send abort */
1278f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
128e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
12951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
13051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
13151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       vrf_id, port);
1338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
1378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
1388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* invalid parameter... send abort */
1398f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
140e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
14151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
14251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
14351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       vrf_id, port);
1458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
1498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init->num_inbound_streams == 0) {
1508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send abort */
1518f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
152e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
15351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
15451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
15551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       vrf_id, port);
1578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
1618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init->num_outbound_streams == 0) {
1628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send abort */
1638f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
164e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
16551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
16651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
16751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       vrf_id, port);
1698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
1738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
17423273859c39742f09cc5ec7c9bf32ff225661e82tuexen					   offset + ntohs(cp->ch.chunk_length))) {
1758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* auth parameter(s) error... send abort */
1768f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
1778f9e45fea288542b24a6bda01269c6fc184d991at		                             "Problem with AUTH parameters");
1788f9e45fea288542b24a6bda01269c6fc184d991at		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
17951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
18051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
18151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
18251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, port);
1838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb)
1848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
1858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto outnow;
1868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
18723273859c39742f09cc5ec7c9bf32ff225661e82tuexen	/* We are only accepting if we have a socket with positive so_qlimit.*/
18823273859c39742f09cc5ec7c9bf32ff225661e82tuexen	if ((stcb == NULL) &&
18923273859c39742f09cc5ec7c9bf32ff225661e82tuexen	    ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
19023273859c39742f09cc5ec7c9bf32ff225661e82tuexen	     (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
19123273859c39742f09cc5ec7c9bf32ff225661e82tuexen	     (inp->sctp_socket == NULL) ||
19223273859c39742f09cc5ec7c9bf32ff225661e82tuexen	     (inp->sctp_socket->so_qlimit == 0))) {
19323273859c39742f09cc5ec7c9bf32ff225661e82tuexen		/*
19423273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * FIX ME ?? What about TCP model and we have a
19523273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * match/restart case? Actually no fix is needed.
19623273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * the lookup will always find the existing assoc so stcb
19723273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * would not be NULL. It may be questionable to do this
19823273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * since we COULD just send back the INIT-ACK and hope that
19923273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * the app did accept()'s by the time the COOKIE was sent. But
20023273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * there is a price to pay for COOKIE generation and I don't
20123273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * want to pay it on the chance that the app will actually do
20223273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * some accepts(). The App just looses and should NOT be in
20323273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 * this state :-)
20423273859c39742f09cc5ec7c9bf32ff225661e82tuexen		 */
20523273859c39742f09cc5ec7c9bf32ff225661e82tuexen		if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
2068f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
2078f9e45fea288542b24a6bda01269c6fc184d991at			                             "No listener");
2088f9e45fea288542b24a6bda01269c6fc184d991at			sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
20951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
21051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                use_mflowid, mflowid,
21151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
21251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                vrf_id, port);
21323273859c39742f09cc5ec7c9bf32ff225661e82tuexen		}
21423273859c39742f09cc5ec7c9bf32ff225661e82tuexen		goto outnow;
21523273859c39742f09cc5ec7c9bf32ff225661e82tuexen	}
21623273859c39742f09cc5ec7c9bf32ff225661e82tuexen	if ((stcb != NULL) &&
21723273859c39742f09cc5ec7c9bf32ff225661e82tuexen	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
21823273859c39742f09cc5ec7c9bf32ff225661e82tuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending SHUTDOWN-ACK\n");
21923273859c39742f09cc5ec7c9bf32ff225661e82tuexen		sctp_send_shutdown_ack(stcb, NULL);
22023273859c39742f09cc5ec7c9bf32ff225661e82tuexen		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
22123273859c39742f09cc5ec7c9bf32ff225661e82tuexen	} else {
22223273859c39742f09cc5ec7c9bf32ff225661e82tuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
223e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, src, dst,
224e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       sh, cp,
22551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
22651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
22751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
22851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, port,
22923273859c39742f09cc5ec7c9bf32ff225661e82tuexen		                       ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
23023273859c39742f09cc5ec7c9bf32ff225661e82tuexen	}
2318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen outnow:
2328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL) {
2338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_RUNLOCK(inp);
2348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
2358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
2368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
2388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * process peer "INIT/INIT-ACK" chunk returns value < 0 on error
2398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
2408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint
2428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
2438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
2448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_UNUSED
2458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
2468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen)
2478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
2488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int unsent_data = 0;
2498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int i;
2508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_stream_queue_pending *sp;
2518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
2528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
2538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* This function returns the number of streams that have
2548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * true unsent data on them. Note that as it looks through
2558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * it will clean up any places that have old data that
2568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * has been sent but left at top of stream queue.
2578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
2588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
2598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_SEND_LOCK(stcb);
2608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
2618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Check to see if some data queued */
2628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
2638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*sa_ignore FREED_MEMORY*/
2648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sp = TAILQ_FIRST(&stcb->asoc.strmout[i].outqueue);
2658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sp == NULL) {
2668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				continue;
2678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
2688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((sp->msg_is_complete) &&
2698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (sp->length == 0)  &&
2708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (sp->sender_all_done)) {
2718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* We are doing differed cleanup. Last
2728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * time through when we took all the data
2738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * the sender_all_done was not set.
2748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
2758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (sp->put_last_out == 0) {
2768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
2778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d\n",
2788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					            sp->sender_all_done,
2798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					            sp->length,
2808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					            sp->msg_is_complete,
2818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					            sp->put_last_out);
2828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
2838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1);
2848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_REMOVE(&stcb->asoc.strmout[i].outqueue, sp, next);
2858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (sp->net) {
2868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_free_remote_addr(sp->net);
2878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sp->net = NULL;
2888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
2898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (sp->data) {
2908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_m_freem(sp->data);
2918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sp->data = NULL;
2928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
2938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_a_strmoq(stcb, sp, so_locked);
2948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
2958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				unsent_data++;
2968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
2978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
2988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
2998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
3008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_SEND_UNLOCK(stcb);
3018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (unsent_data);
3028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
3038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
3050ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
3068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
3078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init *init;
3088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
3098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *lnet;
3108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int i;
3118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init = &cp->init;
3138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
3148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* save off parameters */
3158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->peer_vtag = ntohl(init->initiate_tag);
3168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->peers_rwnd = ntohl(init->a_rwnd);
3178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* init tsn's */
3188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1;
3198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!TAILQ_EMPTY(&asoc->nets)) {
3218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* update any ssthresh's that may have a default */
3228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
3238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			lnet->ssthresh = asoc->peers_rwnd;
3248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE|SCTP_CWND_LOGGING_ENABLE)) {
3258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_INITIALIZATION);
3268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
3278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
3298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
3308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_SEND_LOCK(stcb);
3318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) {
3328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		unsigned int newcnt;
3338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_stream_out *outs;
3348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_stream_queue_pending *sp, *nsp;
3358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_tmit_chunk *chk, *nchk;
3368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* abandon the upper streams */
3388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		newcnt = ntohs(init->num_inbound_streams);
3398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
3408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk->rec.data.stream_number >= newcnt) {
3418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
3428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->send_queue_cnt--;
343446be8e8a472f6e688885674d2430118fc4be5d7t				if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
344446be8e8a472f6e688885674d2430118fc4be5d7t					asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
345446be8e8a472f6e688885674d2430118fc4be5d7t#ifdef INVARIANTS
346446be8e8a472f6e688885674d2430118fc4be5d7t				} else {
347446be8e8a472f6e688885674d2430118fc4be5d7t					panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
348446be8e8a472f6e688885674d2430118fc4be5d7t#endif
349446be8e8a472f6e688885674d2430118fc4be5d7t				}
3508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chk->data != NULL) {
3518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_free_bufspace(stcb, asoc, chk, 1);
35247674b651417d493ff4e0318113fd7beeef119dbtuexen					sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
35347674b651417d493ff4e0318113fd7beeef119dbtuexen					                0, chk, SCTP_SO_NOT_LOCKED);
3548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (chk->data) {
3558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_m_freem(chk->data);
3568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						chk->data = NULL;
3578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
3588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
3598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
3608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*sa_ignore FREED_MEMORY*/
3618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
3628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
3638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->strmout) {
3648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			for (i = newcnt; i < asoc->pre_open_streams; i++) {
3658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				outs = &asoc->strmout[i];
3668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
3678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					TAILQ_REMOVE(&outs->outqueue, sp, next);
3688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					asoc->stream_queue_cnt--;
3698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL,
37047674b651417d493ff4e0318113fd7beeef119dbtuexen					    stcb, 0, sp, SCTP_SO_NOT_LOCKED);
3718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (sp->data) {
3728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_m_freem(sp->data);
3738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sp->data = NULL;
3748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
3758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (sp->net) {
3768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_free_remote_addr(sp->net);
3778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sp->net = NULL;
3788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
3798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* Free the chunk */
3808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED);
3818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*sa_ignore FREED_MEMORY*/
3828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
3838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
3848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
3858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* cut back the count */
3868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->pre_open_streams = newcnt;
3878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
3888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_SEND_UNLOCK(stcb);
3898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams;
3908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* EY - nr_sack: initialize highest tsn in nr_mapping_array */
3928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
3938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
3948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_log_map(0, 5, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
3958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
3968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* This is the next one we expect */
3978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
39832a191a90b5c914a02047389c5b3197e08fc9841tuexen
3998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
4008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
4018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
4038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* open the requested streams */
4048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->strmin != NULL) {
4068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Free the old ones */
4078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_queued_to_read *ctl, *nctl;
4088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		for (i = 0; i < asoc->streamincnt; i++) {
4108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) {
4118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next);
4128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_remote_addr(ctl->whoFrom);
4138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ctl->whoFrom = NULL;
4148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_m_freem(ctl->data);
4158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ctl->data = NULL;
4168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_a_readq(stcb, ctl);
4178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
4188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
4198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
4208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
421f72906cec69866943ecd6c46cc74c87a8b5e9d5ft	if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) {
422f72906cec69866943ecd6c46cc74c87a8b5e9d5ft		asoc->streamincnt = ntohs(init->num_outbound_streams);
423f72906cec69866943ecd6c46cc74c87a8b5e9d5ft	} else {
424f72906cec69866943ecd6c46cc74c87a8b5e9d5ft		asoc->streamincnt = asoc->max_inbound_streams;
4258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
4268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
4278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sizeof(struct sctp_stream_in), SCTP_M_STRMI);
4288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->strmin == NULL) {
4298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* we didn't get memory for the streams! */
4308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "process_init: couldn't get memory for the streams!\n");
4318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
4328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
4338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	for (i = 0; i < asoc->streamincnt; i++) {
4348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->strmin[i].stream_no = i;
4358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->strmin[i].last_sequence_delivered = 0xffff;
4368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_INIT(&asoc->strmin[i].inqueue);
4378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->strmin[i].delivery_started = 0;
4388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
4398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
4408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * load_address_from_init will put the addresses into the
4418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * association when the COOKIE is processed or the INIT-ACK is
4428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * processed. Both types of COOKIE's existing and new call this
4438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * routine. It will remove addresses that are no longer in the
4448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * association (for the restarting case where addresses are
4458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * removed). Up front when the INIT arrives we will discard it if it
4468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * is a restart and new addresses have been added.
4478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
4480ac02f34d6041cd0018437596a5a9a94685e6919tuexen	/* sa_ignore MEMLEAK */
4498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
4508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
4518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
4538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * INIT-ACK message processing/consumption returns value < 0 on error
4548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
4558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
456e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexensctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
457e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen                      struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
45851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                      struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
45951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                      struct sctp_nets *net, int *abort_no_unlock,
46051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
46151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		      uint8_t use_mflowid, uint32_t mflowid,
46251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
46351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                      uint32_t vrf_id)
4648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
4658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
4668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *op_err;
4678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int retval, abort_flag;
4688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t initack_limit;
469b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	int nat_friendly = 0;
4708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* First verify that we have no illegal param's */
4728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	abort_flag = 0;
4738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	op_err = sctp_arethere_unrecognized_parameters(m,
4758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       (offset + sizeof(struct sctp_init_chunk)),
4768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       &abort_flag, (struct sctp_chunkhdr *)cp, &nat_friendly);
4778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (abort_flag) {
4788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Send an abort and notify peer */
47947674b651417d493ff4e0318113fd7beeef119dbtuexen		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
4808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
4818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
4828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
4838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
4848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->peer_supports_nat = (uint8_t)nat_friendly;
4858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process the peer's parameters in the INIT-ACK */
4860ac02f34d6041cd0018437596a5a9a94685e6919tuexen	retval = sctp_process_init((struct sctp_init_chunk *)cp, stcb);
4878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (retval < 0) {
4888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (retval);
4898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
4908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	initack_limit = offset + ntohs(cp->ch.chunk_length);
4918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* load all addresses */
4920ac02f34d6041cd0018437596a5a9a94685e6919tuexen	if ((retval = sctp_load_addresses_from_init(stcb, m,
493e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	    (offset + sizeof(struct sctp_init_chunk)), initack_limit,
494e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	    src, dst, NULL))) {
4958f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
4968f9e45fea288542b24a6bda01269c6fc184d991at		                             "Problem with address parameters");
4978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1,
4988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"Load addresses from INIT causes an abort %d\n",
4998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			retval);
500e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
5018f9e45fea288542b24a6bda01269c6fc184d991at		                       src, dst, sh, op_err,
50251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
50351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
50451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
50551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
5068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
5078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
5088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
5098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* if the peer doesn't support asconf, flush the asconf queue */
510fb3816eaffe5878bb1286adb120fd160da178a05t	if (asoc->asconf_supported == 0) {
5118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_asconf_addr *param, *nparam;
5128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) {
5148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_REMOVE(&asoc->asconf_queue, param, next);
5158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_FREE(param, SCTP_M_ASC_ADDR);
5168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
5178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
5188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
5208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    stcb->asoc.local_hmacs);
5218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (op_err) {
5228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_queue_op_err(stcb, op_err);
5238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* queuing will steal away the mbuf chain to the out queue */
5248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		op_err = NULL;
5258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
5268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* extract the cookie and queue it to "echo" it back... */
5278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       stcb->asoc.overall_error_count,
5308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       0,
5318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       SCTP_FROM_SCTP_INPUT,
5328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       __LINE__);
5338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
5348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb->asoc.overall_error_count = 0;
5358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	net->error_count = 0;
5368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
5388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Cancel the INIT timer, We do this first before queueing the
5398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * cookie. We always cancel at the primary to assue that we are
5408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * canceling the timer started by the INIT which always goes to the
5418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * primary.
5428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
5438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, stcb,
5448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    asoc->primary_destination, SCTP_FROM_SCTP_INPUT+SCTP_LOC_4);
5458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* calculate the RTO */
54732a191a90b5c914a02047389c5b3197e08fc9841tuexen	net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy,
5488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				      SCTP_RTT_FROM_NON_DATA);
5498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	retval = sctp_send_cookie_echo(m, offset, stcb, net);
5518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (retval < 0) {
5528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
5538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * No cookie, we probably should send a op error. But in any
5548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * case if there is no cookie in the INIT-ACK, we can
5558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * abandon the peer, its broke.
5568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
5578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (retval == -3) {
5588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* We abort with an error of missing mandatory param */
5598f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
5608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (op_err) {
5618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
5628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * Expand beyond to include the mandatory
5638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * param cookie
5648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
5658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_inv_mandatory_param *mp;
5668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_BUF_LEN(op_err) =
5688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    sizeof(struct sctp_inv_mandatory_param);
5698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mp = mtod(op_err,
5708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    struct sctp_inv_mandatory_param *);
5718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Subtract the reserved param */
5728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mp->length =
5738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    htons(sizeof(struct sctp_inv_mandatory_param) - 2);
5748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mp->num_param = htonl(1);
5758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mp->param = htons(SCTP_STATE_COOKIE);
5768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mp->resv = 0;
5778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
5788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
579e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen			                       src, dst, sh, op_err,
58051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
58151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                       use_mflowid, mflowid,
58251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
58351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                       vrf_id, net->port);
5848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*abort_no_unlock = 1;
5858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
5868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (retval);
5878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
5888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
5908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
5918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
5928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
5938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
5948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net)
5958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
596bfb1bf7e665a02b48026482bf33d05c83dfad73bt	union sctp_sockstore store;
5978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *r_net, *f_net;
5988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct timeval tv;
5998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int req_prim = 0;
6008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t old_error_counter;
6018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
6028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
6038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Invalid length */
6048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
6058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
6068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
6078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	memset(&store, 0, sizeof(store));
6088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (cp->heartbeat.hb_info.addr_family) {
6098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET
6108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case AF_INET:
6118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
612bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin.sin_family = cp->heartbeat.hb_info.addr_family;
6137b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN
614bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin.sin_len = cp->heartbeat.hb_info.addr_len;
6158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
616bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin.sin_port = stcb->rport;
617bfb1bf7e665a02b48026482bf33d05c83dfad73bt			memcpy(&store.sin.sin_addr, cp->heartbeat.hb_info.address,
618bfb1bf7e665a02b48026482bf33d05c83dfad73bt			       sizeof(store.sin.sin_addr));
6198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
6208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
6218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
6228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
6238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
6248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6
6258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case AF_INET6:
6268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
627bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin6.sin6_family = cp->heartbeat.hb_info.addr_family;
6287b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN
629bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin6.sin6_len = cp->heartbeat.hb_info.addr_len;
6308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
631bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sin6.sin6_port = stcb->rport;
6321b77b4778bf4ea247d4e18d1694d8dc2d3d1d150t			memcpy(&store.sin6.sin6_addr, cp->heartbeat.hb_info.address, sizeof(struct in6_addr));
6338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
6348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
6358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
6368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
6378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
6386a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#if defined(__Userspace__)
6396a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen	case AF_CONN:
6406a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_conn)) {
641bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sconn.sconn_family = cp->heartbeat.hb_info.addr_family;
6427b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SCONN_LEN
643bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sconn.sconn_len = cp->heartbeat.hb_info.addr_len;
6446a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
645bfb1bf7e665a02b48026482bf33d05c83dfad73bt			store.sconn.sconn_port = stcb->rport;
6461b77b4778bf4ea247d4e18d1694d8dc2d3d1d150t			memcpy(&store.sconn.sconn_addr, cp->heartbeat.hb_info.address, sizeof(void *));
6476a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		} else {
6486a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen			return;
6496a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		}
6506a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		break;
6516a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
6528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
6538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
6548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
655bfb1bf7e665a02b48026482bf33d05c83dfad73bt	r_net = sctp_findnet(stcb, &store.sa);
6568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (r_net == NULL) {
6578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "Huh? I can't find the address I sent it to, discard\n");
6588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
6598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
6608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((r_net && (r_net->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
6618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (r_net->heartbeat_random1 == cp->heartbeat.hb_info.random_value1) &&
6628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (r_net->heartbeat_random2 == cp->heartbeat.hb_info.random_value2)) {
6638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
6648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * If the its a HB and it's random value is correct when can
6658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * confirm the destination.
6668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
6678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		r_net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
6688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (r_net->dest_state & SCTP_ADDR_REQ_PRIMARY) {
6698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.primary_destination = r_net;
6708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			r_net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
6718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			f_net = TAILQ_FIRST(&stcb->asoc.nets);
6728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (f_net != r_net) {
6738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* first one on the list is NOT the primary
6748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * sctp_cmpaddr() is much more efficent if
6758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * the primary is the first on the list, make it
6768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * so.
6778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
6788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_REMOVE(&stcb->asoc.nets, r_net, sctp_next);
6798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_INSERT_HEAD(&stcb->asoc.nets, r_net, sctp_next);
6808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
6818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			req_prim = 1;
6828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
6838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
6848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    stcb, 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
6858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
6868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
6878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
6888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	old_error_counter = r_net->error_count;
6898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	r_net->error_count = 0;
6908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	r_net->hb_responded = 1;
6918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	tv.tv_sec = cp->heartbeat.hb_info.time_value_1;
6928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	tv.tv_usec = cp->heartbeat.hb_info.time_value_2;
6938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Now lets do a RTO with this */
69432a191a90b5c914a02047389c5b3197e08fc9841tuexen	r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy,
6958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_RTT_FROM_NON_DATA);
6968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!(r_net->dest_state & SCTP_ADDR_REACHABLE)) {
6978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		r_net->dest_state |= SCTP_ADDR_REACHABLE;
6988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb,
69947674b651417d493ff4e0318113fd7beeef119dbtuexen				0, (void *)r_net, SCTP_SO_NOT_LOCKED);
7008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (r_net->dest_state & SCTP_ADDR_PF) {
7028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		r_net->dest_state &= ~SCTP_ADDR_PF;
7038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
7048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (old_error_counter > 0) {
7068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
7078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
7088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (r_net == stcb->asoc.primary_destination) {
7108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.alternate) {
7118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* release the alternate, primary is good */
7128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_free_remote_addr(stcb->asoc.alternate);
7138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.alternate = NULL;
7148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
7158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Mobility adaptation */
7178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (req_prim) {
7188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
719e2828360ea9cf8951730d46f5c14626c9425cb30t		                                 SCTP_MOBILITY_BASE) ||
720e2828360ea9cf8951730d46f5c14626c9425cb30t		    sctp_is_mobility_feature_on(stcb->sctp_ep,
721e2828360ea9cf8951730d46f5c14626c9425cb30t		                                SCTP_MOBILITY_FASTHANDOFF)) &&
722e2828360ea9cf8951730d46f5c14626c9425cb30t		    sctp_is_mobility_feature_on(stcb->sctp_ep,
723e2828360ea9cf8951730d46f5c14626c9425cb30t		                                SCTP_MOBILITY_PRIM_DELETED)) {
7248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER+SCTP_LOC_7);
7268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
7278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_MOBILITY_FASTHANDOFF)) {
7288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_assoc_immediate_retrans(stcb,
7298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.primary_destination);
7308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
7318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
7328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_MOBILITY_BASE)) {
7338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_move_chunks_from_net(stcb,
7348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.deleted_primary);
7358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
7368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_delete_prim_timer(stcb->sctp_ep, stcb,
7378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.deleted_primary);
7388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
7398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
7418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
7438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
7448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
7458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* return 0 means we want you to proceed with the abort
7468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * non-zero means no abort processing
7478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	*/
7488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctpasochead *head;
7498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
7518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* generate a new vtag and send init */
7528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_REMOVE(stcb, sctp_asocs);
7530ac02f34d6041cd0018437596a5a9a94685e6919tuexen		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
7548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
7558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* put it in the bucket in the vtag hash of assoc's for the system */
7568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
7578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
7588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (1);
7598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
7618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* treat like a case where the cookie expired i.e.:
7628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		* - dump current cookie.
7638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		* - generate a new vtag.
7648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		* - resend init.
7658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*/
7668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* generate a new vtag and send init */
7678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_REMOVE(stcb, sctp_asocs);
7688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.state &= ~SCTP_STATE_COOKIE_ECHOED;
7698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.state |= SCTP_STATE_COOKIE_WAIT;
7708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_all_cookie_timers(stcb);
7718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_toss_old_cookies(stcb, &stcb->asoc);
7728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport,  1);
7738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
7748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* put it in the bucket in the vtag hash of assoc's for the system */
7758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
7768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
7778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (1);
7788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
7798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
7808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
7818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
7838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_nat_missing_state(struct sctp_tcb *stcb,
7848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      struct sctp_nets *net)
7858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
786fb3816eaffe5878bb1286adb120fd160da178a05t	/* return 0 means we want you to proceed with the abort
787fb3816eaffe5878bb1286adb120fd160da178a05t	 * non-zero means no abort processing
788fb3816eaffe5878bb1286adb120fd160da178a05t	 */
789fb3816eaffe5878bb1286adb120fd160da178a05t	if (stcb->asoc.auth_supported == 0) {
790fb3816eaffe5878bb1286adb120fd160da178a05t		SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_nat_missing_state: Peer does not support AUTH, cannot send an asconf\n");
791fb3816eaffe5878bb1286adb120fd160da178a05t		return (0);
792fb3816eaffe5878bb1286adb120fd160da178a05t	}
793fb3816eaffe5878bb1286adb120fd160da178a05t	sctp_asconf_send_nat_state_update(stcb, net);
794fb3816eaffe5878bb1286adb120fd160da178a05t	return (1);
7958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
7968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
7988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
79947674b651417d493ff4e0318113fd7beeef119dbtuexensctp_handle_abort(struct sctp_abort_chunk *abort,
8008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net)
8018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
8020612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
8038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
8048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
8058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t len;
80647674b651417d493ff4e0318113fd7beeef119dbtuexen	uint16_t error;
80747674b651417d493ff4e0318113fd7beeef119dbtuexen
8088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: handling ABORT\n");
8098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL)
8108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
8118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
81247674b651417d493ff4e0318113fd7beeef119dbtuexen	len = ntohs(abort->ch.chunk_length);
8138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (len > sizeof (struct sctp_chunkhdr)) {
8148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Need to check the cause codes for our
8158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * two magic nat aborts which don't kill the assoc
8168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * necessarily.
8178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
8188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_missing_nat_state *natc;
81932a191a90b5c914a02047389c5b3197e08fc9841tuexen
82047674b651417d493ff4e0318113fd7beeef119dbtuexen		natc = (struct sctp_missing_nat_state *)(abort + 1);
82147674b651417d493ff4e0318113fd7beeef119dbtuexen		error = ntohs(natc->cause);
82247674b651417d493ff4e0318113fd7beeef119dbtuexen		if (error == SCTP_CAUSE_NAT_COLLIDING_STATE) {
8238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
82447674b651417d493ff4e0318113fd7beeef119dbtuexen			                           abort->ch.chunk_flags);
8258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_nat_colliding_state(stcb)) {
8268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return;
8278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
82847674b651417d493ff4e0318113fd7beeef119dbtuexen		} else if (error == SCTP_CAUSE_NAT_MISSING_STATE) {
8298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
83047674b651417d493ff4e0318113fd7beeef119dbtuexen			                           abort->ch.chunk_flags);
8318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_nat_missing_state(stcb, net)) {
8328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return;
8338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
8348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
83547674b651417d493ff4e0318113fd7beeef119dbtuexen	} else {
83647674b651417d493ff4e0318113fd7beeef119dbtuexen		error = 0;
8378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
8388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* stop any receive timers */
8398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_6);
8408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* notify user of the abort and clean up... */
84147674b651417d493ff4e0318113fd7beeef119dbtuexen	sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
8428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* free the tcb */
8438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR_COUNTER32(sctps_aborted);
8448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
8458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
8468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
8478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
8488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_ASOCLOG_OF_TSNS
8498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_print_out_track_log(stcb);
8508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
8510612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
8528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	so = SCTP_INP_SO(stcb->sctp_ep);
8538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_add_int(&stcb->asoc.refcnt, 1);
8548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_UNLOCK(stcb);
8558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_LOCK(so, 1);
8568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_LOCK(stcb);
8578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_subtract_int(&stcb->asoc.refcnt, 1);
8588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
8598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
8608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
8618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      SCTP_FROM_SCTP_INPUT+SCTP_LOC_6);
8620612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
8638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_UNLOCK(so, 1);
8648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
8658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: finished\n");
8668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
8678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
8688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
8698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_start_net_timers(struct sctp_tcb *stcb)
8708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
8718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t cnt_hb_sent;
8728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *net;
8738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
8748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cnt_hb_sent = 0;
8758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
8768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* For each network start:
8778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * 1) A pmtu timer.
8788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * 2) A HB timer
8798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * 3) If the dest in unconfirmed send
8808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 *    a hb as well if under max_hb_burst have
8818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 *    been sent.
8828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
8838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
8848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
8858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
886b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		    (cnt_hb_sent < SCTP_BASE_SYSCTL(sctp_hb_maxburst))) {
8878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
8888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			cnt_hb_sent++;
8898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
8908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
8918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (cnt_hb_sent) {
89232a191a90b5c914a02047389c5b3197e08fc9841tuexen		sctp_chunk_output(stcb->sctp_ep, stcb,
89332a191a90b5c914a02047389c5b3197e08fc9841tuexen				  SCTP_OUTPUT_FROM_COOKIE_ACK,
8948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				  SCTP_SO_NOT_LOCKED);
8958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
8968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
8978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
8988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
8998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
9008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
9018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_flag)
9028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
9038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
9048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int some_on_streamwheel;
9050612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
9068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
9078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
9088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
9098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
9108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_shutdown: handling SHUTDOWN\n");
9118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL)
9128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
9138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
9148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
9158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
9168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
9178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_shutdown_chunk)) {
9198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Shutdown NOT the expected size */
9208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
9218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
9220ac02f34d6041cd0018437596a5a9a94685e6919tuexen		sctp_update_acked(stcb, cp, abort_flag);
9238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (*abort_flag) {
9248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
9258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
9268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->control_pdapi) {
9288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* With a normal shutdown
9298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * we assume the end of last record.
9308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
9318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_READ_LOCK(stcb->sctp_ep);
9328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi->end_added = 1;
9338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi->pdapi_aborted = 1;
9348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi = NULL;
9358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
9360612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
9378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		so = SCTP_INP_SO(stcb->sctp_ep);
9388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
9398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
9408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
9418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
9428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
9438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
9448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* assoc was freed while we were unlocked */
9458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
9468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
9478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
9488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
9498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
9500612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
9518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
9528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
9538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* goto SHUTDOWN_RECEIVED state to block new requests */
9558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->sctp_socket) {
9568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
9578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
9588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
9598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_RECEIVED);
9608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
9618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* notify upper layer that peer has initiated a shutdown */
9628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_ulp_notify(SCTP_NOTIFY_PEER_SHUTDOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
9638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
9648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* reset time */
9658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
9668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
9678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
9698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
9708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * stop the shutdown timer, since we WILL move to
9718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * SHUTDOWN-ACK-SENT.
9728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
9738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_8);
9748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Now is there unsent data on a stream somewhere? */
9768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
9778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
9788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!TAILQ_EMPTY(&asoc->send_queue) ||
9798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    !TAILQ_EMPTY(&asoc->sent_queue) ||
9808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    some_on_streamwheel) {
9818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* By returning we will push more data out */
9828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
9838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
9848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* no outstanding data to send, so move on... */
9858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* send SHUTDOWN-ACK */
9868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* move to SHUTDOWN-ACK-SENT state */
9878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
9888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
9898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
9908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
9918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
9928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
9938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_timers_for_shutdown(stcb);
9947988ea8f0c067cf3757e798b473b1ae4d34b6dfdt		sctp_send_shutdown_ack(stcb, net);
9958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
9968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 stcb, net);
9978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
9988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
9998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
10008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
10010ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
10028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                         struct sctp_tcb *stcb,
10038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                         struct sctp_nets *net)
10048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
10058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
10060612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
10078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
10088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
10098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	so = SCTP_INP_SO(stcb->sctp_ep);
10108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
10118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
10128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n");
10138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL)
10148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
10158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
10168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
10178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process according to association state */
10188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
10198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
10208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* unexpected SHUTDOWN-ACK... do OOTB handling... */
10218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_shutdown_complete(stcb, net, 1);
10228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
10238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
10248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
10258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
10268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
10278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* unexpected SHUTDOWN-ACK... so ignore... */
10288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
10298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
10308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
10318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->control_pdapi) {
10328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* With a normal shutdown
10338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * we assume the end of last record.
10348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
10358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_READ_LOCK(stcb->sctp_ep);
10368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi->end_added = 1;
10378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi->pdapi_aborted = 1;
10388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->control_pdapi = NULL;
10398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
10400612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
10418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
10428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
10438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
10448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
10458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
10468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
10478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* assoc was freed while we were unlocked */
10488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
10498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
10508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
10518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
10528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
10530612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
10548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
10558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
10568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
105797e4568a3ba270aaad30d8713c38235a1d8fa518t#ifdef INVARIANTS
10588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!TAILQ_EMPTY(&asoc->send_queue) ||
10598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    !TAILQ_EMPTY(&asoc->sent_queue) ||
10608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
106197e4568a3ba270aaad30d8713c38235a1d8fa518t		panic("Queues are not empty when handling SHUTDOWN-ACK");
10628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
106397e4568a3ba270aaad30d8713c38235a1d8fa518t#endif
10648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* stop the timer */
10658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_9);
10668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* send SHUTDOWN-COMPLETE */
10678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_send_shutdown_complete(stcb, net, 0);
10688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* notify upper layer protocol */
10698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->sctp_socket) {
10708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
10718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
107223273859c39742f09cc5ec7c9bf32ff225661e82tuexen			stcb->sctp_socket->so_snd.sb_cc = 0;
10738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
1074e5acde438f3c0c70f50751fa4c6a8209650f67cbtuexen		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
10758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
10768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
10778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* free the TCB but first save off the ep */
10780612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
10798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_add_int(&stcb->asoc.refcnt, 1);
10808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_UNLOCK(stcb);
10818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_LOCK(so, 1);
10828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_LOCK(stcb);
10838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_subtract_int(&stcb->asoc.refcnt, 1);
10848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
10858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
10868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      SCTP_FROM_SCTP_INPUT+SCTP_LOC_10);
10870612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
10888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_UNLOCK(so, 1);
10898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
10908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
10918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
10928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
10938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Skip past the param header and then we will find the chunk that caused the
10948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * problem. There are two possiblities ASCONF or FWD-TSN other than that and
10958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * our peer must be broken.
10968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
10978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
10988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr,
10998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_nets *net)
11008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
11018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_chunkhdr *chk;
11028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
11038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk = (struct sctp_chunkhdr *)((caddr_t)phdr + sizeof(*phdr));
11048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (chk->chunk_type) {
11058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ASCONF_ACK:
11068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ASCONF:
11078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_asconf_cleanup(stcb, net);
11088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_FORWARD_CUM_TSN:
1110a8657c4fc04fb9cc82100f648810d51ec6ab155at		stcb->asoc.prsctp_supported = 0;
11118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
11138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
11148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"Peer does not support chunk type %d(%x)??\n",
11158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			chk->chunk_type, (uint32_t) chk->chunk_type);
11168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
11188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
11198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
11208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
11218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Skip past the param header and then we will find the param that caused the
11228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * problem.  There are a number of param's in a ASCONF OR the prsctp param
11238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * these will turn of specific features.
1124fb3816eaffe5878bb1286adb120fd160da178a05t * XXX: Is this the right thing to do?
11258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
11268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
11278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
11288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
11298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_paramhdr *pbad;
11308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
11318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	pbad = phdr + 1;
11328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (ntohs(pbad->param_type)) {
11338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* pr-sctp draft */
11348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_PRSCTP_SUPPORTED:
1135a8657c4fc04fb9cc82100f648810d51ec6ab155at		stcb->asoc.prsctp_supported = 0;
11368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SUPPORTED_CHUNK_EXT:
11388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* draft-ietf-tsvwg-addip-sctp */
11408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_HAS_NAT_SUPPORT:
11418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	        stcb->asoc.peer_supports_nat = 0;
11428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	        break;
11438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ADD_IP_ADDRESS:
11448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_DEL_IP_ADDRESS:
11458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SET_PRIM_ADDR:
1146fb3816eaffe5878bb1286adb120fd160da178a05t		stcb->asoc.asconf_supported = 0;
11478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SUCCESS_REPORT:
11498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ERROR_CAUSE_IND:
11508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "Huh, the peer does not support success? or error cause?\n");
11518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
11528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"Turning off ASCONF to this strange peer\n");
1153fb3816eaffe5878bb1286adb120fd160da178a05t		stcb->asoc.asconf_supported = 0;
11548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
11568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
11578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"Peer does not support param type %d(%x)??\n",
11588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			pbad->param_type, (uint32_t) pbad->param_type);
11598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
11608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
11618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
11628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
11638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
11648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_error(struct sctp_chunkhdr *ch,
11658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net)
11668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
11678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int chklen;
11688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_paramhdr *phdr;
116947674b651417d493ff4e0318113fd7beeef119dbtuexen	uint16_t error, error_type;
11708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t error_len;
11718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
11728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int adjust;
11730612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
11748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
11758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
11768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
11778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* parse through all of the errors and process */
11788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
11798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	phdr = (struct sctp_paramhdr *)((caddr_t)ch +
11808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sizeof(struct sctp_chunkhdr));
11818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chklen = ntohs(ch->chunk_length) - sizeof(struct sctp_chunkhdr);
118247674b651417d493ff4e0318113fd7beeef119dbtuexen	error = 0;
11838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	while ((size_t)chklen >= sizeof(struct sctp_paramhdr)) {
11848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Process an Error Cause */
11858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		error_type = ntohs(phdr->param_type);
11868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		error_len = ntohs(phdr->param_length);
11878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((error_len > chklen) || (error_len == 0)) {
11888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* invalid param length for this param */
11898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT1, "Bogus length in error param- chunk left:%d errorlen:%d\n",
11908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				chklen, error_len);
11918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (0);
11928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
119347674b651417d493ff4e0318113fd7beeef119dbtuexen		if (error == 0) {
119447674b651417d493ff4e0318113fd7beeef119dbtuexen			/* report the first error cause */
119547674b651417d493ff4e0318113fd7beeef119dbtuexen			error = error_type;
119647674b651417d493ff4e0318113fd7beeef119dbtuexen		}
11978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		switch (error_type) {
11988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_INVALID_STREAM:
11998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_MISSING_PARAM:
12008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_INVALID_PARAM:
12018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_NO_USER_DATA:
12028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT1, "Software error we got a %d back? We have a bug :/ (or do they?)\n",
12038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				error_type);
12048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_NAT_COLLIDING_STATE:
12068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		        SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
12078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ch->chunk_flags);
12088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_nat_colliding_state(stcb)) {
1209b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			  return (0);
12108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
12118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_NAT_MISSING_STATE:
12138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
12148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			                           ch->chunk_flags);
12158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_nat_missing_state(stcb, net)) {
1216b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			  return (0);
12178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
12188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_STALE_COOKIE:
12208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
12218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We only act if we have echoed a cookie and are
12228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * waiting.
12238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
12248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
12258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int *p;
12268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
12278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				p = (int *)((caddr_t)phdr + sizeof(*phdr));
12288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Save the time doubled */
12298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_preserve_req = ntohl(*p) << 1;
12308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->stale_cookie_count++;
12318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (asoc->stale_cookie_count >
12328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    asoc->max_init_times) {
123347674b651417d493ff4e0318113fd7beeef119dbtuexen					sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
12348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* now free the asoc */
12350612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
12368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					so = SCTP_INP_SO(stcb->sctp_ep);
12378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_add_int(&stcb->asoc.refcnt, 1);
12388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(stcb);
12398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_LOCK(so, 1);
12408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_LOCK(stcb);
12418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_subtract_int(&stcb->asoc.refcnt, 1);
12428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
12438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
12448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							      SCTP_FROM_SCTP_INPUT+SCTP_LOC_11);
12450612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
12468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_UNLOCK(so, 1);
12478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
12488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (-1);
12498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
12508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* blast back to INIT state */
12518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_toss_old_cookies(stcb, &stcb->asoc);
12528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->state &= ~SCTP_STATE_COOKIE_ECHOED;
12538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->state |= SCTP_STATE_COOKIE_WAIT;
12548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_stop_all_cookie_timers(stcb);
12558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
12568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
12578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_UNRESOLVABLE_ADDR:
12598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
12608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Nothing we can do here, we don't do hostname
12618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * addresses so if the peer does not like my IPv6
12628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * (or IPv4 for that matter) it does not matter. If
12638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * they don't support that type of address, they can
12648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * NOT possibly get that packet type... i.e. with no
12658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * IPv6 you can't recieve a IPv6 packet. so we can
12668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * safely ignore this one. If we ever added support
12678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * for HOSTNAME Addresses, then we would need to do
12688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * something here.
12698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
12708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_UNRECOG_CHUNK:
12728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_process_unrecog_chunk(stcb, phdr, net);
12738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_UNRECOG_PARAM:
12758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_process_unrecog_param(stcb, phdr);
12768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_COOKIE_IN_SHUTDOWN:
12788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
12798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We ignore this since the timer will drive out a
12808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * new cookie anyway and there timer will drive us
12818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * to send a SHUTDOWN_COMPLETE. We can't send one
12828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * here since we don't have their tag.
12838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
12848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_DELETING_LAST_ADDR:
12868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_RESOURCE_SHORTAGE:
12878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_DELETING_SRC_ADDR:
12888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
12898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We should NOT get these here, but in a
12908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * ASCONF-ACK.
12918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
12928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT2, "Peer sends ASCONF errors in a Operational Error?<%d>?\n",
12938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				error_type);
12948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
12958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_CAUSE_OUT_OF_RESC:
12968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
12978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * And what, pray tell do we do with the fact that
12988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the peer is out of resources? Not really sure we
12998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * could do anything but abort. I suspect this
13008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * should have came WITH an abort instead of in a
13018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * OP-ERROR.
13028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
13038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
13048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		default:
13058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_handle_error: unknown error type = 0x%xh\n",
13068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				error_type);
13078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
13088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
13098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		adjust = SCTP_SIZE32(error_len);
13108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chklen -= adjust;
13118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		phdr = (struct sctp_paramhdr *)((caddr_t)phdr + adjust);
13128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
131347674b651417d493ff4e0318113fd7beeef119dbtuexen	sctp_ulp_notify(SCTP_NOTIFY_REMOTE_ERROR, stcb, error, ch, SCTP_SO_NOT_LOCKED);
13148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
13158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
13168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
13178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
1318e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexensctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
1319e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen                     struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
132051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                     struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
132151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                     struct sctp_nets *net, int *abort_no_unlock,
132251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
132351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                     uint8_t use_mflowid, uint32_t mflowid,
132451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
132551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                     uint32_t vrf_id)
13268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
13278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init_ack *init_ack;
13288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *op_err;
13298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
13308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
13318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_init_ack: handling INIT-ACK\n");
13328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
13338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL) {
13348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
13358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"sctp_handle_init_ack: TCB is null\n");
13368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
13388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
13398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Invalid length */
13408f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1341e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1342e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
134351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
134451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
134551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
134651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
13478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
13488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
13508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init_ack = &cp->init;
13518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* validate parameters */
13528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_ack->initiate_tag == 0) {
13538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send an abort */
13548f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1355e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1356e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
135751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
135851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
135951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
136051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
13618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
13628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
13648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
13658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send an abort */
13668f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1367e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1368e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
136951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
137051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
137151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
137251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
13738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
13748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
13768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_ack->num_inbound_streams == 0) {
13778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send an abort */
13788f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1379e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1380e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
138151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
138251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
138351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
138451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
13858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
13868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
13888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_ack->num_outbound_streams == 0) {
13898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* protocol error... send an abort */
13908f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1391e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1392e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
139351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
139451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
139551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
139651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, net->port);
13978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*abort_no_unlock = 1;
13988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
13998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
14008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process according to association state... */
14018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (stcb->asoc.state & SCTP_STATE_MASK) {
14028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_COOKIE_WAIT:
14038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* this is the expected state for this chunk */
14048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* process the INIT-ACK parameters */
14058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.primary_destination->dest_state &
14068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    SCTP_ADDR_UNCONFIRMED) {
14078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
14088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * The primary is where we sent the INIT, we can
14098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * always consider it confirmed when the INIT-ACK is
14108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * returned. Do this before we load addresses
14118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * though.
14128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
14138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.primary_destination->dest_state &=
14148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    ~SCTP_ADDR_UNCONFIRMED;
14158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
14168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED);
14178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
1418e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		if (sctp_process_init_ack(m, iphlen, offset, src, dst, sh, cp, stcb,
141951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                          net, abort_no_unlock,
142051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
142151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                          use_mflowid, mflowid,
142251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
142351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                          vrf_id) < 0) {
14248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* error in parsing parameters */
14258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (-1);
14268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
14278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* update our state */
14288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "moving to COOKIE-ECHOED state\n");
14298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_ECHOED);
14308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
14318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* reset the RTO calc */
14328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
14338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
14348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       stcb->asoc.overall_error_count,
14358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       0,
14368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       SCTP_FROM_SCTP_INPUT,
14378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       __LINE__);
14388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
14398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.overall_error_count = 0;
14408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
14418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
14428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * collapse the init timer back in case of a exponential
14438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * backoff
14448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
14458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, stcb->sctp_ep,
14468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    stcb, net);
14478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
14488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * the send at the end of the inbound data processing will
14498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * cause the cookie to be sent
14508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
14518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
14528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_SHUTDOWN_SENT:
14538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* incorrect state... discard */
14548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
14558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_COOKIE_ECHOED:
14568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* incorrect state... discard */
14578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
14588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_OPEN:
14598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* incorrect state... discard */
14608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
14618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_EMPTY:
14628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_STATE_INUSE:
14638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
14648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* incorrect state... discard */
14658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (-1);
14668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
14678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
14688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT1, "Leaving handle-init-ack end\n");
14698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
14708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
14718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
14728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic struct sctp_tcb *
14738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
1474e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    struct sockaddr *src, struct sockaddr *dst,
14758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
14768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_inpcb *inp, struct sctp_nets **netp,
14778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sockaddr *init_src, int *notification,
14788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
147951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
148051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint8_t use_mflowid, uint32_t mflowid,
148151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
14828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    uint32_t vrf_id, uint16_t port);
14838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
14848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
14858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
14868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * handle a state cookie for an existing association m: input packet mbuf
14878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * chain-- assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a
14888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * "split" mbuf and the cookie signature does not exist offset: offset into
14898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * mbuf to the cookie-echo chunk
14908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
14918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic struct sctp_tcb *
14928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
1493e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    struct sockaddr *src, struct sockaddr *dst,
14948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
14958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp,
14960ac02f34d6041cd0018437596a5a9a94685e6919tuexen    struct sockaddr *init_src, int *notification,
149751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
149851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
149951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint8_t use_mflowid, uint32_t mflowid,
150051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
150151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint32_t vrf_id, uint16_t port)
15028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
15038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
15048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init_chunk *init_cp, init_buf;
15058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init_ack_chunk *initack_cp, initack_buf;
15068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *net;
15078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *op_err;
15088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int init_offset, initack_offset, i;
15098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int retval;
1510b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	int spec_flag = 0;
15118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t how_indx;
151220d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS)
151320d5d287bff2075897105f85287230d55bdfa420t	int j;
151420d5d287bff2075897105f85287230d55bdfa420t#endif
151532a191a90b5c914a02047389c5b3197e08fc9841tuexen
15168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	net = *netp;
15178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* I know that the TCB is non-NULL from the caller */
15188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
15198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	for (how_indx = 0; how_indx  < sizeof(asoc->cookie_how); how_indx++) {
15208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->cookie_how[how_indx] == 0)
15218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
15228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (how_indx < sizeof(asoc->cookie_how)) {
15248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->cookie_how[how_indx] = 1;
15258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
15278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* SHUTDOWN came in after sending INIT-ACK */
15288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
15298f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
1530e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
153151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
153251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                   use_mflowid, mflowid,
153351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
153451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                   vrf_id, net->port);
15358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
15368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 2;
15378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
15388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
15408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * find and validate the INIT chunk in the cookie (peer's info) the
15418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * INIT should start after the cookie-echo header struct (chunk
15428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * header, state cookie header struct)
15438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
15448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init_offset = offset += sizeof(struct sctp_cookie_echo_chunk);
15458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
15468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init_cp = (struct sctp_init_chunk *)
15478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
15488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      (uint8_t *) & init_buf);
15498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_cp == NULL) {
15508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* could not pull a INIT chunk in cookie */
15518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
15528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_cp->ch.chunk_type != SCTP_INITIATION) {
15548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
15558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
15578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * find and validate the INIT-ACK chunk in the cookie (my info) the
15588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * INIT-ACK follows the INIT chunk
15598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
1560b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
15618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	initack_cp = (struct sctp_init_ack_chunk *)
15628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
15638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      (uint8_t *) & initack_buf);
15648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (initack_cp == NULL) {
15658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* could not pull INIT-ACK chunk in cookie */
15668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
15678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
15698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
15708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
15718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
15728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag)) {
15738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
15748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * case D in Section 5.2.4 Table 2: MMAA process accordingly
15758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * to get into the OPEN state
15768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
15778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
15788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*-
15798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Opps, this means that we somehow generated two vtag's
15808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the same. I.e. we did:
15818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *  Us               Peer
15828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *   <---INIT(tag=a)------
15838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *   ----INIT-ACK(tag=t)-->
15848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *   ----INIT(tag=t)------> *1
15858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *   <---INIT-ACK(tag=a)---
15868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen                         *   <----CE(tag=t)------------- *2
15878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 *
15888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * At point *1 we should be generating a different
15898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * tag t'. Which means we would throw away the CE and send
15908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * ours instead. Basically this is case C (throw away side).
15918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
15928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
15938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 17;
15948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
15958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
15968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
1597e2828360ea9cf8951730d46f5c14626c9425cb30t		switch (SCTP_GET_STATE(asoc)) {
15988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			case SCTP_STATE_COOKIE_WAIT:
15998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			case SCTP_STATE_COOKIE_ECHOED:
16008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
16018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * INIT was sent but got a COOKIE_ECHO with the
16028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * correct tags... just accept it...but we must
16038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * process the init so that we can make sure we
16048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * have the right seq no's.
16058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
16068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* First we must process the INIT !! */
16070ac02f34d6041cd0018437596a5a9a94685e6919tuexen				retval = sctp_process_init(init_cp, stcb);
16088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (retval < 0) {
16098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (how_indx < sizeof(asoc->cookie_how))
16108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						asoc->cookie_how[how_indx] = 3;
16118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
16128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
16138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* we have already processed the INIT so no problem */
16148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb,
16158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_12);
16168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_13);
16178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* update current state */
16188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
16198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
16208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				else
16218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
16228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
16238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
16248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
16258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
16268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							 stcb->sctp_ep, stcb, asoc->primary_destination);
16278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
16288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR_GAUGE32(sctps_currestab);
16298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_stop_all_cookie_timers(stcb);
16308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
16318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
16328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (inp->sctp_socket->so_qlimit == 0)
16338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					) {
16340612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
16358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					struct socket *so;
16368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
16378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*
16388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * Here is where collision would go if we
16398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * did a connect() and instead got a
16408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * init/init-ack/cookie done before the
16418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * init-ack came back..
16428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
16438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->sctp_ep->sctp_flags |=
16448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_PCB_FLAGS_CONNECTED;
16450612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
16468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					so = SCTP_INP_SO(stcb->sctp_ep);
16478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_add_int(&stcb->asoc.refcnt, 1);
16488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(stcb);
16498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_LOCK(so, 1);
16508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_LOCK(stcb);
16518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_add_int(&stcb->asoc.refcnt, -1);
16528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
16538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_SOCKET_UNLOCK(so, 1);
1654e2828360ea9cf8951730d46f5c14626c9425cb30t						return (NULL);
16558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
16568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
16578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					soisconnected(stcb->sctp_socket);
16580612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
16598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_UNLOCK(so, 1);
16608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
16618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
16628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* notify upper layer */
16638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*notification = SCTP_NOTIFY_ASSOC_UP;
16648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
16658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * since we did not send a HB make sure we
16668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * don't double things
16678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
16688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				net->hb_responded = 1;
16698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				net->RTO = sctp_calculate_rto(stcb, asoc, net,
167032a191a90b5c914a02047389c5b3197e08fc9841tuexen							      &cookie->time_entered,
167132a191a90b5c914a02047389c5b3197e08fc9841tuexen							      sctp_align_unsafe_makecopy,
16728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							      SCTP_RTT_FROM_NON_DATA);
16738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
16748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb->asoc.sctp_autoclose_ticks &&
16758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))) {
16768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
16778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							 inp, stcb, NULL);
16788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
16798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
16808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			default:
16818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
16828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * we're in the OPEN state (or beyond), so
16838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * peer must have simply lost the COOKIE-ACK
16848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
16858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
16868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}	/* end switch */
16878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_all_cookie_timers(stcb);
16888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
16898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * We ignore the return code here.. not sure if we should
16908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * somehow abort.. but we do have an existing asoc. This
16918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * really should not fail.
16928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
16930ac02f34d6041cd0018437596a5a9a94685e6919tuexen		if (sctp_load_addresses_from_init(stcb, m,
16948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						  init_offset + sizeof(struct sctp_init_chunk),
1695e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						  initack_offset, src, dst, init_src)) {
16968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
16978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 4;
16988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
16998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
17008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* respond with a COOKIE-ACK */
17018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_toss_old_cookies(stcb, asoc);
17028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_cookie_ack(stcb);
17038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
17048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 5;
17058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (stcb);
17068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
170732a191a90b5c914a02047389c5b3197e08fc9841tuexen
17088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
17098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag &&
17108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->tie_tag_my_vtag == 0 &&
17118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->tie_tag_peer_vtag == 0) {
17128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
17138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * case C in Section 5.2.4 Table 2: XMOO silently discard
17148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
17158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
17168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 6;
17178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
17188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
17198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* If nat support, and the below and stcb is established,
17208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * send back a ABORT(colliding state) if we are established.
17218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
17228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN)  &&
17238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (asoc->peer_supports_nat) &&
17248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
17258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
17268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	     (asoc->peer_vtag == 0)))) {
17278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Special case - Peer's support nat. We may have
17288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * two init's that we gave out the same tag on since
17298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * one was not established.. i.e. we get INIT from host-1
17308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * behind the nat and we respond tag-a, we get a INIT from
17318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * host-2 behind the nat and we get tag-a again. Then we
17328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * bring up host-1 (or 2's) assoc, Then comes the cookie
17338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * from hsot-2 (or 1). Now we have colliding state. We must
17348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * send an abort here with colliding state indication.
17358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
17368f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
1737e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_send_abort(m, iphlen,  src, dst, sh, 0, op_err,
173851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
173951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                use_mflowid, mflowid,
174051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
174151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                vrf_id, port);
17428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
17438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
17448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
17458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
17468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	     (asoc->peer_vtag == 0))) {
17478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
17488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * case B in Section 5.2.4 Table 2: MXAA or MOAA my info
17498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * should be ok, re-accept peer info
17508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
17518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
17528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Extension of case C.
17538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * If we hit this, then the random number
17548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * generator returned the same vtag when we
17558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * first sent our INIT-ACK and when we later sent
17568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * our INIT. The side with the seq numbers that are
17578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * different will be the one that normnally would
17588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * have hit case C. This in effect "extends" our vtags
17598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * in this collision case to be 64 bits. The same collision
17608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * could occur aka you get both vtag and seq number the
17618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * same twice in a row.. but is much less likely. If it
17628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * did happen then we would proceed through and bring
17638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * up the assoc.. we may end up with the wrong stream
17648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * setup however.. which would be bad.. but there is
17658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * no way to tell.. until we send on a stream that does
17668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * not exist :-)
17678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
17688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
17698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 7;
17708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1771b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			return (NULL);
17728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
17738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
17748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 8;
17758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_14);
17768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_all_cookie_timers(stcb);
17778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
17788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * since we did not send a HB make sure we don't double
17798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * things
17808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
17818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->hb_responded = 1;
17828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.sctp_autoclose_ticks &&
17838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
17848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
17858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 NULL);
17868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
17878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
17888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
17898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
17908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
17918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Ok the peer probably discarded our
17928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * data (if we echoed a cookie+data). So anything
17938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * on the sent_queue should be marked for
17948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * retransmit, we may not get something to
17958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * kick us so it COULD still take a timeout
17968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * to move these.. but it can't hurt to mark them.
17978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
17988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_tmit_chunk *chk;
17998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		        TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
18008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chk->sent < SCTP_DATAGRAM_RESEND) {
18018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					chk->sent = SCTP_DATAGRAM_RESEND;
18028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_flight_size_decrease(chk);
18038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_total_flight_decrease(stcb, chk);
18048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
18058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					spec_flag++;
18068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
18078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
18088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
18098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* process the INIT info (peer's info) */
18110ac02f34d6041cd0018437596a5a9a94685e6919tuexen		retval = sctp_process_init(init_cp, stcb);
18128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (retval < 0) {
18138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
18148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 9;
18158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
18168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18170ac02f34d6041cd0018437596a5a9a94685e6919tuexen		if (sctp_load_addresses_from_init(stcb, m,
18188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						  init_offset + sizeof(struct sctp_init_chunk),
1819e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						  initack_offset, src, dst, init_src)) {
18208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
18218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 10;
18228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
18238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((asoc->state & SCTP_STATE_COOKIE_WAIT) ||
18258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (asoc->state & SCTP_STATE_COOKIE_ECHOED)) {
18268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*notification = SCTP_NOTIFY_ASSOC_UP;
18278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
18288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
18298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
18308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (inp->sctp_socket->so_qlimit == 0)) {
18310612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
18328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct socket *so;
18338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
18348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->sctp_ep->sctp_flags |=
18358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_PCB_FLAGS_CONNECTED;
18360612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
18378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				so = SCTP_INP_SO(stcb->sctp_ep);
18388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				atomic_add_int(&stcb->asoc.refcnt, 1);
18398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(stcb);
18408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_SOCKET_LOCK(so, 1);
18418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_LOCK(stcb);
18428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				atomic_add_int(&stcb->asoc.refcnt, -1);
18438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
18448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_UNLOCK(so, 1);
18458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
18468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
18478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
18488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				soisconnected(stcb->sctp_socket);
18490612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
18508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_SOCKET_UNLOCK(so, 1);
18518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
18528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
18538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
18548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
18558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			else
18568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
18578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_GAUGE32(sctps_currestab);
18588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
18598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_COUNTER32(sctps_restartestab);
18608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
18618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
18628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
18648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
18658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
18668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb->sctp_ep, stcb, asoc->primary_destination);
18678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_all_cookie_timers(stcb);
18698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_toss_old_cookies(stcb, asoc);
18708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_cookie_ack(stcb);
18718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (spec_flag) {
18728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* only if we have retrans set do we do this. What
18738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * this call does is get only the COOKIE-ACK out
18748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * and then when we return the normal call to
18758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * sctp_chunk_output will get the retrans out
18768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * behind this.
18778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
18788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_chunk_output(inp,stcb, SCTP_OUTPUT_FROM_COOKIE_ACK, SCTP_SO_NOT_LOCKED);
18798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
18808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
18818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 11;
18828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
18838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (stcb);
18848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
18858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
18868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	     ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) &&
18878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->tie_tag_my_vtag == asoc->my_vtag_nonce &&
18888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
18898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->tie_tag_peer_vtag != 0) {
18908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctpasochead *head;
1891ea4ad6b0591b5fcab0af327804d0ac0190694b57t#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1892ea4ad6b0591b5fcab0af327804d0ac0190694b57t		struct socket *so;
1893ea4ad6b0591b5fcab0af327804d0ac0190694b57t#endif
1894ea4ad6b0591b5fcab0af327804d0ac0190694b57t
18958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->peer_supports_nat) {
1896b6a8c974796d76c59ef64a7555e446c9cd171877t			/* This is a gross gross hack.
1897b6a8c974796d76c59ef64a7555e446c9cd171877t			 * Just call the cookie_new code since we
1898b6a8c974796d76c59ef64a7555e446c9cd171877t			 * are allowing a duplicate association.
1899b6a8c974796d76c59ef64a7555e446c9cd171877t			 * I hope this works...
1900b6a8c974796d76c59ef64a7555e446c9cd171877t			 */
1901b6a8c974796d76c59ef64a7555e446c9cd171877t			return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
1902b6a8c974796d76c59ef64a7555e446c9cd171877t			                                sh, cookie, cookie_len,
1903b6a8c974796d76c59ef64a7555e446c9cd171877t			                                inp, netp, init_src,notification,
1904b6a8c974796d76c59ef64a7555e446c9cd171877t			                                auth_skipped, auth_offset, auth_len,
190551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
1906b6a8c974796d76c59ef64a7555e446c9cd171877t			                                use_mflowid, mflowid,
190751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
1908b6a8c974796d76c59ef64a7555e446c9cd171877t			                                vrf_id, port));
19098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
19118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * case A in Section 5.2.4 Table 2: XXMM (peer restarted)
19128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
19138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* temp code */
19148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
19158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 12;
19168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_15);
19178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
19188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* notify upper layer */
19208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*notification = SCTP_NOTIFY_ASSOC_RESTART;
19218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
19228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((SCTP_GET_STATE(asoc) != SCTP_STATE_OPEN) &&
19238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
19248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
19258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_GAUGE32(sctps_currestab);
19268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
19288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_GAUGE32(sctps_restartestab);
19298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
19308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR_GAUGE32(sctps_collisionestab);
19318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
19338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
19348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
19358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb->sctp_ep, stcb, asoc->primary_destination);
19368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
19388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* move to OPEN state, if not in SHUTDOWN_SENT */
19398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
19408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->pre_open_streams =
19428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ntohs(initack_cp->init.num_outbound_streams);
19438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
19448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
19458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
19468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
19488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->str_reset_seq_in = asoc->init_seq_number;
19508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->advanced_peer_ack_point = asoc->last_acked_seq;
19528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->mapping_array) {
19538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			memset(asoc->mapping_array, 0,
19548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       asoc->mapping_array_size);
19558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->nr_mapping_array) {
19578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			memset(asoc->nr_mapping_array, 0,
19588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    asoc->mapping_array_size);
19598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
1961ea4ad6b0591b5fcab0af327804d0ac0190694b57t#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1962ea4ad6b0591b5fcab0af327804d0ac0190694b57t		so = SCTP_INP_SO(stcb->sctp_ep);
1963ea4ad6b0591b5fcab0af327804d0ac0190694b57t		SCTP_SOCKET_LOCK(so, 1);
1964ea4ad6b0591b5fcab0af327804d0ac0190694b57t#endif
19658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_INFO_WLOCK();
19668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_WLOCK(stcb->sctp_ep);
19678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
19688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, -1);
19698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* send up all the data */
19708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_SEND_LOCK(stcb);
19718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
1972ea4ad6b0591b5fcab0af327804d0ac0190694b57t		sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
197360db5740d3bcc26fd4ebc19b6b0652506994fd14t		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
197460db5740d3bcc26fd4ebc19b6b0652506994fd14t			stcb->asoc.strmout[i].chunks_on_queues = 0;
197520d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS)
197620d5d287bff2075897105f85287230d55bdfa420t			for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
197720d5d287bff2075897105f85287230d55bdfa420t				asoc->strmout[i].abandoned_sent[j] = 0;
197820d5d287bff2075897105f85287230d55bdfa420t				asoc->strmout[i].abandoned_unsent[j] = 0;
197920d5d287bff2075897105f85287230d55bdfa420t			}
198020d5d287bff2075897105f85287230d55bdfa420t#else
198120d5d287bff2075897105f85287230d55bdfa420t			asoc->strmout[i].abandoned_sent[0] = 0;
198220d5d287bff2075897105f85287230d55bdfa420t			asoc->strmout[i].abandoned_unsent[0] = 0;
198320d5d287bff2075897105f85287230d55bdfa420t#endif
19848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.strmout[i].stream_no = i;
1985e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t			stcb->asoc.strmout[i].next_sequence_send = 0;
19868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.strmout[i].last_msg_incomplete = 0;
19878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
19888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* process the INIT-ACK info (my info) */
19898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
19908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
19918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
19928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* pull from vtag hash */
19938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_REMOVE(stcb, sctp_asocs);
19948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* re-insert to new vtag position */
19958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag,
19968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								    SCTP_BASE_INFO(hashasocmark))];
19978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
19988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * put it in the bucket in the vtag hash of assoc's for the
19998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * system
20008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
20018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
20028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_SEND_UNLOCK(stcb);
20048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_WUNLOCK(stcb->sctp_ep);
20058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_INP_INFO_WUNLOCK();
2006ea4ad6b0591b5fcab0af327804d0ac0190694b57t#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2007ea4ad6b0591b5fcab0af327804d0ac0190694b57t		SCTP_SOCKET_UNLOCK(so, 1);
2008ea4ad6b0591b5fcab0af327804d0ac0190694b57t#endif
200984c69be44d793ca2fffe2ff446114f81b80c96a5t		asoc->total_flight = 0;
201084c69be44d793ca2fffe2ff446114f81b80c96a5t		asoc->total_flight_count = 0;
201184c69be44d793ca2fffe2ff446114f81b80c96a5t		/* process the INIT info (peer's info) */
20120ac02f34d6041cd0018437596a5a9a94685e6919tuexen		retval = sctp_process_init(init_cp, stcb);
20138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (retval < 0) {
20148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
20158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 13;
20168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
20188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
20198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
20208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * since we did not send a HB make sure we don't double
20218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * things
20228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
20238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->hb_responded = 1;
20248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20250ac02f34d6041cd0018437596a5a9a94685e6919tuexen		if (sctp_load_addresses_from_init(stcb, m,
20268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						  init_offset + sizeof(struct sctp_init_chunk),
2027e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						  initack_offset, src, dst, init_src)) {
20288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (how_indx < sizeof(asoc->cookie_how))
20298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->cookie_how[how_indx] = 14;
20308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
20328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
20338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* respond with a COOKIE-ACK */
20348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_stop_all_cookie_timers(stcb);
20358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_toss_old_cookies(stcb, asoc);
20368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_cookie_ack(stcb);
20378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (how_indx < sizeof(asoc->cookie_how))
20388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->cookie_how[how_indx] = 15;
20398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (stcb);
20418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
20428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (how_indx < sizeof(asoc->cookie_how))
20438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->cookie_how[how_indx] = 16;
20448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* all other cases... */
20458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (NULL);
20468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
20478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
20508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * handle a state cookie for a new association m: input packet mbuf chain--
20518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a "split" mbuf
20528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * and the cookie signature does not exist offset: offset into mbuf to the
20538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * cookie-echo chunk length: length of the cookie chunk to: where the init
20548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * was from returns a new TCB
20558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
205651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexenstatic struct sctp_tcb *
20578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
2058e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    struct sockaddr *src, struct sockaddr *dst,
20598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
20608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_inpcb *inp, struct sctp_nets **netp,
20618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sockaddr *init_src, int *notification,
20628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
206351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
206451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint8_t use_mflowid, uint32_t mflowid,
206551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
20668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    uint32_t vrf_id, uint16_t port)
20678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
20688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tcb *stcb;
20698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init_chunk *init_cp, init_buf;
20708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_init_ack_chunk *initack_cp, initack_buf;
2071bfb1bf7e665a02b48026482bf33d05c83dfad73bt	union sctp_sockstore store;
20728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
20738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int init_offset, initack_offset, initack_limit;
20748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int retval;
20758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int error = 0;
20768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
20770612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
20788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
20798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	so = SCTP_INP_SO(inp);
20818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
20828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
20838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
20848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * find and validate the INIT chunk in the cookie (peer's info) the
20858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * INIT should start after the cookie-echo header struct (chunk
20868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * header, state cookie header struct)
20878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
20888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init_offset = offset + sizeof(struct sctp_cookie_echo_chunk);
20898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	init_cp = (struct sctp_init_chunk *)
20908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
20918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (uint8_t *) & init_buf);
20928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_cp == NULL) {
20938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* could not pull a INIT chunk in cookie */
20948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1,
20958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"process_cookie_new: could not pull INIT chunk hdr\n");
20968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
20978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
20988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (init_cp->ch.chunk_type != SCTP_INITIATION) {
20998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "HUH? process_cookie_new: could not find INIT chunk!\n");
21008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
21018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
2102b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
21038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
21048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * find and validate the INIT-ACK chunk in the cookie (my info) the
21058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * INIT-ACK follows the INIT chunk
21068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
21078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	initack_cp = (struct sctp_init_ack_chunk *)
21088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
21098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (uint8_t *) & initack_buf);
21108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (initack_cp == NULL) {
21118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* could not pull INIT-ACK chunk in cookie */
21128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: could not pull INIT-ACK chunk hdr\n");
21138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
21148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
21158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
21168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
21178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
21188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
21198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * NOTE: We can't use the INIT_ACK's chk_length to determine the
21208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * "initack_limit" value.  This is because the chk_length field
21218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * includes the length of the cookie, but the cookie is omitted when
21228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * the INIT and INIT_ACK are tacked onto the cookie...
21238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
21248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	initack_limit = offset + cookie_len;
21258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
21278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * now that we know the INIT/INIT-ACK are in place, create a new TCB
21288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * and popluate
21298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
21308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        /*
21328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Here we do a trick, we set in NULL for the proc/thread argument. We
21338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * do this since in effect we only use the p argument when
21348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * the socket is unbound and we must do an implicit bind.
21358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Since we are getting a cookie, we cannot be unbound.
21368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
21378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb = sctp_aloc_assoc(inp, init_src, &error,
21388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       ntohl(initack_cp->init.initiate_tag), vrf_id,
21398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
21408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       (struct thread *)NULL
21418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__)
21428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       (PKTHREAD)NULL
21438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
21448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       (struct proc *)NULL
21458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
21468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			       );
21478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL) {
21488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct mbuf *op_err;
21498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* memory problem? */
21518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1,
21528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"process_cookie_new: no room for another TCB!\n");
21538f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
21548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
2155e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                       src, dst, sh, op_err,
215651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
215751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
215851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
215951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, port);
21608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
21618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
21628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* get the correct sctp_nets */
21638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (netp)
21648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*netp = sctp_findnet(stcb, init_src);
21658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
21678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* get scope variables out of cookie */
21687988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
21697988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	asoc->scope.site_scope = cookie->site_scope;
21707988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	asoc->scope.local_scope = cookie->local_scope;
21717988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	asoc->scope.loopback_scope = cookie->loopback_scope;
21728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21737988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__)
21747988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
21757988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	    (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal) ||
21767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	    (asoc->scope.conn_addr_legal != cookie->conn_addr_legal)) {
21777988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#else
21787988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
21797988ea8f0c067cf3757e798b473b1ae4d34b6dfdt	    (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
21807988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif
21818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct mbuf *op_err;
21828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
21838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
21848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * Houston we have a problem. The EP changed while the
21858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * cookie was in flight. Only recourse is to abort the
21868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * association.
21878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
21888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
21898f9e45fea288542b24a6bda01269c6fc184d991at		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
21908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
2191e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				       src, dst, sh, op_err,
219251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
219351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       use_mflowid, mflowid,
219451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
219551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                       vrf_id, port);
21960612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
21978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
21988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
21998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
22008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
22028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				      SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
22030612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
22058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
22078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
22088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
22098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process the INIT-ACK info (my info) */
22108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
22118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
22128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
22138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
22148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
22158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
22168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
22178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->str_reset_seq_in = asoc->init_seq_number;
22188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
22198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
22208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
22218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process the INIT info (peer's info) */
22228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (netp)
22230ac02f34d6041cd0018437596a5a9a94685e6919tuexen		retval = sctp_process_init(init_cp, stcb);
22248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	else
22258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		retval = 0;
22268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (retval < 0) {
22278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
22280612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
22308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
22318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
22328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_16);
22340612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
22368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
22388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
22398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
22408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* load all addresses */
22410ac02f34d6041cd0018437596a5a9a94685e6919tuexen	if (sctp_load_addresses_from_init(stcb, m,
2242e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	    init_offset + sizeof(struct sctp_init_chunk), initack_offset,
2243e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	    src, dst, init_src)) {
22448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
22450612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
22478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
22488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
22498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_17);
22510612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
22538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
22558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
22568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
22578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
22588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * verify any preceding AUTH chunk that was skipped
22598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
22608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* pull the local authentication parameters from the cookie/init-ack */
22618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_auth_get_cookie_params(stcb, m,
22628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    initack_offset + sizeof(struct sctp_init_ack_chunk),
22638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)));
22648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (auth_skipped) {
22658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_auth_chunk *auth;
22668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
22678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		auth = (struct sctp_auth_chunk *)
22688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
22698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((auth == NULL) || sctp_handle_auth(stcb, auth, m, auth_offset)) {
22708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* auth HMAC failed, dump the assoc and packet */
22718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_AUTH1,
22728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				"COOKIE-ECHO: AUTH failed\n");
22738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_add_int(&stcb->asoc.refcnt, 1);
22740612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK(stcb);
22768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_LOCK(so, 1);
22778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_LOCK(stcb);
22788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_18);
22800612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
22818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
22828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
22838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_subtract_int(&stcb->asoc.refcnt, 1);
22848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
22858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
22868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* remaining chunks checked... good to go */
22878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.authenticated = 1;
22888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
22898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
22908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* update current state */
22918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
22928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
22938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
22948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
22958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 stcb->sctp_ep, stcb, asoc->primary_destination);
22968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
22978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_stop_all_cookie_timers(stcb);
22988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR_COUNTER32(sctps_passiveestab);
22998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR_GAUGE32(sctps_currestab);
23008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
23018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
23028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * if we're doing ASCONFs, check to see if we have any new local
23038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * addresses that need to get added to the peer (eg. addresses
23048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * changed while cookie echo in flight).  This needs to be done
23058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * after we go to the OPEN state to do the correct asconf
23068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * processing. else, make sure we have the correct addresses in our
23078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * lists
23088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
23098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
23108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* warning, we re-use sin, sin6, sa_store here! */
23118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* pull in local_address (our "from" address) */
23128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (cookie->laddr_type) {
23138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET
23148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_IPV4_ADDRESS:
23158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* source addr is IPv4 */
2316bfb1bf7e665a02b48026482bf33d05c83dfad73bt		memset(&store.sin, 0, sizeof(struct sockaddr_in));
2317bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin.sin_family = AF_INET;
23187b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN
2319bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin.sin_len = sizeof(struct sockaddr_in);
23208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
2321bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin.sin_addr.s_addr = cookie->laddress[0];
23228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
23238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6
23258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_IPV6_ADDRESS:
23268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* source addr is IPv6 */
2327bfb1bf7e665a02b48026482bf33d05c83dfad73bt		memset(&store.sin6, 0, sizeof(struct sockaddr_in6));
2328bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin6.sin6_family = AF_INET6;
23297b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN
2330bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin6.sin6_len = sizeof(struct sockaddr_in6);
23318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
2332bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sin6.sin6_scope_id = cookie->scope_id;
23331b77b4778bf4ea247d4e18d1694d8dc2d3d1d150t		memcpy(&store.sin6.sin6_addr, cookie->laddress, sizeof(struct in6_addr));
23348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
23358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23366a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#if defined(__Userspace__)
23376a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen	case SCTP_CONN_ADDRESS:
2338bfb1bf7e665a02b48026482bf33d05c83dfad73bt		/* source addr is conn */
23397b4117116463e6f61e3c39d542fd9fdfb5c395fat		memset(&store.sconn, 0, sizeof(struct sockaddr_conn));
2340bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sconn.sconn_family = AF_CONN;
23417b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SCONN_LEN
2342bfb1bf7e665a02b48026482bf33d05c83dfad73bt		store.sconn.sconn_len = sizeof(struct sockaddr_conn);
23436a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
2344bfb1bf7e665a02b48026482bf33d05c83dfad73bt		memcpy(&store.sconn.sconn_addr, cookie->laddress, sizeof(void *));
23456a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		break;
23466a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
23478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
23488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
23490612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
23508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
23518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
23528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
23538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_19);
23550612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
23568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
23578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
23598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
23608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
23618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
23628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* set up to notify upper layer */
23638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	*notification = SCTP_NOTIFY_ASSOC_UP;
23648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
23658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
23668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (inp->sctp_socket->so_qlimit == 0)) {
23678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
23688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * This is an endpoint that called connect() how it got a
23698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * cookie that is NEW is a bit of a mystery. It must be that
23708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * the INIT was sent, but before it got there.. a complete
23718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * INIT/INIT-ACK/COOKIE arrived. But of course then it
23728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * should have went to the other code.. not here.. oh well..
23738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * a bit of protection is worth having..
23748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
23758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
23760612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
23778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_add_int(&stcb->asoc.refcnt, 1);
23788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
23798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_LOCK(so, 1);
23808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(stcb);
23818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		atomic_subtract_int(&stcb->asoc.refcnt, 1);
23828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
23838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
23848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
23858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
23868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		soisconnected(stcb->sctp_socket);
23880612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
23898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SOCKET_UNLOCK(so, 1);
23908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
23918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
23928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (inp->sctp_socket->so_qlimit)) {
23938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
23948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * We don't want to do anything with this one. Since it is
23958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * the listening guy. The timer will get started for
23968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * accepted connections in the caller.
23978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
23988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		;
23998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
24008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* since we did not send a HB make sure we don't double things */
24018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((netp) && (*netp))
24028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(*netp)->hb_responded = 1;
24038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->asoc.sctp_autoclose_ticks &&
24058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
24068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
24078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
24088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* calculate the RTT */
24098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
24108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((netp) && (*netp)) {
24118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
241232a191a90b5c914a02047389c5b3197e08fc9841tuexen						  &cookie->time_entered, sctp_align_unsafe_makecopy,
24138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						  SCTP_RTT_FROM_NON_DATA);
24148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
24158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* respond with a COOKIE-ACK */
24168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_send_cookie_ack(stcb);
24178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
24198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * check the address lists for any ASCONFs that need to be sent
24208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * AFTER the cookie-ack is sent
24218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
24228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_check_address_list(stcb, m,
24238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    initack_offset + sizeof(struct sctp_init_ack_chunk),
24248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)),
2425bfb1bf7e665a02b48026482bf33d05c83dfad73bt	    &store.sa, cookie->local_scope, cookie->site_scope,
24268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    cookie->ipv4_scope, cookie->loopback_scope);
24278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (stcb);
24308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
24318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
24338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * CODE LIKE THIS NEEDS TO RUN IF the peer supports the NAT extension, i.e
24348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we NEED to make sure we are not already using the vtag. If so we
24358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * need to send back an ABORT-TRY-AGAIN-WITH-NEW-TAG No middle box bit!
24368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
24378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							    SCTP_BASE_INFO(hashasocmark))];
24388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	LIST_FOREACH(stcb, head, sctp_asocs) {
24398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	        if ((stcb->asoc.my_vtag == tag) && (stcb->rport == rport) && (inp == stcb->sctp_ep))  {
24408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		       -- SEND ABORT - TRY AGAIN --
24418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
24428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
24438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen*/
24448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
24468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * handles a COOKIE-ECHO message stcb: modified to either a new or left as
24478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * existing (non-NULL) TCB
24488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
24498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic struct mbuf *
24508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
2451e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    struct sockaddr *src, struct sockaddr *dst,
24528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctphdr *sh, struct sctp_cookie_echo_chunk *cp,
24538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_inpcb **inp_p, struct sctp_tcb **stcb, struct sctp_nets **netp,
24548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
245551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    struct sctp_tcb **locked_tcb,
245651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
245751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint8_t use_mflowid, uint32_t mflowid,
245851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
245951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint32_t vrf_id, uint16_t port)
24608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
24618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_state_cookie *cookie;
24628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tcb *l_stcb = *stcb;
24638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_inpcb *l_inp;
24648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sockaddr *to;
24658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_pcb *ep;
24668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *m_sig;
24678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t calc_sig[SCTP_SIGNATURE_SIZE], tmp_sig[SCTP_SIGNATURE_SIZE];
24688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t *sig;
24698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t cookie_ok = 0;
24700784257f13611c0e5c3a4b43b1eb73414d5d89a8tuexen	unsigned int sig_offset, cookie_offset;
24718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int cookie_len;
24728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct timeval now;
24738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct timeval time_expires;
24748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int notification = 0;
24758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *netl;
24768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int had_a_existing_tcb = 0;
24778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int send_int_conf = 0;
24788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET
24798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sockaddr_in sin;
24808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
24818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6
24828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sockaddr_in6 sin6;
24838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
24846a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#if defined(__Userspace__)
24856a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen	struct sockaddr_conn sconn;
24866a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
24878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
24898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_cookie: handling COOKIE-ECHO\n");
24908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (inp_p == NULL) {
24928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
24938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
24948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cookie = &cp->cookie;
24958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cookie_offset = offset + sizeof(struct sctp_chunkhdr);
24968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cookie_len = ntohs(cp->ch.chunk_length);
24978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
24988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((cookie->peerport != sh->src_port) &&
24998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (cookie->myport != sh->dest_port) &&
25008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (cookie->my_vtag != sh->v_tag)) {
25018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
25028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * invalid ports or bad tag.  Note that we always leave the
25038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * v_tag in the header in network order and when we stored
25048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * it in the my_vtag slot we also left it in network order.
25058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * This maintains the match even though it may be in the
25068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * opposite byte order of the machine :->
25078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
25088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
25098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25100784257f13611c0e5c3a4b43b1eb73414d5d89a8tuexen	if (cookie_len < sizeof(struct sctp_cookie_echo_chunk) +
25118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sizeof(struct sctp_init_chunk) +
25128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sizeof(struct sctp_init_ack_chunk) + SCTP_SIGNATURE_SIZE) {
25130784257f13611c0e5c3a4b43b1eb73414d5d89a8tuexen		/* cookie too small */
25148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
25158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
25178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * split off the signature into its own mbuf (since it should not be
25188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * calculated in the sctp_hmac_m() call).
25198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
25208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sig_offset = offset + cookie_len - SCTP_SIGNATURE_SIZE;
252168beeca578347438d9c434680197647ed551935ft	m_sig = m_split(m, sig_offset, M_NOWAIT);
25228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (m_sig == NULL) {
25238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* out of memory or ?? */
25248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
25258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MBUF_LOGGING
25278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
25288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct mbuf *mat;
2529208d5309857156b26b753ba8cb35813775f49c5btuexen
2530208d5309857156b26b753ba8cb35813775f49c5btuexen		for (mat = m_sig; mat; mat = SCTP_BUF_NEXT(mat)) {
25318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BUF_IS_EXTENDED(mat)) {
25328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_log_mb(mat, SCTP_MBUF_SPLIT);
25338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
25348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
25358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
25378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
25388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
25398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * compute the signature/digest for the cookie
25408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
25418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	ep = &(*inp_p)->sctp_ep;
25428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	l_inp = *inp_p;
25438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (l_stcb) {
25448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(l_stcb);
25458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_INP_RLOCK(l_inp);
25478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (l_stcb) {
25488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK(l_stcb);
25498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* which cookie is it? */
25518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((cookie->time_entered.tv_sec < (long)ep->time_of_secret_change) &&
25528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (ep->current_secret_number != ep->last_secret_number)) {
25538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* it's the old cookie */
25548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_hmac_m(SCTP_HMAC,
25558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (uint8_t *)ep->secret_key[(int)ep->last_secret_number],
25568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
25578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
25588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* it's the current cookie */
25598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)sctp_hmac_m(SCTP_HMAC,
25608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (uint8_t *)ep->secret_key[(int)ep->current_secret_number],
25618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
25628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* get the signature */
25648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_INP_RUNLOCK(l_inp);
25658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sig = (uint8_t *) sctp_m_getptr(m_sig, 0, SCTP_SIGNATURE_SIZE, (uint8_t *) & tmp_sig);
25668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (sig == NULL) {
25678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* couldn't find signature */
25688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_m_freem(m_sig);
25698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
25708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* compare the received digest with the computed digest */
25728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
25738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* try the old cookie? */
25748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((cookie->time_entered.tv_sec == (long)ep->time_of_secret_change) &&
25758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (ep->current_secret_number != ep->last_secret_number)) {
25768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* compute digest with old */
25778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			(void)sctp_hmac_m(SCTP_HMAC,
25788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (uint8_t *)ep->secret_key[(int)ep->last_secret_number],
25798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
25808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* compare */
25818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) == 0)
25828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				cookie_ok = 1;
25838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
25848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
25858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		cookie_ok = 1;
25868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
25878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
25888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
25898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Now before we continue we must reconstruct our mbuf so that
25908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * normal processing of any other chunks will work.
25918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
25928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	{
25938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct mbuf *m_at;
25948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
25958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		m_at = m;
25968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		while (SCTP_BUF_NEXT(m_at) != NULL) {
25978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			m_at = SCTP_BUF_NEXT(m_at);
25988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
25998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_BUF_NEXT(m_at) = m_sig;
26008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
26018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
26028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (cookie_ok == 0) {
26038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "handle_cookie_echo: cookie signature validation failed!\n");
26048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
26058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"offset = %u, cookie_offset = %u, sig_offset = %u\n",
26068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			(uint32_t) offset, cookie_offset, sig_offset);
26078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
26088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
26098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
26108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
26118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * check the cookie timestamps to be sure it's not stale
26128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
26138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)SCTP_GETTIME_TIMEVAL(&now);
26148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Expire time is in Ticks, so we convert to seconds */
26158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life);
26168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	time_expires.tv_usec = cookie->time_entered.tv_usec;
26178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        /* TODO sctp_constants.h needs alternative time macros when
26188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen         *  _KERNEL is undefined.
26198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen         */
26208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef __FreeBSD__
26218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (timercmp(&now, &time_expires, >))
26228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
26238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (timevalcmp(&now, &time_expires, >))
26248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
26258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	{
26268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* cookie is stale! */
26278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct mbuf *op_err;
26288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_stale_cookie_msg *scm;
26298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		uint32_t tim;
26308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_stale_cookie_msg),
263168beeca578347438d9c434680197647ed551935ft					       0, M_NOWAIT, 1, MT_DATA);
26328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (op_err == NULL) {
26338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* FOOBAR */
26348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
26358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
26368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Set the len */
26378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
26388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		scm = mtod(op_err, struct sctp_stale_cookie_msg *);
26398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
26408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
26418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (sizeof(uint32_t))));
26428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* seconds to usec */
26438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		tim = (now.tv_sec - time_expires.tv_sec) * 1000000;
26448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* add in usec */
26458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (tim == 0)
26468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			tim = now.tv_usec - cookie->time_entered.tv_usec;
26478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		scm->time_usec = htonl(tim);
2648e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
264951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
265051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                   use_mflowid, mflowid,
265151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
265251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                   vrf_id, port);
26538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
26548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
26558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
26568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Now we must see with the lookup address if we have an existing
26578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * asoc. This will only happen if we were in the COOKIE-WAIT state
26588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * and a INIT collided with us and somewhere the peer sent the
26598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * cookie on another address besides the single address our assoc
26608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * had for him. In this case we will have one of the tie-tags set at
26618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * least AND the address field in the cookie can be used to look it
26628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * up.
26638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
26648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	to = NULL;
26658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (cookie->addr_type) {
26668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6
26678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_IPV6_ADDRESS:
26688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		memset(&sin6, 0, sizeof(sin6));
26698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin6.sin6_family = AF_INET6;
26707b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN
26718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin6.sin6_len = sizeof(sin6);
26728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
26738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin6.sin6_port = sh->src_port;
26748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin6.sin6_scope_id = cookie->scope_id;
26758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		memcpy(&sin6.sin6_addr.s6_addr, cookie->address,
26768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sizeof(sin6.sin6_addr.s6_addr));
26778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		to = (struct sockaddr *)&sin6;
26788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
26798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
26808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET
26818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_IPV4_ADDRESS:
26828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		memset(&sin, 0, sizeof(sin));
26838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin.sin_family = AF_INET;
26847b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN
26858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin.sin_len = sizeof(sin);
26868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
26878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin.sin_port = sh->src_port;
26888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sin.sin_addr.s_addr = cookie->address[0];
26898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		to = (struct sockaddr *)&sin;
26908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
26918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
26926a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#if defined(__Userspace__)
26936a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen	case SCTP_CONN_ADDRESS:
26946a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		memset(&sconn, 0, sizeof(struct sockaddr_conn));
26956a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		sconn.sconn_family = AF_CONN;
26967b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SCONN_LEN
26976a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		sconn.sconn_len = sizeof(struct sockaddr_conn);
26986a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
26996a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		sconn.sconn_port = sh->src_port;
27006a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		memcpy(&sconn.sconn_addr, cookie->address, sizeof(void *));
27016a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		to = (struct sockaddr *)&sconn;
27026a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen		break;
27036a977e5c22f6cf4a20cff9658398a6a7fe42e1adtuexen#endif
27048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
27058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* This should not happen */
27068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
27078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((*stcb == NULL) && to) {
27098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Yep, lets check */
2710e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		*stcb = sctp_findassociation_ep_addr(inp_p, to, netp, dst, NULL);
27118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (*stcb == NULL) {
27128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
27138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We should have only got back the same inp. If we
27148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * got back a different ep we have a problem. The
27158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * original findep got back l_inp and now
27168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
27178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (l_inp != *inp_p) {
27188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_PRINTF("Bad problem find_ep got a diff inp then special_locate?\n");
27198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
27208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
27218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (*locked_tcb == NULL) {
27228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* In this case we found the assoc only
27238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * after we locked the create lock. This means
27248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * we are in a colliding case and we must make
27258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * sure that we unlock the tcb if its one of the
27268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * cases where we throw away the incoming packets.
27278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
27288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*locked_tcb = *stcb;
27298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
27308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* We must also increment the inp ref count
27318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * since the ref_count flags was set when we
27328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * did not find the TCB, now we found it which
27338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * reduces the refcount.. we must raise it back
27348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * out to balance it all :-)
27358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
27368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_INP_INCR_REF((*stcb)->sctp_ep);
27378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((*stcb)->sctp_ep != l_inp) {
27388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_PRINTF("Huh? ep:%p diff then l_inp:%p?\n",
2739ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t						    (void *)(*stcb)->sctp_ep, (void *)l_inp);
27408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
27418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
27428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
27438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (to == NULL) {
27458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
27468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
274732a191a90b5c914a02047389c5b3197e08fc9841tuexen
27488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cookie_len -= SCTP_SIGNATURE_SIZE;
27498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (*stcb == NULL) {
27508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* this is the "normal" case... get a new TCB */
2751e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		*stcb = sctp_process_cookie_new(m, iphlen, offset, src, dst, sh,
2752e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                                cookie, cookie_len, *inp_p,
2753e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                                netp, to, &notification,
275451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                                auth_skipped, auth_offset, auth_len,
275551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
275651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                                use_mflowid, mflowid,
275751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
275851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                                vrf_id, port);
27598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
27608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* this is abnormal... cookie-echo on existing TCB */
27618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		had_a_existing_tcb = 1;
2762e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		*stcb = sctp_process_cookie_existing(m, iphlen, offset,
2763e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                                     src, dst, sh,
27648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						     cookie, cookie_len, *inp_p, *stcb, netp, to,
276551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen						     &notification, auth_skipped, auth_offset, auth_len,
276651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
276751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                                     use_mflowid, mflowid,
276851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
276951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                                     vrf_id, port);
27708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
27728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (*stcb == NULL) {
27738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* still no TCB... must be bad cookie-echo */
27748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
27758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__)
277751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	if ((*netp != NULL) && (use_mflowid != 0)) {
277851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		(*netp)->flowid = mflowid;
27798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS
27808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(*netp)->flowidset = 1;
27818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
27828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
27848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
27858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Ok, we built an association so confirm the address we sent the
27868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * INIT-ACK to.
27878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
27888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	netl = sctp_findnet(*stcb, to);
27898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
27908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * This code should in theory NOT run but
27918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
27928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (netl == NULL) {
27938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* TSNH! Huh, why do I need to add this address here? */
2794b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		if (sctp_add_remote_addr(*stcb, to, NULL, SCTP_DONOT_SETSCOPE, SCTP_IN_COOKIE_PROC)) {
2795b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			return (NULL);
2796b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		}
27978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		netl = sctp_findnet(*stcb, to);
27988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
27998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (netl) {
28008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (netl->dest_state & SCTP_ADDR_UNCONFIRMED) {
28018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			netl->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
28028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			(void)sctp_set_primary_addr((*stcb), (struct sockaddr *)NULL,
28038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    netl);
28048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			send_int_conf = 1;
28058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
28068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
28078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_start_net_timers(*stcb);
28088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
28098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (!had_a_existing_tcb ||
28108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
28118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
28128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * If we have a NEW cookie or the connect never
28138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * reached the connected state during collision we
28148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * must do the TCP accept thing.
28158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
28168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct socket *so, *oso;
28178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_inpcb *inp;
28188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
28198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (notification == SCTP_NOTIFY_ASSOC_RESTART) {
28208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
28218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * For a restart we will keep the same
28228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * socket, no need to do anything. I THINK!!
28238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
28240ac02f34d6041cd0018437596a5a9a94685e6919tuexen				sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
28258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (send_int_conf) {
28268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
2827e2828360ea9cf8951730d46f5c14626c9425cb30t					                (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
28288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
28298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (m);
28308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
28318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			oso = (*inp_p)->sctp_socket;
28328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 700000)
28338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
28348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We do this to keep the sockets side happy during
28358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the sonewcon ONLY.
28368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
28378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			NET_LOCK_GIANT();
28388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
28408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK((*stcb));
28418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
28428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			CURVNET_SET(oso->so_vnet);
28438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__)
28458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_LOCK(oso, 1);
28468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			so = sonewconn(oso, 0
28488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__)
28498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    ,NULL
28508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __Panda__
28528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			     ,NULL , (*inp_p)->def_vrf_id
28538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    );
28558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 700000)
28568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			NET_UNLOCK_GIANT();
28578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__)
28598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(oso, 1);
28608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
28628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			CURVNET_RESTORE();
28638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_LOCK((*stcb));
28658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
28668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
28678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (so == NULL) {
28688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct mbuf *op_err;
28690612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
28708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct socket *pcb_so;
28718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Too many sockets */
28738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
28748f9e45fea288542b24a6bda01269c6fc184d991at				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
28758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_abort_association(*inp_p, NULL, m, iphlen,
2876e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						       src, dst, sh, op_err,
287751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
287851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       use_mflowid, mflowid,
287951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
288051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       vrf_id, port);
28810612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
28828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				pcb_so = SCTP_INP_SO(*inp_p);
28838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				atomic_add_int(&(*stcb)->asoc.refcnt, 1);
28848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK((*stcb));
28858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_SOCKET_LOCK(pcb_so, 1);
28868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_LOCK((*stcb));
28878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
28888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				(void)sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_20);
28900612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
28918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_SOCKET_UNLOCK(pcb_so, 1);
28928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
28938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
28948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
28958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp = (struct sctp_inpcb *)so->so_pcb;
28968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_INP_INCR_REF(inp);
28978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
28988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We add the unbound flag here so that
28998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * if we get an soabort() before we get the
29008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * move_pcb done, we will properly cleanup.
29018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
29028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
29038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    SCTP_PCB_FLAGS_CONNECTED |
29048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    SCTP_PCB_FLAGS_IN_TCPPOOL |
2905e2828360ea9cf8951730d46f5c14626c9425cb30t			    SCTP_PCB_FLAGS_UNBOUND |
29068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) |
29078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    SCTP_PCB_FLAGS_DONT_WAKE);
29088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_features = (*inp_p)->sctp_features;
29098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
29108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_socket = so;
29118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
29128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
2913aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t			inp->ecn_supported = (*inp_p)->ecn_supported;
2914a8657c4fc04fb9cc82100f648810d51ec6ab155at			inp->prsctp_supported = (*inp_p)->prsctp_supported;
2915fb3816eaffe5878bb1286adb120fd160da178a05t			inp->auth_supported = (*inp_p)->auth_supported;
2916fb3816eaffe5878bb1286adb120fd160da178a05t			inp->asconf_supported = (*inp_p)->asconf_supported;
29172344bfccffeb80545fca6a86e8cda3d56a6f50bft			inp->reconfig_supported = (*inp_p)->reconfig_supported;
291844318e900a771ba1a5bafb510c38f33fd5cd8a39t			inp->nrsack_supported = (*inp_p)->nrsack_supported;
2919669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t			inp->pktdrop_supported = (*inp_p)->pktdrop_supported;
29208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
29218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_context = (*inp_p)->sctp_context;
2922c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			inp->local_strreset_support = (*inp_p)->local_strreset_support;
29238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->inp_starting_point_for_iterator = NULL;
292432a191a90b5c914a02047389c5b3197e08fc9841tuexen#if defined(__Userspace__)
2925d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen			inp->ulp_info = (*inp_p)->ulp_info;
292632a191a90b5c914a02047389c5b3197e08fc9841tuexen			inp->recv_callback = (*inp_p)->recv_callback;
292732a191a90b5c914a02047389c5b3197e08fc9841tuexen			inp->send_callback = (*inp_p)->send_callback;
292832a191a90b5c914a02047389c5b3197e08fc9841tuexen			inp->send_sb_threshold = (*inp_p)->send_sb_threshold;
292932a191a90b5c914a02047389c5b3197e08fc9841tuexen#endif
29308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
29318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * copy in the authentication parameters from the
29328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * original endpoint
29338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
29348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (inp->sctp_ep.local_hmacs)
29358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
29368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_ep.local_hmacs =
29378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    sctp_copy_hmaclist((*inp_p)->sctp_ep.local_hmacs);
29388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (inp->sctp_ep.local_auth_chunks)
29398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
29408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			inp->sctp_ep.local_auth_chunks =
29418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    sctp_copy_chunklist((*inp_p)->sctp_ep.local_auth_chunks);
29428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
29448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Now we must move it from one hash table to
29458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * another and get the tcb in the right place.
29468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
29478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* This is where the one-2-one socket is put into
29498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the accept state waiting for the accept!
29508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
29518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (*stcb) {
29528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				(*stcb)->asoc.state |= SCTP_STATE_IN_ACCEPT_QUEUE;
29538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
29548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_move_pcb_and_assoc(*inp_p, inp, *stcb);
29558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
29578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK((*stcb));
29588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__)
29608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb,
29618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    0);
29628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
29638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb, M_NOWAIT);
29648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
29658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_LOCK((*stcb));
29668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
29678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* now we must check to see if we were aborted while
29708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the move was going on and the lock/unlock happened.
29718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
29728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
29738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* yep it was, we leave the
29748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * assoc attached to the socket since
29758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * the sctp_inpcb_free() call will send
29768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * an abort for us.
29778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
29788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_INP_DECR_REF(inp);
29798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
29808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
29818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_INP_DECR_REF(inp);
29828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Switch over to the new guy */
29838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*inp_p = inp;
29848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
29858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (send_int_conf) {
29868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
29878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				                (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
29888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
29898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
29908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Pull it from the incomplete queue and wake the guy */
29910612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
29928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
29938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK((*stcb));
29948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_LOCK(so, 1);
29958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
29968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			soisconnected(so);
29970612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
29988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_LOCK((*stcb));
29998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
30008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
30018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
30028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (m);
30038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
3005186f71381d5ac588524f9a1401d0c0a9997601e5tuexen	if (notification) {
3006186f71381d5ac588524f9a1401d0c0a9997601e5tuexen		sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
3007186f71381d5ac588524f9a1401d0c0a9997601e5tuexen	}
3008186f71381d5ac588524f9a1401d0c0a9997601e5tuexen	if (send_int_conf) {
3009186f71381d5ac588524f9a1401d0c0a9997601e5tuexen		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
3010186f71381d5ac588524f9a1401d0c0a9997601e5tuexen		                (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
30118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
30128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (m);
30138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
30148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
30160ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
30178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net)
30188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
30198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* cp must not be used, others call this without a c-ack :-) */
30208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
30218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
30238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_cookie_ack: handling COOKIE-ACK\n");
30248975bd5397c2ec97f50e0b87b544054e0536bfe1t	if ((stcb == NULL) || (net == NULL)) {
30258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
30268975bd5397c2ec97f50e0b87b544054e0536bfe1t	}
30278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
30298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_stop_all_cookie_timers(stcb);
30318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process according to association state */
30328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
30338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* state change only needed when I am in right state */
30348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
30358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
30368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_start_net_timers(stcb);
30378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
30388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
30398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb->sctp_ep, stcb, asoc->primary_destination);
30408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* update RTO */
30438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
30448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR_GAUGE32(sctps_currestab);
30458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asoc->overall_error_count == 0) {
30468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net->RTO = sctp_calculate_rto(stcb, asoc, net,
304732a191a90b5c914a02047389c5b3197e08fc9841tuexen					             &asoc->time_entered, sctp_align_safe_nocopy,
30488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						      SCTP_RTT_FROM_NON_DATA);
30498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
30518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_UP, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
30528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
30538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
30540612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
30558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct socket *so;
30568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
30588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
30590612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
30608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			so = SCTP_INP_SO(stcb->sctp_ep);
30618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_add_int(&stcb->asoc.refcnt, 1);
30628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK(stcb);
30638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_LOCK(so, 1);
30648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_LOCK(stcb);
30658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			atomic_subtract_int(&stcb->asoc.refcnt, 1);
30668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
30678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) == 0) {
30688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				soisconnected(stcb->sctp_socket);
30698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
30700612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
30718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_SOCKET_UNLOCK(so, 1);
30728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
30738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
30758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * since we did not send a HB make sure we don't double
30768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * things
30778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
30788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->hb_responded = 1;
30798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
30818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* We don't need to do the asconf thing,
30828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * nor hb or autoclose if the socket is closed.
30838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
30848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			goto closed_socket;
30858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
30888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    stcb, net);
30898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
30918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.sctp_autoclose_ticks &&
30928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTOCLOSE)) {
30938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
30948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    stcb->sctp_ep, stcb, NULL);
30958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
30968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
30978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * send ASCONF if parameters are pending and ASCONFs are
30988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * allowed (eg. addresses changed when init/cookie echo were
30998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * in flight)
31008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
31018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DO_ASCONF)) &&
3102fb3816eaffe5878bb1286adb120fd160da178a05t		    (stcb->asoc.asconf_supported == 1) &&
31038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (!TAILQ_EMPTY(&stcb->asoc.asconf_queue))) {
31048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_TIMER_BASED_ASCONF
31058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
31068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb->sctp_ep, stcb,
31078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb->asoc.primary_destination);
31088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
31098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_send_asconf(stcb, stcb->asoc.primary_destination,
31108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 SCTP_ADDR_NOT_LOCKED);
31118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
31128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
31138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenclosed_socket:
31158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Toss the cookie if I can */
31168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_toss_old_cookies(stcb, asoc);
31178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
31188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Restart the timer if we have pending data */
31198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_tmit_chunk *chk;
31208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
31218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chk = TAILQ_FIRST(&asoc->sent_queue);
31228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
31238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
31258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
31268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
31278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_ecn_echo(struct sctp_ecne_chunk *cp,
31288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		     struct sctp_tcb *stcb)
31298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
31308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_nets *net;
31318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *lchk;
31328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_ecne_chunk bkup;
3133b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	uint8_t override_bit;
31348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t tsn, window_data_tsn;
31358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int len;
31368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int pkt_cnt;
3137b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen
31388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	len = ntohs(cp->ch.chunk_length);
31398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((len != sizeof(struct sctp_ecne_chunk)) &&
31408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (len != sizeof(struct old_sctp_ecne_chunk))) {
31418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
31428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (len == sizeof(struct old_sctp_ecne_chunk)) {
31448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Its the old format */
31458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		memcpy(&bkup, cp, sizeof(struct old_sctp_ecne_chunk));
31468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		bkup.num_pkts_since_cwr = htonl(1);
31478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		cp = &bkup;
31488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR(sctps_recvecne);
31508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	tsn = ntohl(cp->tsn);
31518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	pkt_cnt = ntohl(cp->num_pkts_since_cwr);
31528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead);
31538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (lchk == NULL) {
31548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		window_data_tsn = stcb->asoc.sending_seq - 1;
31558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
31568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		window_data_tsn = lchk->rec.data.TSN_seq;
31578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
31598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Find where it was sent to if possible. */
31608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	net = NULL;
31618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
31628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (lchk->rec.data.TSN_seq == tsn) {
31638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net = lchk->whoTo;
31648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send;
31658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
31668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
31678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_TSN_GT(lchk->rec.data.TSN_seq, tsn)) {
31688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
31698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
31708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
31718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (net == NULL) {
317232a191a90b5c914a02047389c5b3197e08fc9841tuexen		/*
31738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * What to do. A previous send of a
31748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * CWR was possibly lost. See how old it is, we
31758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * may have it marked on the actual net.
31768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
31778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
31788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (tsn == net->last_cwr_tsn) {
31798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Found him, send it off */
3180b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen				break;
31818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
31828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
3183b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		if (net == NULL) {
318432a191a90b5c914a02047389c5b3197e08fc9841tuexen			/*
3185b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			 * If we reach here, we need to send a special
3186b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			 * CWR that says hey, we did this a long time
3187b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			 * ago and you lost the response.
3188b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			 */
3189b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			net = TAILQ_FIRST(&stcb->asoc.nets);
3190b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			if (net == NULL) {
3191b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen				/* TSNH */
3192b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen				return;
3193b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			}
3194b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			override_bit = SCTP_CWR_REDUCE_OVERRIDE;
3195b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		} else {
3196b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			override_bit = 0;
3197b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		}
3198b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	} else {
3199b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen		override_bit = 0;
32008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
32018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) &&
32028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((override_bit&SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
32038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* JRS - Use the congestion control given in the pluggable CC module */
32048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt);
32058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
32068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * We reduce once every RTT. So we will only lower cwnd at
32078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * the next sending seq i.e. the window_data_tsn
32088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
32098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->cwr_window_tsn = window_data_tsn;
32108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->ecn_ce_pkt_cnt += pkt_cnt;
32118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->lost_cnt = pkt_cnt;
32128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		net->last_cwr_tsn = tsn;
32138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
32148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		override_bit |= SCTP_CWR_IN_SAME_WINDOW;
32158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_TSN_GT(tsn, net->last_cwr_tsn) &&
32168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    ((override_bit&SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
32178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
32188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Another loss in the same window update how
32198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * many marks/packets lost we have had.
32208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
32218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			int cnt = 1;
32228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (pkt_cnt > net->lost_cnt) {
32238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Should be the case */
32248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				cnt = (pkt_cnt - net->lost_cnt);
32258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				net->ecn_ce_pkt_cnt += cnt;
32268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
32278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net->lost_cnt = pkt_cnt;
32288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net->last_cwr_tsn = tsn;
32298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
32308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Most CC functions will ignore this call, since we are in-window
32318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * yet of the initial CE the peer saw.
32328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
32338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 1, cnt);
32348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
32358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
32368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
32378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * We always send a CWR this way if our previous one was lost our
32388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * peer will get an update, or if it is not time again to reduce we
32398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * still get the cwr to the peer. Note we set the override when we
32408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * could not find the TSN on the chunk or the destination network.
32418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
32428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_send_cwr(stcb, net, net->last_cwr_tsn, override_bit);
32438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
32448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
32458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
32468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sctp_nets *net)
32478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
32488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
32498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Here we get a CWR from the peer. We must look in the outqueue and
3250f405d7f07b0213ec54f2055f8bdc6185c836870ct	 * make sure that we have a covered ECNE in the control chunk part.
32518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * If so remove it.
32528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
32538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *chk;
32548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_ecne_chunk *ecne;
32558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int override;
32568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t cwr_tsn;
32578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	cwr_tsn = ntohl(cp->tsn);
32588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
32598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	override = cp->ch.chunk_flags & SCTP_CWR_REDUCE_OVERRIDE;
32608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
32618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (chk->rec.chunk_id.id != SCTP_ECN_ECHO) {
32628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			continue;
32638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
32648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((override == 0) && (chk->whoTo != net)) {
32658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Must be from the right src unless override is set */
32668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			continue;
32678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
32688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ecne = mtod(chk->data, struct sctp_ecne_chunk *);
32698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_TSN_GE(cwr_tsn, ntohl(ecne->tsn))) {
32708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* this covers this ECNE, we can remove it */
32718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.ecn_echo_cnt_onq--;
32728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk,
32738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    sctp_next);
32748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk->data) {
32758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_m_freem(chk->data);
32768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				chk->data = NULL;
32778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
32788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.ctrl_queue_cnt--;
32798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
32808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (override == 0) {
32818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
32828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
32838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
32848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
32858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
32868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
32878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
32880ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSED,
32898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net)
32908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
32918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
32920612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
32938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
32948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
32958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
32968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
32978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_shutdown_complete: handling SHUTDOWN-COMPLETE\n");
32988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL)
32998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
33008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
33018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
33028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* process according to association state */
33038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
33048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* unexpected SHUTDOWN-COMPLETE... so ignore... */
33058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2,
33068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"sctp_handle_shutdown_complete: not in SCTP_STATE_SHUTDOWN_ACK_SENT --- ignore\n");
33078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_UNLOCK(stcb);
33088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
33098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
33108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* notify upper layer protocol */
33118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->sctp_socket) {
33128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
33138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
331497e4568a3ba270aaad30d8713c38235a1d8fa518t#ifdef INVARIANTS
331597e4568a3ba270aaad30d8713c38235a1d8fa518t	if (!TAILQ_EMPTY(&asoc->send_queue) ||
331697e4568a3ba270aaad30d8713c38235a1d8fa518t	    !TAILQ_EMPTY(&asoc->sent_queue) ||
331797e4568a3ba270aaad30d8713c38235a1d8fa518t	    !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
331897e4568a3ba270aaad30d8713c38235a1d8fa518t		panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
331997e4568a3ba270aaad30d8713c38235a1d8fa518t	}
332097e4568a3ba270aaad30d8713c38235a1d8fa518t#endif
33218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* stop the timer */
33228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_22);
33238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
33248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* free the TCB */
33258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT2,
33268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"sctp_handle_shutdown_complete: calls free-asoc\n");
33270612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
33288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	so = SCTP_INP_SO(stcb->sctp_ep);
33298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_add_int(&stcb->asoc.refcnt, 1);
33308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_UNLOCK(stcb);
33318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_LOCK(so, 1);
33328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_TCB_LOCK(stcb);
33338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	atomic_subtract_int(&stcb->asoc.refcnt, 1);
33348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
33358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_23);
33360612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
33378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_SOCKET_UNLOCK(so, 1);
33388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
33398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return;
33408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
33418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
33428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
33438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenprocess_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
33448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_nets *net, uint8_t flg)
33458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
33468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	switch (desc->chunk_type) {
33478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_DATA:
33488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* find the tsn to resend (possibly */
33498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	{
33508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		uint32_t tsn;
33518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_tmit_chunk *tp1;
33528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
33538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		tsn = ntohl(desc->tsn_ifany);
33548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
33558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (tp1->rec.data.TSN_seq == tsn) {
33568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* found it */
33578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
33588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
33598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, tsn)) {
33608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* not found */
33618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				tp1 = NULL;
33628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
33638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
33648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
33658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (tp1 == NULL) {
33668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
33678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Do it the other way , aka without paying
33688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * attention to queue seq order.
33698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
33708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrpdnfnd);
33718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
33728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (tp1->rec.data.TSN_seq == tsn) {
33738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* found it */
33748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
33758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
33768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
33778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
33788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (tp1 == NULL) {
33798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrptsnnf);
33808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
33818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((tp1) && (tp1->sent < SCTP_DATAGRAM_ACKED)) {
33828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			uint8_t *ddp;
33838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
33848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (((flg & SCTP_BADCRC) == 0) &&
33858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
33868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (0);
33878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
33888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb->asoc.peers_rwnd == 0) &&
33898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
33908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpdiwnp);
33918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (0);
33928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
33938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb->asoc.peers_rwnd == 0 &&
33948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (flg & SCTP_FROM_MIDDLE_BOX)) {
33958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpdizrw);
33968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (0);
33978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
3398b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			ddp = (uint8_t *) (mtod(tp1->data, caddr_t) +
33998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					   sizeof(struct sctp_data_chunk));
34008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			{
34018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				unsigned int iii;
34028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				for (iii = 0; iii < sizeof(desc->data_bytes);
34048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				     iii++) {
34058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (ddp[iii] != desc->data_bytes[iii]) {
34068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_STAT_INCR(sctps_pdrpbadd);
34078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						return (-1);
34088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
34098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
34108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (tp1->do_rtt) {
34138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
34148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * this guy had a RTO calculation
34158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * pending on it, cancel it
34168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
34178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (tp1->whoTo->rto_needed == 0) {
34188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					tp1->whoTo->rto_needed = 1;
34198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
34208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				tp1->do_rtt = 0;
34218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrpmark);
34238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (tp1->sent != SCTP_DATAGRAM_RESEND)
34248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
34258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
34268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * mark it as if we were doing a FR, since
34278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * we will be getting gap ack reports behind
34288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the info from the router.
34298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
34308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			tp1->rec.data.doing_fast_retransmit = 1;
34318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
34328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * mark the tsn with what sequences can
34338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * cause a new FR.
34348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
34358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
34368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				tp1->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
34378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
34388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
34398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* restart the timer */
34428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
34438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb, tp1->whoTo, SCTP_FROM_SCTP_INPUT+SCTP_LOC_24);
34448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
34458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 stcb, tp1->whoTo);
34468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* fix counts and things */
34488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
34498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PDRP,
34508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       tp1->whoTo->flight_size,
34518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       tp1->book_size,
34528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       (uintptr_t)stcb,
34538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       tp1->rec.data.TSN_seq);
34548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (tp1->sent < SCTP_DATAGRAM_RESEND) {
34568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_flight_size_decrease(tp1);
34578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_total_flight_decrease(stcb, tp1);
34588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			tp1->sent = SCTP_DATAGRAM_RESEND;
34608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} {
34618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* audit code */
34628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			unsigned int audit;
34638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			audit = 0;
34658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
34668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (tp1->sent == SCTP_DATAGRAM_RESEND)
34678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					audit++;
34688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_FOREACH(tp1, &stcb->asoc.control_send_queue,
34708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				      sctp_next) {
34718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (tp1->sent == SCTP_DATAGRAM_RESEND)
34728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					audit++;
34738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (audit != stcb->asoc.sent_queue_retran_cnt) {
34758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_PRINTF("**Local Audit finds cnt:%d asoc cnt:%d\n",
34768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					    audit, stcb->asoc.sent_queue_retran_cnt);
34778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef SCTP_AUDITING_ENABLED
34788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.sent_queue_retran_cnt = audit;
34798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
34808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
34828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
34838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	break;
34848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ASCONF:
34858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	{
34868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_tmit_chunk *asconf;
34878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
34888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
34898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      sctp_next) {
34908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (asconf->rec.chunk_id.id == SCTP_ASCONF) {
34918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
34928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
34938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
34948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (asconf) {
34958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (asconf->sent != SCTP_DATAGRAM_RESEND)
34968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
34978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asconf->sent = SCTP_DATAGRAM_RESEND;
34988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asconf->snd_count--;
34998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
35018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	break;
35028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_INITIATION:
35038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* resend the INIT */
35048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.dropped_special_cnt++;
35058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.dropped_special_cnt < SCTP_RETRY_DROPPED_THRESH) {
35068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
35078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * If we can get it in, in a few attempts we do
35088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * this, otherwise we let the timer fire.
35098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
35108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep,
35118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_25);
35128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
35138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SELECTIVE_ACK:
35168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_NR_SELECTIVE_ACK:
35178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* resend the sack */
35188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
35198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_HEARTBEAT_REQUEST:
35218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* resend a demand HB */
35228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
35238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Only retransmit if we KNOW we wont destroy the tcb */
35248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
35258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SHUTDOWN:
35288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_shutdown(stcb, net);
35298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SHUTDOWN_ACK:
35318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_shutdown_ack(stcb, net);
35328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_COOKIE_ECHO:
35348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	{
35358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		struct sctp_tmit_chunk *cookie;
35368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
35378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		cookie = NULL;
35388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue,
35398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			      sctp_next) {
35408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
35418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
35428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
35438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (cookie) {
35458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (cookie->sent != SCTP_DATAGRAM_RESEND)
35468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
35478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			cookie->sent = SCTP_DATAGRAM_RESEND;
35488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_stop_all_cookie_timers(stcb);
35498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
35518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	break;
35528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_COOKIE_ACK:
35538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_cookie_ack(stcb);
35548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ASCONF_ACK:
35568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* resend last asconf ack */
35578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_asconf_ack(stcb);
35588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_FORWARD_CUM_TSN:
35608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		send_forward_tsn(stcb, &stcb->asoc);
35618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* can't do anything with these */
35638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_PACKET_DROPPED:
35648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_INITIATION_ACK:	/* this should not happen */
35658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_HEARTBEAT_ACK:
35668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ABORT_ASSOCIATION:
35678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_OPERATION_ERROR:
35688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_SHUTDOWN_COMPLETE:
35698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ECN_ECHO:
35708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	case SCTP_ECN_CWR:
35718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	default:
35728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		break;
35738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
35748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
35758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
35768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
35778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
3578b6a8c974796d76c59ef64a7555e446c9cd171877tsctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
35798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
3580c1f5477d96c0c5178c74caad234035e534c37bdct	uint32_t i;
35818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t temp;
35828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
35838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
35848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * We set things to 0xffff since this is the last delivered sequence
35858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * and we will be sending in 0 after the reset.
35868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
35878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
35888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (number_entries) {
35898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		for (i = 0; i < number_entries; i++) {
35908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			temp = ntohs(list[i]);
35918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (temp >= stcb->asoc.streamincnt) {
35928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				continue;
35938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
35948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.strmin[temp].last_sequence_delivered = 0xffff;
35958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
35968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
35978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		list = NULL;
35988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		for (i = 0; i < stcb->asoc.streamincnt; i++) {
35998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
36008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
36018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_RECV, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
36038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
36048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
3606b6a8c974796d76c59ef64a7555e446c9cd171877tsctp_reset_out_streams(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
36078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
3608b6a8c974796d76c59ef64a7555e446c9cd171877t	uint32_t i;
3609b6a8c974796d76c59ef64a7555e446c9cd171877t	uint16_t temp;
36108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
3611b6a8c974796d76c59ef64a7555e446c9cd171877t	if (number_entries > 0) {
36128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		for (i = 0; i < number_entries; i++) {
36138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			temp = ntohs(list[i]);
36148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (temp >= stcb->asoc.streamoutcnt) {
36158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* no such stream */
36168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				continue;
36178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
3618e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t			stcb->asoc.strmout[temp].next_sequence_send = 0;
3619b6a8c974796d76c59ef64a7555e446c9cd171877t		}
3620b6a8c974796d76c59ef64a7555e446c9cd171877t	} else {
3621b6a8c974796d76c59ef64a7555e446c9cd171877t		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
3622b6a8c974796d76c59ef64a7555e446c9cd171877t			stcb->asoc.strmout[i].next_sequence_send = 0;
36238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
36248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
36268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
36278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sctp_stream_reset_out_request *
36308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk)
36318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
36328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
363324feb751a6f488d36918e2f333dc2be853c259c8t	struct sctp_chunkhdr *ch;
36348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_stream_reset_out_request *r;
36358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *chk;
36368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int len, clen;
36378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
36398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
36408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->stream_reset_outstanding = 0;
36418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
36428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->asoc.str_reset == NULL) {
36448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->stream_reset_outstanding = 0;
36458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
36468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk = stcb->asoc.str_reset;
36488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (chk->data == NULL) {
36498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
36508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (bchk) {
36528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* he wants a copy of the chk pointer */
36538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*bchk = chk;
36548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	clen = chk->send_size;
365624feb751a6f488d36918e2f333dc2be853c259c8t	ch = mtod(chk->data, struct sctp_chunkhdr *);
365724feb751a6f488d36918e2f333dc2be853c259c8t	r = (struct sctp_stream_reset_out_request *)(ch + 1);
36588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohl(r->request_seq) == seq) {
36598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* found it */
36608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (r);
36618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	len = SCTP_SIZE32(ntohs(r->ph.param_length));
36638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (clen > (len + (int)sizeof(struct sctp_chunkhdr))) {
36648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* move to the next one, there can only be a max of two */
36658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		r = (struct sctp_stream_reset_out_request *)((caddr_t)r + len);
36668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ntohl(r->request_seq) == seq) {
36678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (r);
36688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
36698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* that seq is not here */
36718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (NULL);
36728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
36738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
36758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_clean_up_stream_reset(struct sctp_tcb *stcb)
36768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
36778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
36788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *chk = stcb->asoc.str_reset;
36798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb->asoc.str_reset == NULL) {
36818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
36828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc = &stcb->asoc;
36848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo, SCTP_FROM_SCTP_INPUT+SCTP_LOC_26);
36868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_REMOVE(&asoc->control_send_queue,
36878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    chk,
36888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sctp_next);
36898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (chk->data) {
36908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_m_freem(chk->data);
36918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chk->data = NULL;
36928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
36938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	asoc->ctrl_queue_cnt--;
36948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
36958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen        /*sa_ignore NO_NULL_CHK*/
36968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb->asoc.str_reset = NULL;
36978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
36988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
36998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
37008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
37018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_stream_reset_response(struct sctp_tcb *stcb,
3702c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				  uint32_t seq, uint32_t action,
3703c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				  struct sctp_stream_reset_response *respin)
37048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
37058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t type;
37068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int lparm_len;
37078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc = &stcb->asoc;
37088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *chk;
37098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_stream_reset_out_request *srparam;
3710b6a8c974796d76c59ef64a7555e446c9cd171877t	uint32_t number_entries;
37118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
37128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->stream_reset_outstanding == 0) {
37138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* duplicate */
37148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (0);
37158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
37168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (seq == stcb->asoc.str_reset_seq_out) {
37178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		srparam = sctp_find_stream_reset(stcb, seq, &chk);
37188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (srparam) {
37198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.str_reset_seq_out++;
37208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			type = ntohs(srparam->ph.param_type);
37218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			lparm_len = ntohs(srparam->ph.param_length);
37228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (type == SCTP_STR_RESET_OUT_REQUEST) {
37238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				number_entries = (lparm_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t);
37248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asoc->stream_reset_out_is_outstanding = 0;
37258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (asoc->stream_reset_outstanding)
37268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					asoc->stream_reset_outstanding--;
372737d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
37288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* do it */
37298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_reset_out_streams(stcb, number_entries, srparam->list_of_streams);
3730cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3731cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
37328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
37338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
37348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
37358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else if (type == SCTP_STR_RESET_IN_REQUEST) {
37368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Answered my request */
37378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t);
37388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (asoc->stream_reset_outstanding)
37398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					asoc->stream_reset_outstanding--;
3740cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3741cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_IN, stcb,
3742cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen							number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3743cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				} else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
374432a191a90b5c914a02047389c5b3197e08fc9841tuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb,
3745c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen							number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3746c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				}
3747c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			} else if (type == SCTP_STR_RESET_ADD_OUT_STREAMS) {
3748c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				/* Ok we now may have more streams */
3749c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				int num_stream;
3750c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen
3751c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				num_stream = stcb->asoc.strm_pending_add_size;
3752c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				if (num_stream > (stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt)) {
3753c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					/* TSNH */
3754c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					num_stream = stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt;
3755c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				}
3756c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				stcb->asoc.strm_pending_add_size = 0;
3757c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				if (asoc->stream_reset_outstanding)
3758c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					asoc->stream_reset_outstanding--;
375937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
3760c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					/* Put the new streams into effect */
3761c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					stcb->asoc.streamoutcnt += num_stream;
3762c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
3763cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3764cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3765cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_STREAM_CHANGE_DENIED);
3766c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				} else {
376732a191a90b5c914a02047389c5b3197e08fc9841tuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3768cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_STREAM_CHANGE_FAILED);
3769c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				}
3770c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			} else if (type == SCTP_STR_RESET_ADD_IN_STREAMS) {
3771c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				if (asoc->stream_reset_outstanding)
3772c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen					asoc->stream_reset_outstanding--;
3773cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3774cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3775cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_STREAM_CHANGE_DENIED);
3776cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				} else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
377732a191a90b5c914a02047389c5b3197e08fc9841tuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3778cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_STREAM_CHANGE_FAILED);
37798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
37808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else if (type == SCTP_STR_RESET_TSN_REQUEST) {
37818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/**
37828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * a) Adopt the new in tsn.
37838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * b) reset the map
37848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * c) Adopt the new out-tsn
37858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
37868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_stream_reset_response_tsn *resp;
37878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_forward_tsn_chunk fwdtsn;
37888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int abort_flag = 0;
37898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (respin == NULL) {
37908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* huh ? */
37918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (0);
37928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
379337d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
37948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					resp = (struct sctp_stream_reset_response_tsn *)respin;
37958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					asoc->stream_reset_outstanding--;
37968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
37978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
37988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					fwdtsn.new_cumulative_tsn = htonl(ntohl(resp->senders_next_tsn) - 1);
37998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
38008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (abort_flag) {
38018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						return (1);
38028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
38038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.highest_tsn_inside_map = (ntohl(resp->senders_next_tsn) - 1);
38048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
3805c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen						sctp_log_map(0, 7, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
38068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
38078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
38098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
38108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
381132a191a90b5c914a02047389c5b3197e08fc9841tuexen
38128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
38138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
381432a191a90b5c914a02047389c5b3197e08fc9841tuexen
38158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
38168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
38178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
38198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3820cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
3821cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3822cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
3823cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_ASSOC_RESET_DENIED);
3824c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				} else {
3825cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
3826cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen								     SCTP_ASSOC_RESET_FAILED);
38278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
38288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
38298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* get rid of the request and get the request flags */
38308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (asoc->stream_reset_outstanding == 0) {
38318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_clean_up_stream_reset(stcb);
38328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
38338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
38348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
38358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
38368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
38378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
38398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_str_reset_request_in(struct sctp_tcb *stcb,
38408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tmit_chunk *chk,
38418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_stream_reset_in_request *req, int trunc)
38428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
38438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t seq;
38448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int len, i;
38458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int number_entries;
38468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t temp;
38478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
38498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * peer wants me to send a str-reset to him for my outgoing seq's if
38508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * seq_in is right.
38518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
38528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc = &stcb->asoc;
38538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	seq = ntohl(req->request_seq);
38558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->str_reset_seq_in == seq) {
385637d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		asoc->last_reset_action[1] = asoc->last_reset_action[0];
385737d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
385837d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
385937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		} else if (trunc) {
38608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Can't do it, since they exceeded our buffer size  */
386137d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
38628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (stcb->asoc.stream_reset_out_is_outstanding == 0) {
38638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			len = ntohs(req->ph.param_length);
38648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t));
38658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			for (i = 0; i < number_entries; i++) {
38668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				temp = ntohs(req->list_of_streams[i]);
38678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				req->list_of_streams[i] = temp;
38688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
386937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
38708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_add_stream_reset_out(chk, number_entries, req->list_of_streams,
38718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    asoc->str_reset_seq_out,
38728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    seq, (asoc->sending_seq - 1));
38738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->stream_reset_out_is_outstanding = 1;
38748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asoc->str_reset = chk;
38758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
38768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.stream_reset_outstanding++;
38778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
38788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Can't do it, since we have sent one out */
387937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
38808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
3881c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
38828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->str_reset_seq_in++;
38838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (asoc->str_reset_seq_in - 1 == seq) {
38848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
38858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (asoc->str_reset_seq_in - 2 == seq) {
38868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
38878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
388837d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
38898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
38908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
38918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
38928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
38938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
38948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tmit_chunk *chk,
38958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_stream_reset_tsn_request *req)
38968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
38978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* reset all in and out and update the tsn */
38988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
38998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * A) reset my str-seq's on in and out. B) Select a receive next,
39008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * and set cum-ack to it. Also process this selected number as a
39018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * fwd-tsn as well. C) set in the response my next sending seq.
39028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
39038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_forward_tsn_chunk fwdtsn;
39048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc = &stcb->asoc;
39058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int abort_flag = 0;
39068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t seq;
39078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	seq = ntohl(req->request_seq);
39098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->str_reset_seq_in == seq) {
391047674b651417d493ff4e0318113fd7beeef119dbtuexen		asoc->last_reset_action[1] = stcb->asoc.last_reset_action[0];
391137d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
391237d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
391347674b651417d493ff4e0318113fd7beeef119dbtuexen		} else {
391447674b651417d493ff4e0318113fd7beeef119dbtuexen			fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
391547674b651417d493ff4e0318113fd7beeef119dbtuexen			fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
391647674b651417d493ff4e0318113fd7beeef119dbtuexen			fwdtsn.ch.chunk_flags = 0;
391747674b651417d493ff4e0318113fd7beeef119dbtuexen			fwdtsn.new_cumulative_tsn = htonl(stcb->asoc.highest_tsn_inside_map + 1);
391847674b651417d493ff4e0318113fd7beeef119dbtuexen			sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
391947674b651417d493ff4e0318113fd7beeef119dbtuexen			if (abort_flag) {
392047674b651417d493ff4e0318113fd7beeef119dbtuexen				return (1);
392147674b651417d493ff4e0318113fd7beeef119dbtuexen			}
392247674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->highest_tsn_inside_map += SCTP_STREAM_RESET_TSN_DELTA;
392347674b651417d493ff4e0318113fd7beeef119dbtuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
392447674b651417d493ff4e0318113fd7beeef119dbtuexen				sctp_log_map(0, 10, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
392547674b651417d493ff4e0318113fd7beeef119dbtuexen			}
392647674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
392747674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->mapping_array_base_tsn = asoc->highest_tsn_inside_map + 1;
392847674b651417d493ff4e0318113fd7beeef119dbtuexen			memset(asoc->mapping_array, 0, asoc->mapping_array_size);
392947674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
393047674b651417d493ff4e0318113fd7beeef119dbtuexen			memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
393147674b651417d493ff4e0318113fd7beeef119dbtuexen			atomic_add_int(&asoc->sending_seq, 1);
393247674b651417d493ff4e0318113fd7beeef119dbtuexen			/* save off historical data for retrans */
393347674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->last_sending_seq[1] = asoc->last_sending_seq[0];
393447674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->last_sending_seq[0] = asoc->sending_seq;
393547674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0];
393647674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->last_base_tsnsent[0] = asoc->mapping_array_base_tsn;
393747674b651417d493ff4e0318113fd7beeef119dbtuexen			sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
393847674b651417d493ff4e0318113fd7beeef119dbtuexen			sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
393947674b651417d493ff4e0318113fd7beeef119dbtuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
394047674b651417d493ff4e0318113fd7beeef119dbtuexen			sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, (asoc->mapping_array_base_tsn + 1), 0);
394147674b651417d493ff4e0318113fd7beeef119dbtuexen		}
394247674b651417d493ff4e0318113fd7beeef119dbtuexen		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
394347674b651417d493ff4e0318113fd7beeef119dbtuexen		                                 asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
39448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->str_reset_seq_in++;
39458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (asoc->str_reset_seq_in - 1 == seq) {
39468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
394747674b651417d493ff4e0318113fd7beeef119dbtuexen		                                 asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
39488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (asoc->str_reset_seq_in - 2 == seq) {
39498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1],
395047674b651417d493ff4e0318113fd7beeef119dbtuexen		                                 asoc->last_sending_seq[1], asoc->last_base_tsnsent[1]);
39518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
395237d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
39538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
39548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (0);
39558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
39568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
39588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_str_reset_request_out(struct sctp_tcb *stcb,
39598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tmit_chunk *chk,
39608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_stream_reset_out_request *req, int trunc)
39618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
39628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t seq, tsn;
39638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int number_entries, len;
39648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc = &stcb->asoc;
39658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	seq = ntohl(req->request_seq);
39678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* now if its not a duplicate we process it */
39698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->str_reset_seq_in == seq) {
39708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		len = ntohs(req->ph.param_length);
39718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		number_entries = ((len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t));
39728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
39738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * the sender is resetting, handle the list issue.. we must
39748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * a) verify if we can do the reset, if so no problem b) If
39758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * we can't do the reset we must copy the request. c) queue
39768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * it, and setup the data in processor to trigger it off
39778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * when needed and dequeue all the queued data.
39788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
39798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		tsn = ntohl(req->send_reset_at_tsn);
39808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* move the reset action back one */
39828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->last_reset_action[1] = asoc->last_reset_action[0];
398337d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
398437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
398537d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		} else if (trunc) {
398637d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
39878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
39888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* we can do it now */
39898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_reset_in_stream(stcb, number_entries, req->list_of_streams);
399037d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
39918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
39928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
39938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * we must queue it up and thus wait for the TSN's
39948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * to arrive that are at or before tsn
39958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
39968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_reset_list *liste;
39978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			int siz;
39988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
39998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
40008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
40018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    siz, SCTP_M_STRESET);
40028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (liste == NULL) {
40038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* gak out of memory */
400437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
400537d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
40068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return;
40078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
40088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			liste->tsn = tsn;
40098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			liste->number_entries = number_entries;
4010c1f5477d96c0c5178c74caad234035e534c37bdct			memcpy(&liste->list_of_streams, req->list_of_streams, number_entries * sizeof(uint16_t));
40118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp);
401237d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
40138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
4014c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
40158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc->str_reset_seq_in++;
40168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if ((asoc->str_reset_seq_in - 1) == seq) {
40178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
40188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * one seq back, just echo back last action since my
40198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * response was lost.
40208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
40218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
40228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if ((asoc->str_reset_seq_in - 2) == seq) {
40238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
40248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * two seq back, just echo back last action since my
40258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * response was lost.
40268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
40278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
40288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
402937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
40308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
40318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
40328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
40338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
40348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
4035c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			       struct sctp_stream_reset_add_strm  *str_add)
40368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
403737d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	/*
403837d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * Peer is requesting to add more streams.
403937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * If its within our max-streams we will
404037d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * allow it.
404137d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 */
4042c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	uint32_t num_stream, i;
40438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t seq;
40448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc = &stcb->asoc;
40458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_queued_to_read *ctl, *nctl;
40468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
40478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Get the number. */
40488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	seq = ntohl(str_add->request_seq);
40498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	num_stream = ntohs(str_add->number_of_streams);
40508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Now what would be the new total? */
40518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asoc->str_reset_seq_in == seq) {
40528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		num_stream += stcb->asoc.streamincnt;
405337d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
405437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
405537d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
405637d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		} else if ((num_stream > stcb->asoc.max_inbound_streams) ||
4057b6a8c974796d76c59ef64a7555e446c9cd171877t		           (num_stream > 0xffff)) {
40588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* We must reject it they ask for to many */
40598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen  denied:
406037d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
40618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
40628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Ok, we can do that :-) */
40638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_in *oldstrm;
40648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
40658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* save off the old */
40668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			oldstrm = stcb->asoc.strmin;
40678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *,
40688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			            (num_stream * sizeof(struct sctp_stream_in)),
40698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			            SCTP_M_STRMI);
40708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb->asoc.strmin == NULL) {
40718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin = oldstrm;
40728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				goto denied;
40738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
40748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* copy off the old data */
40758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			for (i = 0; i < stcb->asoc.streamincnt; i++) {
40768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
40778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].stream_no = i;
40788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].last_sequence_delivered = oldstrm[i].last_sequence_delivered;
40798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started;
40808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* now anything on those queues? */
40818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_FOREACH_SAFE(ctl, &oldstrm[i].inqueue, next, nctl) {
40828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					TAILQ_REMOVE(&oldstrm[i].inqueue, ctl, next);
40838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].inqueue, ctl, next);
40848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
40858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
40868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Init the new streams */
40878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			for (i = stcb->asoc.streamincnt; i < num_stream; i++) {
40888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
40898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].stream_no = i;
40908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
40918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.strmin[i].delivery_started = 0;
40928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
40938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_FREE(oldstrm, SCTP_M_STRMI);
40948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* update the size */
40958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.streamincnt = num_stream;
409637d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
4097c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
40988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
4099c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
4100c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		asoc->str_reset_seq_in++;
41018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if ((asoc->str_reset_seq_in - 1) == seq) {
41028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
41038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * one seq back, just echo back last action since my
41048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * response was lost.
41058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
41068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
41078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if ((asoc->str_reset_seq_in - 2) == seq) {
41088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
41098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * two seq back, just echo back last action since my
41108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * response was lost.
41118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
41128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
41138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
411437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
41158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
41168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
41178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
41188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
4119c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexenstatic void
4120c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexensctp_handle_str_reset_add_out_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
4121c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				   struct sctp_stream_reset_add_strm  *str_add)
4122c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen{
412337d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	/*
412437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * Peer is requesting to add more streams.
412537d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * If its within our max-streams we will
412637d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 * allow it.
412737d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	 */
4128c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	uint16_t num_stream;
4129c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	uint32_t seq;
4130c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	struct sctp_association *asoc = &stcb->asoc;
4131c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen
4132c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	/* Get the number. */
4133c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	seq = ntohl(str_add->request_seq);
4134c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	num_stream = ntohs(str_add->number_of_streams);
4135c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	/* Now what would be the new total? */
4136c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	if (asoc->str_reset_seq_in == seq) {
413737d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
413837d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
413937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
414037d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		} else if (stcb->asoc.stream_reset_outstanding) {
4141c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			/* We must reject it we have something pending */
414237d37f01a7cf8a44de69d2e65e02191552a3894ctuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
4143c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		} else {
4144c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			/* Ok, we can do that :-) */
4145c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			int mychk;
4146c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			mychk = stcb->asoc.streamoutcnt;
4147c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			mychk += num_stream;
4148c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			if (mychk < 0x10000) {
414937d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
4150c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				if (sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, 1, num_stream, 0, 1)) {
415137d37f01a7cf8a44de69d2e65e02191552a3894ctuexen					stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
4152c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen				}
4153c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			} else {
415437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen				stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
4155c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			}
4156c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		}
4157c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, stcb->asoc.last_reset_action[0]);
4158c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		asoc->str_reset_seq_in++;
4159c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	} else if ((asoc->str_reset_seq_in - 1) == seq) {
4160c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		/*
4161c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 * one seq back, just echo back last action since my
4162c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 * response was lost.
4163c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 */
4164c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
4165c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	} else if ((asoc->str_reset_seq_in - 2) == seq) {
4166c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		/*
4167c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 * two seq back, just echo back last action since my
4168c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 * response was lost.
4169c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		 */
4170c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
4171c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	} else {
417237d37f01a7cf8a44de69d2e65e02191552a3894ctuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
4173c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen	}
4174c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen}
4175c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen
41768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Panda__)
41778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __GNUC__
41788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen__attribute__ ((noinline))
41798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
41808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
41818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int
41828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
418324feb751a6f488d36918e2f333dc2be853c259c8t			 struct sctp_chunkhdr *ch_req)
41848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
41858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int chk_length, param_len, ptype;
41868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_paramhdr pstore;
41878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
418837d37f01a7cf8a44de69d2e65e02191552a3894ctuexen	uint32_t seq = 0;
41898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int num_req = 0;
4190b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	int trunc = 0;
41918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tmit_chunk *chk;
41928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_chunkhdr *ch;
41938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_paramhdr *ph;
41948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int ret_code = 0;
41958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int num_param = 0;
41968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
41978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* now it may be a reset or a reset-response */
419824feb751a6f488d36918e2f333dc2be853c259c8t	chk_length = ntohs(ch_req->chunk_length);
41998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
42008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* setup for adding the response */
42018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_alloc_a_chunk(stcb, chk);
42028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (chk == NULL) {
42038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (ret_code);
42048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
42058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->rec.chunk_id.id = SCTP_STREAM_RESET;
42068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->rec.chunk_id.can_take_data = 0;
42078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->asoc = &stcb->asoc;
42088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->no_fr_allowed = 0;
42098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
42108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->book_size_scale = 0;
421168beeca578347438d9c434680197647ed551935ft	chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
42128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (chk->data == NULL) {
42138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	strres_nochunk:
42148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (chk->data) {
42158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_m_freem(chk->data);
42168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			chk->data = NULL;
42178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
42188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
42198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (ret_code);
42208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
42218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
42228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
42238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* setup chunk parameters */
42248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->sent = SCTP_DATAGRAM_UNSENT;
42258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->snd_count = 0;
42268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chk->whoTo = NULL;
42278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
42288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	ch = mtod(chk->data, struct sctp_chunkhdr *);
42298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	ch->chunk_type = SCTP_STREAM_RESET;
42308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	ch->chunk_flags = 0;
42318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	ch->chunk_length = htons(chk->send_size);
42328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
42338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	offset += sizeof(struct sctp_chunkhdr);
42348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) {
42358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *)&pstore);
42368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ph == NULL)
42378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
42388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		param_len = ntohs(ph->param_length);
42398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) {
42408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* bad param */
42418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
42428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
42438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)),
42448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							   (uint8_t *)&cstore);
42458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ptype = ntohs(ph->param_type);
42468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		num_param++;
42478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (param_len > (int)sizeof(cstore)) {
42488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			trunc = 1;
42498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
42508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			trunc = 0;
42518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
42528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (num_param > SCTP_MAX_RESET_PARAMS) {
42538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* hit the max of parameters already sorry.. */
42548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
42558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
42568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
42578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_reset_out_request *req_out;
42588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			req_out = (struct sctp_stream_reset_out_request *)ph;
42598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			num_req++;
42608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb->asoc.stream_reset_outstanding) {
42618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				seq = ntohl(req_out->response_seq);
42628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (seq == stcb->asoc.str_reset_seq_out) {
42638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* implicit ack */
426437d37f01a7cf8a44de69d2e65e02191552a3894ctuexen					(void)sctp_handle_stream_reset_response(stcb, seq, SCTP_STREAM_RESET_RESULT_PERFORMED, NULL);
42658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
42668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
42678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_handle_str_reset_request_out(stcb, chk, req_out, trunc);
4268c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
4269c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			struct sctp_stream_reset_add_strm  *str_add;
4270c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			str_add = (struct sctp_stream_reset_add_strm  *)ph;
4271c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			num_req++;
4272c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
4273c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
4274c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			struct sctp_stream_reset_add_strm  *str_add;
4275c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			str_add = (struct sctp_stream_reset_add_strm  *)ph;
4276c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			num_req++;
4277c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
42788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (ptype == SCTP_STR_RESET_IN_REQUEST) {
42798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_reset_in_request *req_in;
42808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			num_req++;
42818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			req_in = (struct sctp_stream_reset_in_request *)ph;
42828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_handle_str_reset_request_in(stcb, chk, req_in, trunc);
42838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (ptype == SCTP_STR_RESET_TSN_REQUEST) {
42848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_reset_tsn_request *req_tsn;
42858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			num_req++;
42868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			req_tsn = (struct sctp_stream_reset_tsn_request *)ph;
42878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_str_reset_request_tsn(stcb, chk, req_tsn)) {
42888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ret_code = 1;
42898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				goto strres_nochunk;
42908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
42918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* no more */
42928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
42938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (ptype == SCTP_STR_RESET_RESPONSE) {
42948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_stream_reset_response *resp;
42958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			uint32_t result;
42968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			resp = (struct sctp_stream_reset_response *)ph;
42978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			seq = ntohl(resp->response_seq);
42988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			result = ntohl(resp->result);
42998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (sctp_handle_stream_reset_response(stcb, seq, result, resp)) {
43008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ret_code = 1;
43018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				goto strres_nochunk;
43028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
43038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
43048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
43058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
43068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		offset += SCTP_SIZE32(param_len);
43078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chk_length -= SCTP_SIZE32(param_len);
43088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
43098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (num_req == 0) {
43108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* we have no response free the stuff */
43118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto strres_nochunk;
43128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
43138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* ok we have a chunk to link in */
43148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue,
4315c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			  chk,
4316c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen			  sctp_next);
43178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	stcb->asoc.ctrl_queue_cnt++;
43188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (ret_code);
43198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
43208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
43218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
43228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Handle a router or endpoints report of a packet loss, there are two ways
43238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to handle this, either we get the whole packet and must disect it
43248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ourselves (possibly with truncation and or corruption) or it is a summary
43258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * from a middle box that did the disectting for us.
43268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
43278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
43288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
43298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t limit)
43308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
43318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t bottle_bw, on_queue;
43328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t trunc_len;
43338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int chlen;
43348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	unsigned int at;
43358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_chunk_desc desc;
43368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_chunkhdr *ch;
43378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
43388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chlen = ntohs(cp->ch.chunk_length);
43398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	chlen -= sizeof(struct sctp_pktdrop_chunk);
43408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* XXX possible chlen underflow */
43418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (chlen == 0) {
43428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ch = NULL;
43438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX)
43448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrpbwrpt);
43458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
43468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ch = (struct sctp_chunkhdr *)(cp->data + sizeof(struct sctphdr));
43478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chlen -= sizeof(struct sctphdr);
43488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* XXX possible chlen underflow */
43498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		memset(&desc, 0, sizeof(desc));
43508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
43518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	trunc_len = (uint16_t) ntohs(cp->trunc_len);
43528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (trunc_len > limit) {
43538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		trunc_len = limit;
43548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
43558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
43568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* now the chunks themselves */
43578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	while ((ch != NULL) && (chlen >= sizeof(struct sctp_chunkhdr))) {
43588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		desc.chunk_type = ch->chunk_type;
43598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* get amount we need to move */
43608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		at = ntohs(ch->chunk_length);
43618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (at < sizeof(struct sctp_chunkhdr)) {
43628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* corrupt chunk, maybe at the end? */
43638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrpcrupt);
43648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
43658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
43668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (trunc_len == 0) {
43678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* we are supposed to have all of it */
43688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (at > chlen) {
43698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* corrupt skip it */
43708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpcrupt);
43718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
43728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
43738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
43748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* is there enough of it left ? */
43758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (desc.chunk_type == SCTP_DATA) {
43768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chlen < (sizeof(struct sctp_data_chunk) +
43778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    sizeof(desc.data_bytes))) {
43788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
43798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
43808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
43818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chlen < sizeof(struct sctp_chunkhdr)) {
43828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
43838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
43848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
43858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
43868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (desc.chunk_type == SCTP_DATA) {
43878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* can we get out the tsn? */
43888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
43898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpmbda);
43908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
43918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chlen >= (sizeof(struct sctp_data_chunk) + sizeof(uint32_t))) {
43928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* yep */
43938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_data_chunk *dcp;
43948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint8_t *ddp;
43958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				unsigned int iii;
43968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
43978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				dcp = (struct sctp_data_chunk *)ch;
43988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ddp = (uint8_t *) (dcp + 1);
43998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				for (iii = 0; iii < sizeof(desc.data_bytes); iii++) {
44008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					desc.data_bytes[iii] = ddp[iii];
44018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
44028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				desc.tsn_ifany = dcp->dp.tsn;
44038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
44048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* nope we are done. */
44058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpnedat);
44068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				break;
44078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
44088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
44098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
44108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_pdrpmbct);
44118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
44128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (process_chunk_drop(stcb, &desc, net, cp->ch.chunk_flags)) {
44148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_pdrppdbrk);
44158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
44168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
44178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_SIZE32(at) > chlen) {
44188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
44198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
44208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chlen -= SCTP_SIZE32(at);
44218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (chlen < sizeof(struct sctp_chunkhdr)) {
44228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* done, none left */
44238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
44248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
44258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ch = (struct sctp_chunkhdr *)((caddr_t)ch + SCTP_SIZE32(at));
44268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
44278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Now update any rwnd --- possibly */
44288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) == 0) {
44298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* From a peer, we get a rwnd report */
44308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		uint32_t a_rwnd;
44318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_pdrpfehos);
44338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		bottle_bw = ntohl(cp->bottle_bw);
44358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		on_queue = ntohl(cp->current_onq);
44368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (bottle_bw && on_queue) {
44378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* a rwnd report is in here */
44388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (bottle_bw > on_queue)
44398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				a_rwnd = bottle_bw - on_queue;
44408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			else
44418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				a_rwnd = 0;
44428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (a_rwnd == 0)
44448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.peers_rwnd = 0;
44458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			else {
44468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (a_rwnd > stcb->asoc.total_flight) {
44478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.peers_rwnd =
44488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					    a_rwnd - stcb->asoc.total_flight;
44498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
44508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.peers_rwnd = 0;
44518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
44528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb->asoc.peers_rwnd <
44538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
44548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* SWS sender side engages */
44558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.peers_rwnd = 0;
44568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
44578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
44588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
44598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
44608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_pdrpfmbox);
44618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
44628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* now middle boxes in sat networks get a cwnd bump */
44648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) &&
44658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (stcb->asoc.sat_t3_loss_recovery == 0) &&
44668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (stcb->asoc.sat_network)) {
44678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
44688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * This is debateable but for sat networks it makes sense
44698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * Note if a T3 timer has went off, we will prohibit any
44708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * changes to cwnd until we exit the t3 loss recovery.
44718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
44728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped(stcb,
44738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			net, cp, &bottle_bw, &on_queue);
44748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
44758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
44768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
44778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
44788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * handles all control chunks in a packet inputs: - m: mbuf chain, assumed to
44798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * still contain IP/SCTP header - stcb: is the tcb found for this packet -
44808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * offset: offset into the mbuf chain to first chunkhdr - length: is the
44818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * length of the complete packet outputs: - length: modified to remaining
44828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * length after control processing - netp: modified to new sctp_nets after
44838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * cookie-echo processing - return NULL to discard the packet (ie. no asoc,
44848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad packet,...) otherwise return the tcb for this packet
44858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
44868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Panda__)
44878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __GNUC__
44888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen__attribute__ ((noinline))
44898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
44908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
44918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic struct sctp_tcb *
44928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
4493e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen    struct sockaddr *src, struct sockaddr *dst,
44948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp,
44958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen,
449651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
449751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen    uint8_t use_mflowid, uint32_t mflowid,
449851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
44998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen    uint32_t vrf_id, uint16_t port)
45008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
45018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_association *asoc;
45028f9e45fea288542b24a6bda01269c6fc184d991at	struct mbuf *op_err;
45038f9e45fea288542b24a6bda01269c6fc184d991at	char msg[SCTP_DIAG_INFO_LEN];
45048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t vtag_in;
45058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int num_chunks = 0;	/* number of control chunks processed */
45068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t chk_length;
45078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int ret;
45088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int abort_no_unlock = 0;
45098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int ecne_seen = 0;
45108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
45118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * How big should this be, and should it be alloc'd? Lets try the
45128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * d-mtu-ceiling for now (2k) and that should hopefully work ...
45138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * until we get into jumbo grams and such..
45148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
45158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t chunk_buf[SCTP_CHUNK_BUFFER_SIZE];
45168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tcb *locked_tcb = stcb;
45178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int got_auth = 0;
45188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t auth_offset = 0, auth_len = 0;
45198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int auth_skipped = 0;
45208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int asconf_cnt = 0;
45210612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
45228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct socket *so;
45238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
45248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
45258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_process_control: iphlen=%u, offset=%u, length=%u stcb:%p\n",
4526ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t		iphlen, *offset, length, (void *)stcb);
45278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
45288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* validate chunk header length... */
45298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ntohs(ch->chunk_length) < sizeof(*ch)) {
45308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "Invalid header length %d\n",
45318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ntohs(ch->chunk_length));
45328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (locked_tcb) {
45338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_TCB_UNLOCK(locked_tcb);
45348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
45358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return (NULL);
45368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
45378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
45388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * validate the verification tag
45398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
45408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	vtag_in = ntohl(sh->v_tag);
45418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
45428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (locked_tcb) {
45438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_TCB_LOCK_ASSERT(locked_tcb);
45448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
45458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (ch->chunk_type == SCTP_INITIATION) {
45468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "Its an INIT of len:%d vtag:%x\n",
45478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ntohs(ch->chunk_length), vtag_in);
45488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (vtag_in != 0) {
45498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* protocol error- silently discard... */
45508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_badvtag);
45518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
45528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
45538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
45548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
45558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
45568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (ch->chunk_type != SCTP_COOKIE_ECHO) {
45578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
45588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * If there is no stcb, skip the AUTH chunk and process
45598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * later after a stcb is found (to validate the lookup was
45608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * valid.
45618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
45628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((ch->chunk_type == SCTP_AUTHENTICATION) &&
45638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (stcb == NULL) &&
4564fb3816eaffe5878bb1286adb120fd160da178a05t		    (inp->auth_supported == 1)) {
45658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* save this chunk for later processing */
45668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			auth_skipped = 1;
45678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			auth_offset = *offset;
45688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			auth_len = ntohs(ch->chunk_length);
45698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
45708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* (temporarily) move past this chunk */
45718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset += SCTP_SIZE32(auth_len);
45728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (*offset >= length) {
45738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* no more data left in the mbuf chain */
45748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
45758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
45768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
45778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
45788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
45798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
45808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
45818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								   sizeof(struct sctp_chunkhdr), chunk_buf);
45828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
45838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ch == NULL) {
45848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* Help */
45858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
45868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
45878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
45888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
45898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
45908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
45918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ch->chunk_type == SCTP_COOKIE_ECHO) {
45928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			goto process_control_chunks;
45938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
45948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
45958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * first check if it's an ASCONF with an unknown src addr we
45968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * need to look inside to find the association
45978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
45988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ch->chunk_type == SCTP_ASCONF && stcb == NULL) {
45998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			struct sctp_chunkhdr *asconf_ch = ch;
46008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			uint32_t asconf_offset = 0, asconf_len = 0;
46018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
46028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* inp's refcount may be reduced */
46038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_INP_INCR_REF(inp);
46048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
46058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			asconf_offset = *offset;
46068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			do {
46078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asconf_len = ntohs(asconf_ch->chunk_length);
46088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (asconf_len < sizeof(struct sctp_asconf_paramhdr))
46098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
46100ac02f34d6041cd0018437596a5a9a94685e6919tuexen				stcb = sctp_findassociation_ep_asconf(m,
4611e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				                                      *offset,
4612e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				                                      dst,
4613e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				                                      sh, &inp, netp, vrf_id);
46148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb != NULL)
46158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
46168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asconf_offset += SCTP_SIZE32(asconf_len);
46178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asconf_ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, asconf_offset,
46188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen										  sizeof(struct sctp_chunkhdr), chunk_buf);
46198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} while (asconf_ch != NULL && asconf_ch->chunk_type == SCTP_ASCONF);
46208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb == NULL) {
46218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
46228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * reduce inp's refcount if not reduced in
46238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * sctp_findassociation_ep_asconf().
46248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
46258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_INP_DECR_REF(inp);
46268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
46278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				locked_tcb = stcb;
46288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
46298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
46308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* now go back and verify any auth chunk to be sure */
46318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (auth_skipped && (stcb != NULL)) {
46328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_auth_chunk *auth;
46338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
46348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				auth = (struct sctp_auth_chunk *)
46358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_m_getptr(m, auth_offset,
46368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						      auth_len, chunk_buf);
46378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				got_auth = 1;
46388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				auth_skipped = 0;
46398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((auth == NULL) || sctp_handle_auth(stcb, auth, m,
46408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								       auth_offset)) {
46418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* auth HMAC failed so dump it */
46428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
46438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (locked_tcb) {
46448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(locked_tcb);
46458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
46468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
46478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
46488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* remaining chunks are HMAC checked */
46498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.authenticated = 1;
46508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
46518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
46528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
46538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb == NULL) {
46548f9e45fea288542b24a6bda01269c6fc184d991at			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
46558f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
46568f9e45fea288542b24a6bda01269c6fc184d991at			                             msg);
46578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* no association, so it's out of the blue... */
46588f9e45fea288542b24a6bda01269c6fc184d991at			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
465951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
466051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 use_mflowid, mflowid,
466151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
46628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 vrf_id, port);
46638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
46648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
46658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
46668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
46678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
46688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
46698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		asoc = &stcb->asoc;
46708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* ABORT and SHUTDOWN can use either v_tag... */
46718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) ||
46728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) ||
46738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (ch->chunk_type == SCTP_PACKET_DROPPED)) {
467484a42e7150ac17acef0963810b547fbc3b4b8ac1t			/* Take the T-bit always into account. */
467584a42e7150ac17acef0963810b547fbc3b4b8ac1t			if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) &&
467684a42e7150ac17acef0963810b547fbc3b4b8ac1t			     (vtag_in == asoc->my_vtag)) ||
467784a42e7150ac17acef0963810b547fbc3b4b8ac1t			    (((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) &&
46788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			     (vtag_in == asoc->peer_vtag))) {
46798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* this is valid */
46808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
46818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* drop this packet... */
46828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_badvtag);
46838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
46848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
46858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
46868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
46878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
46888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
46898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (vtag_in != asoc->my_vtag) {
46908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
46918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * this could be a stale SHUTDOWN-ACK or the
46928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * peer never got the SHUTDOWN-COMPLETE and
46938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * is still hung; we have started a new asoc
46948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * but it won't complete until the shutdown
46958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * is completed
46968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
46978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
46988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
46998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
47008f9e45fea288542b24a6bda01269c6fc184d991at				snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
47018f9e45fea288542b24a6bda01269c6fc184d991at				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
47028f9e45fea288542b24a6bda01269c6fc184d991at				                             msg);
4703e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				sctp_handle_ootb(m, iphlen, *offset, src, dst,
47048f9e45fea288542b24a6bda01269c6fc184d991at				                 sh, inp, op_err,
470551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
470651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                 use_mflowid, mflowid,
470751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
4708eab8290432042d40f3c599ebfb67890c39d16556tuexen				                 vrf_id, port);
47098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
47108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
47118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
47128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* for all other chunks, vtag must match */
47138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (vtag_in != asoc->my_vtag) {
47148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* invalid vtag... */
47158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT3,
47168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					"invalid vtag: %xh, expect %xh\n",
47178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					vtag_in, asoc->my_vtag);
47188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_badvtag);
47198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
47208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
47218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
47228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
47238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
47248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
47258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
47268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}			/* end if !SCTP_COOKIE_ECHO */
47278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
47288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * process all control chunks...
47298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
47308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (((ch->chunk_type == SCTP_SELECTIVE_ACK) ||
473123273859c39742f09cc5ec7c9bf32ff225661e82tuexen	     (ch->chunk_type == SCTP_NR_SELECTIVE_ACK) ||
473223273859c39742f09cc5ec7c9bf32ff225661e82tuexen	     (ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
47338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
47348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* implied cookie-ack.. we must have lost the ack */
47358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
47368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
47378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       stcb->asoc.overall_error_count,
47388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       0,
47398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       SCTP_FROM_SCTP_INPUT,
47408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       __LINE__);
47418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
47428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.overall_error_count = 0;
47438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb,
47448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				       *netp);
47458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
47468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
47478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen process_control_chunks:
47488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	while (IS_SCTP_CONTROL(ch)) {
47498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* validate chunk length */
47508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		chk_length = ntohs(ch->chunk_length);
47518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_process_control: processing a chunk type=%u, len=%u\n",
47528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ch->chunk_type, chk_length);
47538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_LTRACE_CHK(inp, stcb, ch->chunk_type, chk_length);
47548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (chk_length < sizeof(*ch) ||
47558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (*offset + (int)chk_length) > length) {
47568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
47578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
47588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
47598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
47608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
47618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
47628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR_COUNTER64(sctps_incontrolchunks);
47638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
47648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * INIT-ACK only gets the init ack "header" portion only
47658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * because we don't have to process the peer's COOKIE. All
47668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * others get a complete chunk.
47678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
47688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((ch->chunk_type == SCTP_INITIATION_ACK) ||
47698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (ch->chunk_type == SCTP_INITIATION)) {
47708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* get an init-ack chunk */
47718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
47728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								   sizeof(struct sctp_init_ack_chunk), chunk_buf);
47738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (ch == NULL) {
47748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
47758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
47768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
47778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
47788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
47798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
47808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
47818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* For cookies and all other chunks. */
47828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk_length > sizeof(chunk_buf)) {
47838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
47848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * use just the size of the chunk buffer
47858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * so the front part of our chunks fit in
47868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * contiguous space up to the chunk buffer
47878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * size (508 bytes).
47888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * For chunks that need to get more than that
47898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * they must use the sctp_m_getptr() function
47908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * or other means (e.g. know how to parse mbuf
47918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * chains). Cookies do this already.
47928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
47938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
47948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen									   (sizeof(chunk_buf) - 4),
47958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen									   chunk_buf);
47968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (ch == NULL) {
47978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
47988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (locked_tcb) {
47998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(locked_tcb);
48008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
48018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
48028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
48038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
48048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* We can fit it all */
48058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
48068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								   chk_length, chunk_buf);
48078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (ch == NULL) {
48088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_PRINTF("sctp_process_control: Can't get the all data....\n");
48098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
48108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (locked_tcb) {
48118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(locked_tcb);
48128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
48138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
48148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
48158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
48168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
48178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		num_chunks++;
48188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Save off the last place we got a control from */
48198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb != NULL) {
48208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (((netp != NULL) && (*netp != NULL)) || (ch->chunk_type == SCTP_ASCONF)) {
48218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/*
48228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * allow last_control to be NULL if
48238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * ASCONF... ASCONF processing will find the
48248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 * right net later
48258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				 */
48268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((netp != NULL) && (*netp != NULL))
48278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.last_control_chunk_from = *netp;
48288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
48298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
48308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED
48318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_audit_log(0xB0, ch->chunk_type);
48328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
48338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
48348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* check to see if this chunk required auth, but isn't */
48358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb != NULL) &&
4836fb3816eaffe5878bb1286adb120fd160da178a05t		    (stcb->asoc.auth_supported == 1) &&
48378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) &&
48388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    !stcb->asoc.authenticated) {
48398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* "silently" ignore */
48408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_recvauthmissing);
48418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			goto next_chunk;
48428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
48438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		switch (ch->chunk_type) {
48448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_INITIATION:
48458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT\n");
484623273859c39742f09cc5ec7c9bf32ff225661e82tuexen			/* The INIT chunk must be the only chunk. */
484723273859c39742f09cc5ec7c9bf32ff225661e82tuexen			if ((num_chunks > 1) ||
484823273859c39742f09cc5ec7c9bf32ff225661e82tuexen			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
48498f9e45fea288542b24a6bda01269c6fc184d991at				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
48508f9e45fea288542b24a6bda01269c6fc184d991at				                             "INIT not the only chunk");
4851e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				sctp_abort_association(inp, stcb, m, iphlen,
48528f9e45fea288542b24a6bda01269c6fc184d991at				                       src, dst, sh, op_err,
485351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
485451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       use_mflowid, mflowid,
485551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
485651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       vrf_id, port);
48578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
48588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
48598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
486023273859c39742f09cc5ec7c9bf32ff225661e82tuexen			/* Honor our resource limit. */
486123273859c39742f09cc5ec7c9bf32ff225661e82tuexen			if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
48628f9e45fea288542b24a6bda01269c6fc184d991at				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
4863e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				sctp_abort_association(inp, stcb, m, iphlen,
4864e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						       src, dst, sh, op_err,
486551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
486651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       use_mflowid, mflowid,
486751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
486851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                       vrf_id, port);
48698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
48708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
48718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
4872e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen			sctp_handle_init(m, iphlen, *offset, src, dst, sh,
487323273859c39742f09cc5ec7c9bf32ff225661e82tuexen			                 (struct sctp_init_chunk *)ch, inp,
487451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 stcb, &abort_no_unlock,
487551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
487651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 use_mflowid, mflowid,
487751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
487851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 vrf_id, port);
48798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
488023273859c39742f09cc5ec7c9bf32ff225661e82tuexen			if ((!abort_no_unlock) && (locked_tcb)) {
48818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
48828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
48838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
48848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
48858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_PAD_CHUNK:
48868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
48878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_INITIATION_ACK:
48888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n");
48898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
48908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* We are not interested anymore */
4891e2828360ea9cf8951730d46f5c14626c9425cb30t				if ((stcb) && (stcb->asoc.total_output_queue_size)) {
48928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					;
48938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
48948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (locked_tcb != stcb) {
48958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						/* Very unlikely */
48968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(locked_tcb);
48978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
48988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
48998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (stcb) {
49000612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
49018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						so = SCTP_INP_SO(inp);
49028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						atomic_add_int(&stcb->asoc.refcnt, 1);
49038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(stcb);
49048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_SOCKET_LOCK(so, 1);
49058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_LOCK(stcb);
49068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						atomic_subtract_int(&stcb->asoc.refcnt, 1);
49078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
49088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_27);
49090612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
49108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_SOCKET_UNLOCK(so, 1);
49118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
49128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
49138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
49148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
491623273859c39742f09cc5ec7c9bf32ff225661e82tuexen			/* The INIT-ACK chunk must be the only chunk. */
49178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((num_chunks > 1) ||
491823273859c39742f09cc5ec7c9bf32ff225661e82tuexen			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
49198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
49208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
49218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
49228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
49248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
49258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((netp) && (*netp)) {
4926e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				ret = sctp_handle_init_ack(m, iphlen, *offset,
4927e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				                           src, dst, sh,
4928e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				                           (struct sctp_init_ack_chunk *)ch,
492951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                           stcb, *netp,
493051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                           &abort_no_unlock,
493151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
493251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                           use_mflowid, mflowid,
493351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
493451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen				                           vrf_id);
49358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
49368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ret = -1;
49378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
493823273859c39742f09cc5ec7c9bf32ff225661e82tuexen			*offset = length;
493923273859c39742f09cc5ec7c9bf32ff225661e82tuexen			if (abort_no_unlock) {
494023273859c39742f09cc5ec7c9bf32ff225661e82tuexen				return (NULL);
494123273859c39742f09cc5ec7c9bf32ff225661e82tuexen			}
49428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
49438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * Special case, I must call the output routine to
49448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * get the cookie echoed
49458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
494623273859c39742f09cc5ec7c9bf32ff225661e82tuexen			if ((stcb != NULL) && (ret == 0)) {
49478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
494823273859c39742f09cc5ec7c9bf32ff225661e82tuexen			}
49498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
49508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
49518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
49528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
49538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
49548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_SELECTIVE_ACK:
49558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			{
49568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_sack_chunk *sack;
49578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int abort_now = 0;
49588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint32_t a_rwnd, cum_ack;
49598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint16_t num_seg, num_dup;
49608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint8_t flags;
49618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int offset_seg, offset_dup;
49628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
49638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
49648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_recvsacks);
49658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb == NULL) {
49668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
49678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
49688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chk_length < sizeof(struct sctp_sack_chunk)) {
49708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
49718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
49728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
49748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*-
49758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * If we have sent a shutdown-ack, we will pay no
49768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * attention to a sack sent in to us since
49778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * we don't care anymore.
49788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
49798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
49808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sack = (struct sctp_sack_chunk *)ch;
49828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				flags = ch->chunk_flags;
49838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				cum_ack = ntohl(sack->sack.cum_tsn_ack);
49848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				num_seg = ntohs(sack->sack.num_gap_ack_blks);
49858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				num_dup = ntohs(sack->sack.num_dup_tsns);
49868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				a_rwnd = (uint32_t) ntohl(sack->sack.a_rwnd);
49878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (sizeof(struct sctp_sack_chunk) +
49888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    num_seg * sizeof(struct sctp_gap_ack_block) +
49898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    num_dup * sizeof(uint32_t) != chk_length) {
49908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
49918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
49928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
49938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				offset_seg = *offset + sizeof(struct sctp_sack_chunk);
49948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
49958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
49968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				        cum_ack, num_seg, a_rwnd);
49978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.seen_a_sack_this_pkt = 1;
49988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((stcb->asoc.pr_sctp_cnt == 0) &&
49998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (num_seg == 0) &&
5000b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen				    SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
50018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.saw_sack_with_frags == 0) &&
50028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.saw_sack_with_nr_frags == 0) &&
50038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))
50048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					) {
50058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* We have a SIMPLE sack having no prior segments and
50068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * data on sent queue to be acked.. Use the faster
50078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * path sack processing. We also allow window update
50088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * sacks with no missing segments to go this way too.
50098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
50108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now, ecne_seen);
50118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
50128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (netp && *netp)
50130ac02f34d6041cd0018437596a5a9a94685e6919tuexen						sctp_handle_sack(m, offset_seg, offset_dup, stcb,
50148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								 num_seg, 0, num_dup, &abort_now, flags,
50158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								 cum_ack, a_rwnd, ecne_seen);
50168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (abort_now) {
50188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* ABORT signal from sack processing */
50198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
50208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
50218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
50238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
50248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.stream_queue_cnt == 0)) {
50258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb,  0, NULL, SCTP_SO_NOT_LOCKED);
50268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
50288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
50298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* EY - nr_sack:  If the received chunk is an nr_sack chunk */
50308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_NR_SELECTIVE_ACK:
50318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			{
50328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_nr_sack_chunk *nr_sack;
50338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int abort_now = 0;
50348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint32_t a_rwnd, cum_ack;
50358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint16_t num_seg, num_nr_seg, num_dup;
50368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				uint8_t flags;
50378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int offset_seg, offset_dup;
50388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
50398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
50408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_recvsacks);
50418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb == NULL) {
50428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
50438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
50448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
504544318e900a771ba1a5bafb510c38f33fd5cd8a39t				if (stcb->asoc.nrsack_supported == 0) {
50468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					goto unknown_chunk;
50478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
50498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR-SACK chunk, too small\n");
50508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
50518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
50538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*-
50548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * If we have sent a shutdown-ack, we will pay no
50558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * attention to a sack sent in to us since
50568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * we don't care anymore.
50578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
50588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
50598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				nr_sack = (struct sctp_nr_sack_chunk *)ch;
50618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				flags = ch->chunk_flags;
50628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
50638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
50648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
50658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
50668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				a_rwnd = (uint32_t) ntohl(nr_sack->nr_sack.a_rwnd);
50678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (sizeof(struct sctp_nr_sack_chunk) +
50688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
50698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    num_dup * sizeof(uint32_t) != chk_length) {
50708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
50718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					break;
50728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
50738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
50748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
50758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
50768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				        cum_ack, num_seg, a_rwnd);
50778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.seen_a_sack_this_pkt = 1;
50788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((stcb->asoc.pr_sctp_cnt == 0) &&
50798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (num_seg == 0) && (num_nr_seg == 0) &&
50808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
50818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.saw_sack_with_frags == 0) &&
50828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.saw_sack_with_nr_frags == 0) &&
50838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
50848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*
50858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * We have a SIMPLE sack having no
50868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * prior segments and data on sent
50878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * queue to be acked. Use the
50888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * faster path sack processing. We
50898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * also allow window update sacks
50908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * with no missing segments to go
50918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * this way too.
50928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
50938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_express_handle_sack(stcb, cum_ack, a_rwnd,
50948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					                         &abort_now, ecne_seen);
50958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
50968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (netp && *netp)
50970ac02f34d6041cd0018437596a5a9a94685e6919tuexen						sctp_handle_sack(m, offset_seg, offset_dup, stcb,
50988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						                 num_seg, num_nr_seg, num_dup, &abort_now, flags,
50998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						                 cum_ack, a_rwnd, ecne_seen);
51008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (abort_now) {
51028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* ABORT signal from sack processing */
51038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
51048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
51058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
51078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
51088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (stcb->asoc.stream_queue_cnt == 0)) {
51098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb,  0, NULL, SCTP_SO_NOT_LOCKED);
51108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
51148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_HEARTBEAT_REQUEST:
51158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT\n");
51168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp) {
51178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_STAT_INCR(sctps_recvheartbeat);
51188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_send_heartbeat_ack(stcb, m, *offset,
51198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							chk_length, *netp);
51208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
51218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* He's alive so give him credit */
51228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
51238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
51248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
51258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
51268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
51278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
51288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
51308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_HEARTBEAT_ACK:
51338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT-ACK\n");
51348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_heartbeat_chunk))) {
51358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
51368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
51378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
51388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
51398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
51418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
51438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
51448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
51458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       stcb->asoc.overall_error_count,
51468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       0,
51478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       SCTP_FROM_SCTP_INPUT,
51488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       __LINE__);
51498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.overall_error_count = 0;
51518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_recvheartbeatack);
51528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (netp && *netp)
51538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_heartbeat_ack((struct sctp_heartbeat_chunk *)ch,
51548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							  stcb, *netp);
51558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_ABORT_ASSOCIATION:
51578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n",
5158ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t				(void *)stcb);
51598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp)
51608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_abort((struct sctp_abort_chunk *)ch,
51618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						  stcb, *netp);
51628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
51638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
51648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_SHUTDOWN:
51668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN, stcb %p\n",
5167ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t				(void *)stcb);
51688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_shutdown_chunk))) {
51698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
51708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
51718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
51728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
51748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (netp && *netp) {
51768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int abort_flag = 0;
51778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
51788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_shutdown((struct sctp_shutdown_chunk *)ch,
51798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						     stcb, *netp, &abort_flag);
51808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (abort_flag) {
51818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
51828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
51838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
51848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
51858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_SHUTDOWN_ACK:
5187ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK, stcb %p\n", (void *)stcb);
51888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && (netp) && (*netp))
51898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_shutdown_ack((struct sctp_shutdown_ack_chunk *)ch, stcb, *netp);
51908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
51918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
51928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
51938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
51948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_OPERATION_ERROR:
51958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_OP-ERR\n");
51968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp && sctp_handle_error(ch, stcb, *netp) < 0) {
51978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
51988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
51998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
52008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
52018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_COOKIE_ECHO:
52028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3,
5203ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t				"SCTP_COOKIE-ECHO, stcb %p\n", (void *)stcb);
52048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && (stcb->asoc.total_output_queue_size)) {
52058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				;
52068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
52078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
52088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* We are not interested anymore */
52098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				abend:
52108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (stcb) {
52118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(stcb);
52128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
52138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
52148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
52158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
52178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
52188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * First are we accepting? We do this again here
52198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * since it is possible that a previous endpoint WAS
52208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * listening responded to a INIT-ACK and then
52218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * closed. We opened and bound.. and are now no
52228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * longer listening.
52238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
52248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
52258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
52268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
52278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				    (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
52288f9e45fea288542b24a6bda01269c6fc184d991at					op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
5229e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen					sctp_abort_association(inp, stcb, m, iphlen,
5230e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen					                       src, dst, sh, op_err,
523151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
523251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen					                       use_mflowid, mflowid,
523351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
523451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen					                       vrf_id, port);
52358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
52378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
52388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
52398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct mbuf *ret_buf;
52408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_inpcb *linp;
52418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (stcb) {
52428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					linp = NULL;
52438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
52448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					linp = inp;
52458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
52478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (linp) {
52488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_ASOC_CREATE_LOCK(linp);
52498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
52508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
52518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_ASOC_CREATE_UNLOCK(linp);
52528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						goto abend;
52538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
52548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
52568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (netp) {
52578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					ret_buf =
52588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_handle_cookie_echo(m, iphlen,
5259e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        *offset,
5260e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        src, dst,
5261e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        sh,
5262e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        (struct sctp_cookie_echo_chunk *)ch,
5263e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        &inp, &stcb, netp,
5264e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        auth_skipped,
5265e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        auth_offset,
5266e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        auth_len,
5267e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        &locked_tcb,
526851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
526951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen						                        use_mflowid,
527051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen						                        mflowid,
527151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
5272e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        vrf_id,
5273e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen						                        port);
52748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
52758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					ret_buf = NULL;
52768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (linp) {
52788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_ASOC_CREATE_UNLOCK(linp);
52798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (ret_buf == NULL) {
52818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (locked_tcb) {
52828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						SCTP_TCB_UNLOCK(locked_tcb);
52838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
52848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTPDBG(SCTP_DEBUG_INPUT3,
52858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						"GAK, null buffer\n");
52868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
52878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
52888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* if AUTH skipped, see if it verified... */
52908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (auth_skipped) {
52918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					got_auth = 1;
52928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					auth_skipped = 0;
52938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
52948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
52958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*
52968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * Restart the timer if we have
52978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * pending data
52988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
52998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					struct sctp_tmit_chunk *chk;
53008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
53018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
53028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
53038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
53068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_COOKIE_ACK:
5307ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", (void *)stcb);
53088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) {
53098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
53108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
53118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
53138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
53158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* We are not interested anymore */
53168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if ((stcb) && (stcb->asoc.total_output_queue_size)) {
53178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					;
53188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else if (stcb) {
53190612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
53208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					so = SCTP_INP_SO(inp);
53218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_add_int(&stcb->asoc.refcnt, 1);
53228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(stcb);
53238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_LOCK(so, 1);
53248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_LOCK(stcb);
53258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_subtract_int(&stcb->asoc.refcnt, 1);
53268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
53278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_27);
53280612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
53298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_UNLOCK(so, 1);
53308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
53318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
53328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
53338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
53368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp) {
53378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
53388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
53398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
53408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
53418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
53428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
53438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
53458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch,stcb, *netp);
53468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
53488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_ECN_ECHO:
53498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-ECHO\n");
53508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
53518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_ecne_chunk))) {
53528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
53538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
53548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
53558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
53578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
53588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb) {
5360fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.ecn_supported == 0) {
5361fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5362fb3816eaffe5878bb1286adb120fd160da178a05t				}
53638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
53648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
53658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
53668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
53678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
53688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
53698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
53718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch,
53728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						     stcb);
53738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				ecne_seen = 1;
53748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
53768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_ECN_CWR:
53778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-CWR\n");
53788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
53798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_cwr_chunk))) {
53808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
53818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
53828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
53838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
53858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
53868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
53878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb) {
5388fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.ecn_supported == 0) {
5389fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5390fb3816eaffe5878bb1286adb120fd160da178a05t				}
53918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
53928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
53938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
53948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
53958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
53968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
53978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
53988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
53998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
54008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
54028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_SHUTDOWN_COMPLETE:
5403ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE, stcb %p\n", (void *)stcb);
54048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* must be first and only chunk */
54058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((num_chunks > 1) ||
54068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
54078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
54088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
54098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
54108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
54128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp) {
54148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_shutdown_complete((struct sctp_shutdown_complete_chunk *)ch,
54158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							      stcb, *netp);
54168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
54188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
54198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
54208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_ASCONF:
54218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF\n");
54228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
54238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb) {
5424fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.asconf_supported == 0) {
5425fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5426fb3816eaffe5878bb1286adb120fd160da178a05t				}
54278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
54288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
54298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
54308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
54318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
54328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
54338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
5435e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				sctp_handle_asconf(m, *offset, src,
54368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						   (struct sctp_asconf_chunk *)ch, stcb, asconf_cnt == 0);
54378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				asconf_cnt++;
54388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
54408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_ASCONF_ACK:
54418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF-ACK\n");
54428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) {
54438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
54448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
54458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
54468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
54488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
54498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((stcb) && netp && *netp) {
5451fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.asconf_supported == 0) {
5452fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5453fb3816eaffe5878bb1286adb120fd160da178a05t				}
54548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* He's alive so give him credit */
54558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
54568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
54578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
54588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
54598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
54608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
54618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
54638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_asconf_ack(m, *offset,
54648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       (struct sctp_asconf_ack_chunk *)ch, stcb, *netp, &abort_no_unlock);
54658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (abort_no_unlock)
54668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
54678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
54698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_FORWARD_CUM_TSN:
54708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD-TSN\n");
54718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) {
54728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
54738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
54748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
54758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
54778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
54788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
54798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
54808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* He's alive so give him credit */
54818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb) {
54828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				int abort_flag = 0;
5483fb3816eaffe5878bb1286adb120fd160da178a05t
5484fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.prsctp_supported == 0) {
5485fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5486fb3816eaffe5878bb1286adb120fd160da178a05t				}
54878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.overall_error_count = 0;
54888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
54898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
54908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       stcb->asoc.overall_error_count,
54918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       0,
54928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       SCTP_FROM_SCTP_INPUT,
54938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						       __LINE__);
54948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
54958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*fwd_tsn_seen = 1;
54968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
54978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/* We are not interested anymore */
54980612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
54998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					so = SCTP_INP_SO(inp);
55008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_add_int(&stcb->asoc.refcnt, 1);
55018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(stcb);
55028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_LOCK(so, 1);
55038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_LOCK(stcb);
55048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					atomic_subtract_int(&stcb->asoc.refcnt, 1);
55058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
55068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT+SCTP_LOC_29);
55070612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
55088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_SOCKET_UNLOCK(so, 1);
55098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
55108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
55118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
55128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_forward_tsn(stcb,
55148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							(struct sctp_forward_tsn_chunk *)ch, &abort_flag, m, *offset);
55158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (abort_flag) {
55168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					*offset = length;
55178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return (NULL);
55188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				} else {
55198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
55208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
55218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							       stcb->asoc.overall_error_count,
55228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							       0,
55238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							       SCTP_FROM_SCTP_INPUT,
55248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							       __LINE__);
55258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
55268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					stcb->asoc.overall_error_count = 0;
55278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
55298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
55318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STREAM_RESET:
55328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_STREAM_RESET\n");
5533b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen			if (((stcb == NULL) || (ch == NULL) || (chk_length < sizeof(struct sctp_stream_reset_tsn_req)))) {
55348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
55358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
55368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
55378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
55398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
55408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55412344bfccffeb80545fca6a86e8cda3d56a6f50bft			if (stcb->asoc.reconfig_supported == 0) {
5542fb3816eaffe5878bb1286adb120fd160da178a05t				goto unknown_chunk;
55438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
554424feb751a6f488d36918e2f333dc2be853c259c8t			if (sctp_handle_stream_reset(stcb, m, *offset, ch)) {
55458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* stop processing */
55468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
55478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
55488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
55508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_PACKET_DROPPED:
55518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_PACKET_DROPPED\n");
55528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* re-get it all please */
55538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (chk_length < sizeof(struct sctp_pktdrop_chunk)) {
55548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
55558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
55568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
55578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
55598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
55608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
55628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
55638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (ch && (stcb) && netp && (*netp)) {
5564fb3816eaffe5878bb1286adb120fd160da178a05t				if (stcb->asoc.pktdrop_supported == 0) {
5565fb3816eaffe5878bb1286adb120fd160da178a05t					goto unknown_chunk;
5566fb3816eaffe5878bb1286adb120fd160da178a05t				}
55678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch,
55688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							   stcb, *netp,
55698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							   min(chk_length, (sizeof(chunk_buf) - 4)));
55708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
55718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
55738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
55748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_AUTHENTICATION:
55758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_AUTHENTICATION\n");
55768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (stcb == NULL) {
55778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* save the first AUTH for later processing */
55788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (auth_skipped == 0) {
55798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					auth_offset = *offset;
55808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					auth_len = chk_length;
55818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					auth_skipped = 1;
55828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* skip this chunk (temporarily) */
55848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				goto next_chunk;
55858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
5586fb3816eaffe5878bb1286adb120fd160da178a05t			if (stcb->asoc.auth_supported == 0) {
5587fb3816eaffe5878bb1286adb120fd160da178a05t				goto unknown_chunk;
5588fb3816eaffe5878bb1286adb120fd160da178a05t			}
55898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((chk_length < (sizeof(struct sctp_auth_chunk))) ||
55908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			    (chk_length > (sizeof(struct sctp_auth_chunk) +
55910ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen					   SCTP_AUTH_DIGEST_LEN_MAX))) {
55928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* Its not ours */
55938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (locked_tcb) {
55948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_TCB_UNLOCK(locked_tcb);
55958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
55968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
55978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (NULL);
55988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
55998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (got_auth == 1) {
56008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* skip this chunk... it's already auth'd */
56018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				goto next_chunk;
56028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
56038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			got_auth = 1;
56048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((ch == NULL) || sctp_handle_auth(stcb, (struct sctp_auth_chunk *)ch,
56058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							     m, *offset)) {
56068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* auth HMAC failed so dump the packet */
56078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
56088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (stcb);
56098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			} else {
56108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* remaining chunks are HMAC checked */
56118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				stcb->asoc.authenticated = 1;
56128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
56138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
56148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		default:
56168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		unknown_chunk:
56178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* it's an unknown chunk! */
56188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
56198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct mbuf *mm;
56208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				struct sctp_paramhdr *phd;
56218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
562368beeca578347438d9c434680197647ed551935ft							   0, M_NOWAIT, 1, MT_DATA);
56248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (mm) {
56258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					phd = mtod(mm, struct sctp_paramhdr *);
56268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					/*
56278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * We cheat and use param type since
56288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * we did not bother to define a
56298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * error cause struct. They are the
56308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * same basic format with different
56318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 * names.
56328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 */
56338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					phd->param_type =  htons(SCTP_CAUSE_UNRECOG_CHUNK);
56348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					phd->param_length = htons(chk_length + sizeof(*phd));
56358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_BUF_LEN(mm) = sizeof(*phd);
563668beeca578347438d9c434680197647ed551935ft					SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
56378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					if (SCTP_BUF_NEXT(mm)) {
5638290e3870bdc4b436f18bfe30e6c243205fc29702t						if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL) == NULL) {
56394df11f5004bbb4c768851ee41149ba6982c60f29tuexen							sctp_m_freem(mm);
56404df11f5004bbb4c768851ee41149ba6982c60f29tuexen						} else {
56418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MBUF_LOGGING
56424df11f5004bbb4c768851ee41149ba6982c60f29tuexen							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
56434df11f5004bbb4c768851ee41149ba6982c60f29tuexen								struct mbuf *mat;
56444df11f5004bbb4c768851ee41149ba6982c60f29tuexen
5645208d5309857156b26b753ba8cb35813775f49c5btuexen								for (mat = SCTP_BUF_NEXT(mm); mat; mat = SCTP_BUF_NEXT(mat)) {
56464df11f5004bbb4c768851ee41149ba6982c60f29tuexen									if (SCTP_BUF_IS_EXTENDED(mat)) {
56474df11f5004bbb4c768851ee41149ba6982c60f29tuexen										sctp_log_mb(mat, SCTP_MBUF_ICOPY);
56484df11f5004bbb4c768851ee41149ba6982c60f29tuexen									}
56498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen								}
56508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							}
56518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
56524df11f5004bbb4c768851ee41149ba6982c60f29tuexen							sctp_queue_op_err(stcb, mm);
56534df11f5004bbb4c768851ee41149ba6982c60f29tuexen						}
56548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					} else {
56558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen						sctp_m_freem(mm);
56568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					}
56578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
56588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
56598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((ch->chunk_type & 0x80) == 0) {
56608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				/* discard this packet */
56618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				*offset = length;
56628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				return (stcb);
56638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}	/* else skip this bad chunk and continue... */
56648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
56658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}		/* switch (ch->chunk_type) */
56668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	next_chunk:
56698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* get the next chunk */
56708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		*offset += SCTP_SIZE32(chk_length);
56718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (*offset >= length) {
56728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* no more data left in the mbuf chain */
56738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
56748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
56758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
56768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen							   sizeof(struct sctp_chunkhdr), chunk_buf);
56778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (ch == NULL) {
56788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (locked_tcb) {
56798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				SCTP_TCB_UNLOCK(locked_tcb);
56808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
56818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			*offset = length;
56828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return (NULL);
56838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
56848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}			/* while */
56858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (asconf_cnt > 0 && stcb != NULL) {
56878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_asconf_ack(stcb);
56888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
56898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return (stcb);
56908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
56918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
56938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS
56948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __GNUC__
56958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen__attribute__((noinline))
56968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
56978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
56988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_validate_no_locks(struct sctp_inpcb *inp)
56998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
57008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef __APPLE__
57018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctp_tcb *lstcb;
570215aed6e434dc1aac416f14635bb78920317d60e7t
57038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
57048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (mtx_owned(&lstcb->tcb_mtx)) {
57058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			panic("Own lock on stcb at return from input");
57068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
57078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
57088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (mtx_owned(&inp->inp_create_mtx)) {
57098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		panic("Own create lock on inp");
57108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
57118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (mtx_owned(&inp->inp_mtx)) {
57128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		panic("Own inp lock on inp");
57138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
57148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
57158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
57168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
57178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
57188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*
57198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * common input chunk processing (v4 and v6)
57208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */
57218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
5722e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexensctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length,
5723e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen                             struct sockaddr *src, struct sockaddr *dst,
5724e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen                             struct sctphdr *sh, struct sctp_chunkhdr *ch,
572566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM)
572666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen                             uint8_t compute_crc,
572766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
572866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen                             uint8_t ecn_bits,
572951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
573051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                             uint8_t use_mflowid, uint32_t mflowid,
573151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
573251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen                             uint32_t vrf_id, uint16_t port)
57338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
57348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t high_tsn;
57358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int fwd_tsn_seen = 0, data_processed = 0;
57368f9e45fea288542b24a6bda01269c6fc184d991at	struct mbuf *m = *mm, *op_err;
57378f9e45fea288542b24a6bda01269c6fc184d991at	char msg[SCTP_DIAG_INFO_LEN];
57388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int un_sent;
5739b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	int cnt_ctrl_ready = 0;
57404a19dac3955f03ff398400d269bdca84b113c85btuexen	struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
574166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	struct sctp_tcb *stcb = NULL;
574266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	struct sctp_nets *net = NULL;
57438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
57448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR(sctps_recvdatagrams);
57458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED
57468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_audit_log(0xE0, 1);
57478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_auditing(0, inp, stcb, net);
57488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
574966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM)
575066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (compute_crc != 0) {
575166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		uint32_t check, calc_check;
575266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen
575366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		check = sh->checksum;
575466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		sh->checksum = 0;
575566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		calc_check = sctp_calculate_cksum(m, iphlen);
575666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		sh->checksum = check;
575766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (calc_check != check) {
575866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
5759ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			        calc_check, check, (void *)m, length, iphlen);
576066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			stcb = sctp_findassociation_addr(m, offset, src, dst,
576166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			                                 sh, ch, &inp, &net, vrf_id);
576248830a703639020b04dbea0128bc37fd8a8ab35et#if defined(INET) || defined(INET6)
576366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if ((net != NULL) && (port != 0)) {
576466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				if (net->port == 0) {
576566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen					sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
576666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				}
576766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				net->port = port;
576866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
57696c632b3f6e570981666f8a3ff4be34eaf1735835t#endif
577066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__)
577166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if ((net != NULL) && (use_mflowid != 0)) {
577266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				net->flowid = mflowid;
577366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#ifdef INVARIANTS
577466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				net->flowidset = 1;
577566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
577666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
577766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
577866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if ((inp != NULL) && (stcb != NULL)) {
577966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
578066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
578166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			} else if ((inp != NULL) && (stcb == NULL)) {
578266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				inp_decr = inp;
578366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
578466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			SCTP_STAT_INCR(sctps_badsum);
578566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
578666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
578766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
578866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
578966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
579066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	/* Destination port of 0 is illegal, based on RFC4960. */
579166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (sh->dest_port == 0) {
579266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_STAT_INCR(sctps_hdrops);
579366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
579466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
579566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	stcb = sctp_findassociation_addr(m, offset, src, dst,
579666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	                                 sh, ch, &inp, &net, vrf_id);
579748830a703639020b04dbea0128bc37fd8a8ab35et#if defined(INET) || defined(INET6)
579866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if ((net != NULL) && (port != 0)) {
579966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (net->port == 0) {
580066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
580166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
580266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		net->port = port;
580366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
58046c632b3f6e570981666f8a3ff4be34eaf1735835t#endif
580566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__)
580666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if ((net != NULL) && (use_mflowid != 0)) {
580766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		net->flowid = mflowid;
580866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#ifdef INVARIANTS
580966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		net->flowidset = 1;
581066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
581166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
581266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
581366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (inp == NULL) {
581466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_STAT_INCR(sctps_noport);
5815b06edc654b01523d6cdf646804e9dd5903a5cc68t#if defined(__FreeBSD__) && (((__FreeBSD_version < 900000) && (__FreeBSD_version >= 804000)) || (__FreeBSD_version > 900000))
581666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
581766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
581866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
581966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
582066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
582166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			sctp_send_shutdown_complete2(src, dst, sh,
582266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__)
582366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			                             use_mflowid, mflowid,
582466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
582566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			                             vrf_id, port);
582666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
582766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
582866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
582966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
583066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
583166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
583266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
583366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
583466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			     (ch->chunk_type != SCTP_INIT))) {
58358f9e45fea288542b24a6bda01269c6fc184d991at				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
58368f9e45fea288542b24a6bda01269c6fc184d991at				                             "Out of the blue");
583766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				sctp_send_abort(m, iphlen, src, dst,
58388f9e45fea288542b24a6bda01269c6fc184d991at				                sh, 0, op_err,
583966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__)
584066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				                use_mflowid, mflowid,
584166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
584266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				                vrf_id, port);
584366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
584466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
584566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
584666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	} else if (stcb == NULL) {
584766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		inp_decr = inp;
584866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
584966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#ifdef IPSEC
585066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	/*-
585166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	 * I very much doubt any of the IPSEC stuff will work but I have no
585266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	 * idea, so I will leave it in place.
585366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	 */
585466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (inp != NULL) {
585566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		switch (dst->sa_family) {
585666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#ifdef INET
585766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		case AF_INET:
585866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
5859e9a6e49099bfee0c316e89efc4c9d2211af729f3t#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
5860ebdc22cd2539b3e5ae3b11100cc14e1306640b8at				IPSECSTAT_INC(ips_in_polvio);
5861e9a6e49099bfee0c316e89efc4c9d2211af729f3t#else
586266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				MODULE_GLOBAL(ipsec4stat).in_polvio++;
5863e9a6e49099bfee0c316e89efc4c9d2211af729f3t#endif
586466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				SCTP_STAT_INCR(sctps_hdrops);
586566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				goto out;
586666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
586766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			break;
586866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
586966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#ifdef INET6
587066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		case AF_INET6:
587166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
5872e9a6e49099bfee0c316e89efc4c9d2211af729f3t#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
5873ebdc22cd2539b3e5ae3b11100cc14e1306640b8at				IPSEC6STAT_INC(ips_in_polvio);
5874e9a6e49099bfee0c316e89efc4c9d2211af729f3t#else
587566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				MODULE_GLOBAL(ipsec6stat).in_polvio++;
5876e9a6e49099bfee0c316e89efc4c9d2211af729f3t#endif
587766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				SCTP_STAT_INCR(sctps_hdrops);
587866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen				goto out;
587966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			}
588066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			break;
588166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
588266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		default:
588366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			break;
588466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		}
588566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
588666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
58878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n",
5888ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t		(void *)m, iphlen, offset, length, (void *)stcb);
58898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb) {
58908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* always clear this before beginning a packet */
58918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.authenticated = 0;
58928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.seen_a_sack_this_pkt = 0;
58938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT1, "stcb:%p state:%x\n",
5894ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			(void *)stcb, stcb->asoc.state);
58958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
58968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) ||
58978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
58988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*-
58998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * If we hit here, we had a ref count
59008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * up when the assoc was aborted and the
59018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * timer is clearing out the assoc, we should
59028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * NOT respond to any packet.. its OOTB.
59038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
5904e2828360ea9cf8951730d46f5c14626c9425cb30t			SCTP_TCB_UNLOCK(stcb);
590566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			stcb = NULL;
59068f9e45fea288542b24a6bda01269c6fc184d991at			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
59078f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
59088f9e45fea288542b24a6bda01269c6fc184d991at			                             msg);
59098f9e45fea288542b24a6bda01269c6fc184d991at			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
591051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
591151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 use_mflowid, mflowid,
591251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
5913e2828360ea9cf8951730d46f5c14626c9425cb30t			                 vrf_id, port);
591466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
59158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
59168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
59178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
59188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (IS_SCTP_CONTROL(ch)) {
59198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* process the control portion of the SCTP packet */
59208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* sa_ignore NO_NULL_CHK */
5921e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		stcb = sctp_process_control(m, iphlen, &offset, length,
5922e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                            src, dst, sh, ch,
592351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                            inp, stcb, &net, &fwd_tsn_seen,
592451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
5925e2828360ea9cf8951730d46f5c14626c9425cb30t		                            use_mflowid, mflowid,
592651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
592751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                            vrf_id, port);
59288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb) {
59298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* This covers us if the cookie-echo was there
59308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * and it changes our INP.
59318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
5932e2828360ea9cf8951730d46f5c14626c9425cb30t			inp = stcb->sctp_ep;
593348830a703639020b04dbea0128bc37fd8a8ab35et#if defined(INET) || defined(INET6)
59348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if ((net) && (port)) {
59358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				if (net->port == 0) {
59360ac02f34d6041cd0018437596a5a9a94685e6919tuexen					sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
59378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
59388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				net->port = port;
59398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
59406c632b3f6e570981666f8a3ff4be34eaf1735835t#endif
59418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
59428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else {
59438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
59448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * no control chunks, so pre-process DATA chunks (these
59458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * checks are taken care of by control processing)
59468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
59478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
59488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
59498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * if DATA only packet, and auth is required, then punt...
59508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * can't have authenticated without any AUTH (control)
59518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * chunks
59528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
59538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if ((stcb != NULL) &&
5954fb3816eaffe5878bb1286adb120fd160da178a05t		    (stcb->asoc.auth_supported == 1) &&
59558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		    sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
59568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* "silently" ignore */
59578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_recvauthmissing);
595866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
59598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
59608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb == NULL) {
59618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* out of the blue DATA chunk */
59628f9e45fea288542b24a6bda01269c6fc184d991at			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
59638f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
59648f9e45fea288542b24a6bda01269c6fc184d991at			                             msg);
59658f9e45fea288542b24a6bda01269c6fc184d991at			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
596651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
596751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 use_mflowid, mflowid,
596851e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
59698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 vrf_id, port);
597066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
59718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
59728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
59738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* v_tag mismatch! */
59748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_badvtag);
597566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
59768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
59778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
59788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
59798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (stcb == NULL) {
59808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
59818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * no valid TCB for this packet, or we found it's a bad
59828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * packet while processing control, or we're done with this
59838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * packet (done or skip rest of data), so we drop it...
59848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
598566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
59868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
59878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
59888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
59898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * DATA chunk processing
59908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
59918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* plow through the data chunks while length > offset */
59928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
59938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/*
59948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * Rest should be DATA only.  Check authentication state if AUTH for
59958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 * DATA is required.
59968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	 */
59978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((length > offset) &&
59988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    (stcb != NULL) &&
5999fb3816eaffe5878bb1286adb120fd160da178a05t	    (stcb->asoc.auth_supported == 1) &&
60008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) &&
60018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    !stcb->asoc.authenticated) {
60028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* "silently" ignore */
60038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_recvauthmissing);
60048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_AUTH1,
60058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			"Data chunk requires AUTH, skipped\n");
60068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		goto trigger_send;
60078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
60088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (length > offset) {
60098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		int retval;
60108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
60118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
60128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * First check to make sure our state is correct. We would
60138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * not get here unless we really did have a tag, so we don't
60148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * abort if this happens, just dump the chunk silently.
60158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
60168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		switch (SCTP_GET_STATE(&stcb->asoc)) {
60178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_COOKIE_ECHOED:
60188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
60198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * we consider data with valid tags in this state
60208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * shows us the cookie-ack was lost. Imply it was
60218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * there.
60228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
60238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
60248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
60258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       stcb->asoc.overall_error_count,
60268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       0,
60278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       SCTP_FROM_SCTP_INPUT,
60288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					       __LINE__);
60298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
60308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			stcb->asoc.overall_error_count = 0;
60318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, net);
60328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
60338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_COOKIE_WAIT:
60348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
60358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * We consider OOTB any data sent during asoc setup.
60368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
60378f9e45fea288542b24a6bda01269c6fc184d991at			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
60388f9e45fea288542b24a6bda01269c6fc184d991at			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
60398f9e45fea288542b24a6bda01269c6fc184d991at			                             msg);
60408f9e45fea288542b24a6bda01269c6fc184d991at			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
604151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
604251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen			                 use_mflowid, mflowid,
604351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
60448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					 vrf_id, port);
604566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
60468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*sa_ignore NOTREACHED*/
60478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
60488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_EMPTY:	/* should not happen */
60498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_INUSE:	/* should not happen */
60508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_SHUTDOWN_RECEIVED:	/* This is a peer error */
60518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_SHUTDOWN_ACK_SENT:
60528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		default:
605366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
60548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*sa_ignore NOTREACHED*/
60558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
60568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_OPEN:
60578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		case SCTP_STATE_SHUTDOWN_SENT:
60588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			break;
60598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
60608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* plow through the data chunks while length > offset */
6061e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		retval = sctp_process_data(mm, iphlen, &offset, length,
6062e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		                           src, dst, sh,
606351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                           inp, stcb, net, &high_tsn,
606451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
606551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                           use_mflowid, mflowid,
606651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
606751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		                           vrf_id, port);
60688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (retval == 2) {
60698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/*
60708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * The association aborted, NO UNLOCK needed since
60718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * the association is destroyed.
60728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
607366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			stcb = NULL;
607466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen			goto out;
60758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
60768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		data_processed = 1;
60778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/*
60788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * Anything important needs to have been m_copy'ed in
60798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 * process_data
60808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		 */
60818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
60828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
60838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* take care of ecn */
6084b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	if ((data_processed == 1) &&
6085aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t	    (stcb->asoc.ecn_supported == 1) &&
60868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) {
60878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		/* Yep, we need to add a ECNE */
60888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_send_ecn_echo(stcb, net, high_tsn);
60898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
60908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
60918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if ((data_processed == 0) && (fwd_tsn_seen)) {
60928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		int was_a_gap;
60938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		uint32_t highest_tsn;
60948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
60958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_TSN_GT(stcb->asoc.highest_tsn_inside_nr_map, stcb->asoc.highest_tsn_inside_map)) {
60968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			highest_tsn = stcb->asoc.highest_tsn_inside_nr_map;
60978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
60988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			highest_tsn = stcb->asoc.highest_tsn_inside_map;
60998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
61008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn);
61018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.send_sack = 1;
61020ac02f34d6041cd0018437596a5a9a94685e6919tuexen		sctp_sack_check(stcb, was_a_gap);
61038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	} else if (fwd_tsn_seen) {
61048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.send_sack = 1;
61058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
61068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* trigger send of any chunks in queue... */
61078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexentrigger_send:
61088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED
61098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_audit_log(0xE0, 2);
61108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_auditing(1, inp, stcb, net);
61118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
61128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTPDBG(SCTP_DEBUG_INPUT1,
61138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		"Check for chunk output prw:%d tqe:%d tf=%d\n",
61148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.peers_rwnd,
61158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		TAILQ_EMPTY(&stcb->asoc.control_send_queue),
61168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		stcb->asoc.total_flight);
61178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight);
61188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
61198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq;
61208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
61218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (cnt_ctrl_ready ||
61228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	    ((un_sent) &&
61238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	     (stcb->asoc.peers_rwnd > 0 ||
61248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	      (stcb->asoc.peers_rwnd <= 0 && stcb->asoc.total_flight == 0)))) {
61258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "Calling chunk OUTPUT\n");
61268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
61278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "chunk OUTPUT returns\n");
61288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
61298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED
61308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_audit_log(0xE0, 3);
61318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_auditing(2, inp, stcb, net);
61328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
613366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen out:
613466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (stcb != NULL) {
613566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_TCB_UNLOCK(stcb);
613666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
613766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (inp_decr != NULL) {
613866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		/* reduce ref-count */
613966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_INP_WLOCK(inp_decr);
614066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_INP_DECR_REF(inp_decr);
614166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_INP_WUNLOCK(inp_decr);
614266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
61438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS
614466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (inp != NULL) {
614566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		sctp_validate_no_locks(inp);
614666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	}
61478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
61488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return;
61498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
61508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
61518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if 0
61528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void
61538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_print_mbuf_chain(struct mbuf *m)
61548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
6155b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen	for (; m; m = SCTP_BUF_NEXT(m)) {
6156ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t		SCTP_PRINTF("%p: m_len = %ld\n", (void *)m, SCTP_BUF_LEN(m));
61578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (SCTP_BUF_IS_EXTENDED(m))
6158ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t			SCTP_PRINTF("%p: extend_size = %d\n", (void *)m, SCTP_BUF_EXTEND_SIZE(m));
61598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
61608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
61618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
61628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
61638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET
6164b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if !defined(__Userspace__)
6165b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
61668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
61678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
6168b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#elif defined(__Panda__)
61698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
61708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_input(pakhandle_type i_pak)
61718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
61728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
61738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __STDC__
61748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_input(struct mbuf *i_pak,...)
61758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
61768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_input(i_pak, va_alist)
61778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *i_pak;
61788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
61798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
61808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
61818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct mbuf *m;
61828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	int iphlen;
61838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint32_t vrf_id = 0;
61848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint8_t ecn_bits;
6185e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	struct sockaddr_in src, dst;
61868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct ip *ip;
61878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	struct sctphdr *sh;
6188923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	struct sctp_chunkhdr *ch;
6189923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	int length, offset;
619066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM)
619166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	uint8_t compute_crc;
619266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
619351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
619451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	uint32_t mflowid;
619551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	uint8_t use_mflowid;
619651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
6197b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__))
61988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	uint16_t port = 0;
61998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
62008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
6201923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#if defined(__Panda__)
6202923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	/* This is Evil, but its the only way to make panda work right. */
6203923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	iphlen = sizeof(struct ip);
6204923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#else
6205923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	iphlen = off;
62068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
62078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
62088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_RELEASE_PKT(i_pak);
62098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
62108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
62118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	m = SCTP_HEADER_TO_CHAIN(i_pak);
62128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __Panda__
62138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_DETACH_HEADER_FROM_CHAIN(i_pak);
62148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	(void)SCTP_RELEASE_HEADER(i_pak);
62158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
62168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MBUF_LOGGING
62178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* Log in any input mbufs */
62188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
6219208d5309857156b26b753ba8cb35813775f49c5btuexen		struct mbuf *mat;
6220208d5309857156b26b753ba8cb35813775f49c5btuexen
6221208d5309857156b26b753ba8cb35813775f49c5btuexen		for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
62228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BUF_IS_EXTENDED(mat)) {
62238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				sctp_log_mb(mat, SCTP_MBUF_INPUT);
62248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
62258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
62268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
62278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
62281b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen#ifdef SCTP_PACKET_LOGGING
6229923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
62301b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen		sctp_packet_log(m);
6231923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	}
62328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
623351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
623432ce34e90f7862d56c81f432a802a00110f7b427t#if __FreeBSD_version > 1000049
623532ce34e90f7862d56c81f432a802a00110f7b427t	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
623632ce34e90f7862d56c81f432a802a00110f7b427t	        "sctp_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
623732ce34e90f7862d56c81f432a802a00110f7b427t	        m->m_pkthdr.len,
623832ce34e90f7862d56c81f432a802a00110f7b427t	        if_name(m->m_pkthdr.rcvif),
623932ce34e90f7862d56c81f432a802a00110f7b427t	        (int)m->m_pkthdr.csum_flags, CSUM_BITS);
62408d509612af0dc2e1895434112897cf049b463063t#elif __FreeBSD_version >= 800000
624166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
624266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
624366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.len,
624466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        if_name(m->m_pkthdr.rcvif),
624566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.csum_flags);
624666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#else
624766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
624866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
624966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.len,
625066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.rcvif->if_xname,
625166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.csum_flags);
625266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
625366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
625466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__APPLE__)
625566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
625666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        "sctp_input(): Packet of length %d received on %s%d with csum_flags 0x%x.\n",
625766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.len,
625866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.rcvif->if_name,
625966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.rcvif->if_unit,
626066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.csum_flags);
626166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
626266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__Windows__)
626366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
626466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
626566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.len,
626666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.rcvif->if_xname,
626766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	        m->m_pkthdr.csum_flags);
626866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
626966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__)
627051e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	if (m->m_flags & M_FLOWID) {
627151e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		mflowid = m->m_pkthdr.flowid;
627251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		use_mflowid = 1;
627351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	} else {
627451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		mflowid = 0;
627551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen		use_mflowid = 0;
627651e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	}
627751e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
6278923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	SCTP_STAT_INCR(sctps_recvpackets);
6279923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
6280923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	/* Get IP, SCTP, and first chunk header together in the first mbuf. */
6281923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
62828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (SCTP_BUF_LEN(m) < offset) {
6283e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen		if ((m = m_pullup(m, offset)) == NULL) {
62848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			SCTP_STAT_INCR(sctps_hdrops);
62858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			return;
62868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
62878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
6288e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	ip = mtod(m, struct ip *);
6289923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	sh = (struct sctphdr *)((caddr_t)ip + iphlen);
6290923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
6291923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	offset -= sizeof(struct sctp_chunkhdr);
6292e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	memset(&src, 0, sizeof(struct sockaddr_in));
6293e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	src.sin_family = AF_INET;
62947b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN
6295e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	src.sin_len = sizeof(struct sockaddr_in);
6296e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif
6297e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	src.sin_port = sh->src_port;
6298e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	src.sin_addr = ip->ip_src;
6299e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	memset(&dst, 0, sizeof(struct sockaddr_in));
6300e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	dst.sin_family = AF_INET;
63017b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN
6302e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	dst.sin_len = sizeof(struct sockaddr_in);
6303e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif
6304e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	dst.sin_port = sh->dest_port;
6305e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	dst.sin_addr = ip->ip_dst;
63068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Windows__)
63078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	NTOHS(ip->ip_len);
63088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
63090ac02f34d6041cd0018437596a5a9a94685e6919tuexen#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Windows)
631081616c6a3e184f46276632dd15aa489cd06d94dftuexen	ip->ip_len = ntohs(ip->ip_len);
63110af84c59aeb7cc1995f82ef737987d970c345cc7tuexen#endif
63124bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#if defined(__FreeBSD__)
63134bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#if __FreeBSD_version >= 1000000
63144bda18bd6192b29406d04eeb576f5d5d7bd32fc7t	length = ntohs(ip->ip_len);
63154bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#else
63164bda18bd6192b29406d04eeb576f5d5d7bd32fc7t	length = ip->ip_len + iphlen;
63174bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#endif
63184bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#elif defined(__APPLE__)
6319923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	length = ip->ip_len + iphlen;
6320923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#elif defined(__Userspace__)
6321923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Windows)
6322923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	length = ip->ip_len;
6323923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#else
6324923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	length = ip->ip_len + iphlen;
6325923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif
6326923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#else
6327923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	length = ip->ip_len;
6328923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif
6329923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	/* Validate mbuf chain length with IP payload length. */
633066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (SCTP_HEADER_LEN(m) != length) {
6331923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen		SCTPDBG(SCTP_DEBUG_INPUT1,
633266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		        "sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m));
63338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_hdrops);
633466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
63358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
63368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	/* SCTP does not allow broadcasts or multicasts */
6337e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
633866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
63398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
6340e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) {
634166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		goto out;
63428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
634366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	ecn_bits = ip->ip_tos;
63448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_WITH_NO_CSUM)
63458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	SCTP_STAT_INCR(sctps_recvnocrc);
63468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else
63478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
63488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
63498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_recvhwcrc);
635066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		compute_crc = 0;
635166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	} else {
635266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#else
635366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
6354e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	    ((src.sin_addr.s_addr == dst.sin_addr.s_addr) ||
6355923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen	     (SCTP_IS_IT_LOOPBACK(m)))) {
63568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		SCTP_STAT_INCR(sctps_recvnocrc);
635766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		compute_crc = 0;
635866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	} else {
635951e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
636066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		SCTP_STAT_INCR(sctps_recvswcrc);
636166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen		compute_crc = 1;
63628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
63638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
6364e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	sctp_common_input_processing(&m, iphlen, offset, length,
6365e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	                             (struct sockaddr *)&src,
6366e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen	                             (struct sockaddr *)&dst,
636766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	                             sh, ch,
636866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM)
636966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	                             compute_crc,
637066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif
637166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen	                             ecn_bits,
637251e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#if defined(__FreeBSD__)
637351e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	                             use_mflowid, mflowid,
637451e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen#endif
637551e1e2f0655e8df3aac73911a52e1e558d74ad63tuexen	                             vrf_id, port);
637666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen out:
63778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (m) {
63788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_m_freem(m);
63798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	}
63808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	return;
63818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
63828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
63838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
63848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenextern int *sctp_cpuarry;
63858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
63868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen
638761a075e65a009a719c4265bfc4bfc433962ffc3ft#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
638861a075e65a009a719c4265bfc4bfc433962ffc3ftint
638961a075e65a009a719c4265bfc4bfc433962ffc3ftsctp_input(struct mbuf **mp, int *offp, int proto SCTP_UNUSED)
639061a075e65a009a719c4265bfc4bfc433962ffc3ft{
639161a075e65a009a719c4265bfc4bfc433962ffc3ft	struct mbuf *m;
639261a075e65a009a719c4265bfc4bfc433962ffc3ft	int off;
639361a075e65a009a719c4265bfc4bfc433962ffc3ft
639461a075e65a009a719c4265bfc4bfc433962ffc3ft	m = *mp;
639561a075e65a009a719c4265bfc4bfc433962ffc3ft	off = *offp;
639661a075e65a009a719c4265bfc4bfc433962ffc3ft#else
63978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid
63988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_input(struct mbuf *m, int off)
63998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{
640061a075e65a009a719c4265bfc4bfc433962ffc3ft#endif
64018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
64028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	if (mp_ncpus > 1) {
640361a075e65a009a719c4265bfc4bfc433962ffc3ft		struct ip *ip;
640461a075e65a009a719c4265bfc4bfc433962ffc3ft		struct sctphdr *sh;
640561a075e65a009a719c4265bfc4bfc433962ffc3ft		int offset;
640661a075e65a009a719c4265bfc4bfc433962ffc3ft		int cpu_to_use;
640761a075e65a009a719c4265bfc4bfc433962ffc3ft		uint32_t flowid, tag;
640861a075e65a009a719c4265bfc4bfc433962ffc3ft
64098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		if (m->m_flags & M_FLOWID) {
64108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			flowid = m->m_pkthdr.flowid;
64118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		} else {
64128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			/* No flow id built by lower layers
64138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 * fix it so we create one.
64148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			 */
6415e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen			offset = off + sizeof(struct sctphdr);
64168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			if (SCTP_BUF_LEN(m) < offset) {
6417e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen				if ((m = m_pullup(m, offset)) == NULL) {
64188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					SCTP_STAT_INCR(sctps_hdrops);
641961a075e65a009a719c4265bfc4bfc433962ffc3ft#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
642061a075e65a009a719c4265bfc4bfc433962ffc3ft					return (IPPROTO_DONE);
642161a075e65a009a719c4265bfc4bfc433962ffc3ft#else
64228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen					return;
642361a075e65a009a719c4265bfc4bfc433962ffc3ft#endif
64248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen				}
64258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			}
6426e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen			ip = mtod(m, struct ip *);
64278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			sh = (struct sctphdr *)((caddr_t)ip + off);
64288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			tag = htonl(sh->v_tag);
64298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);
64308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			m->m_pkthdr.flowid = flowid;
64318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen			m->m_flags |= M_FLOWID;
64328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		}
64338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		cpu_to_use = sctp_cpuarry[flowid % mp_ncpus];
64348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		sctp_queue_to_mcore(m, off, cpu_to_use);
643561a075e65a009a719c4265bfc4bfc433962ffc3ft#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
643661a075e65a009a719c4265bfc4bfc433962ffc3ft		return (IPPROTO_DONE);
643761a075e65a009a719c4265bfc4bfc433962ffc3ft#else
64388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen		return;
643961a075e65a009a719c4265bfc4bfc433962ffc3ft#endif
644032a191a90b5c914a02047389c5b3197e08fc9841tuexen	}
64418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
64428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen	sctp_input_with_port(m, off, 0);
644361a075e65a009a719c4265bfc4bfc433962ffc3ft#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
644461a075e65a009a719c4265bfc4bfc433962ffc3ft	return (IPPROTO_DONE);
644561a075e65a009a719c4265bfc4bfc433962ffc3ft#endif
64468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}
64478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif
6448b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif
6449