1163953Srrs/*-
2185694Srrs * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3237896Stuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
4237896Stuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
5163953Srrs *
6163953Srrs * Redistribution and use in source and binary forms, with or without
7163953Srrs * modification, are permitted provided that the following conditions are met:
8163953Srrs *
9163953Srrs * a) Redistributions of source code must retain the above copyright notice,
10231038Stuexen *    this list of conditions and the following disclaimer.
11163953Srrs *
12163953Srrs * b) Redistributions in binary form must reproduce the above copyright
13163953Srrs *    notice, this list of conditions and the following disclaimer in
14231038Stuexen *    the documentation and/or other materials provided with the distribution.
15163953Srrs *
16163953Srrs * c) Neither the name of Cisco Systems, Inc. nor the names of its
17163953Srrs *    contributors may be used to endorse or promote products derived
18163953Srrs *    from this software without specific prior written permission.
19163953Srrs *
20163953Srrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21163953Srrs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22163953Srrs * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23163953Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24163953Srrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25163953Srrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26163953Srrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27163953Srrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28163953Srrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29163953Srrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30163953Srrs * THE POSSIBILITY OF SUCH DAMAGE.
31163953Srrs */
32163953Srrs
33163953Srrs#include <sys/cdefs.h>
34163953Srrs__FBSDID("$FreeBSD$");
35163953Srrs
36163953Srrs#include <netinet/sctp_os.h>
37163953Srrs#include <netinet/sctp_var.h>
38167598Srrs#include <netinet/sctp_sysctl.h>
39163953Srrs#include <netinet/sctp_pcb.h>
40163953Srrs#include <netinet/sctp_header.h>
41163953Srrs#include <netinet/sctputil.h>
42163953Srrs#include <netinet/sctp_output.h>
43163953Srrs#include <netinet/sctp_input.h>
44163953Srrs#include <netinet/sctp_auth.h>
45163953Srrs#include <netinet/sctp_indata.h>
46163953Srrs#include <netinet/sctp_asconf.h>
47170091Srrs#include <netinet/sctp_bsd_addr.h>
48172091Srrs#include <netinet/sctp_timer.h>
49188067Srrs#include <netinet/sctp_crc32.h>
50179157Srrs#include <netinet/udp.h>
51218211Srrs#include <sys/smp.h>
52163953Srrs
53163953Srrs
54163953Srrs
55163953Srrsstatic void
56163953Srrssctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
57163953Srrs{
58163953Srrs	struct sctp_nets *net;
59163953Srrs
60165220Srrs	/*
61165220Srrs	 * This now not only stops all cookie timers it also stops any INIT
62165220Srrs	 * timers as well. This will make sure that the timers are stopped
63165220Srrs	 * in all collision cases.
64165220Srrs	 */
65163953Srrs	SCTP_TCB_LOCK_ASSERT(stcb);
66163953Srrs	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
67165220Srrs		if (net->rxt_timer.type == SCTP_TIMER_TYPE_COOKIE) {
68163953Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE,
69163953Srrs			    stcb->sctp_ep,
70163953Srrs			    stcb,
71165220Srrs			    net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_1);
72165220Srrs		} else if (net->rxt_timer.type == SCTP_TIMER_TYPE_INIT) {
73165220Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_INIT,
74165220Srrs			    stcb->sctp_ep,
75165220Srrs			    stcb,
76165220Srrs			    net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_2);
77163953Srrs		}
78163953Srrs	}
79163953Srrs}
80163953Srrs
81163953Srrs/* INIT handler */
82163953Srrsstatic void
83252889Stuexensctp_handle_init(struct mbuf *m, int iphlen, int offset,
84252889Stuexen    struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
85238253Stuexen    struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
86238253Stuexen    struct sctp_tcb *stcb, int *abort_no_unlock,
87238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
88238253Stuexen    uint32_t vrf_id, uint16_t port)
89163953Srrs{
90163953Srrs	struct sctp_init *init;
91163953Srrs	struct mbuf *op_err;
92163953Srrs
93169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_init: handling INIT tcb:%p\n",
94252927Stuexen	    (void *)stcb);
95172396Srrs	if (stcb == NULL) {
96172396Srrs		SCTP_INP_RLOCK(inp);
97172396Srrs	}
98231041Stuexen	/* validate length */
99163953Srrs	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
100266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
101252889Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
102238253Stuexen		    use_mflowid, mflowid,
103179157Srrs		    vrf_id, port);
104168299Srrs		if (stcb)
105168299Srrs			*abort_no_unlock = 1;
106172396Srrs		goto outnow;
107163953Srrs	}
108163953Srrs	/* validate parameters */
109231041Stuexen	init = &cp->init;
110163953Srrs	if (init->initiate_tag == 0) {
111163953Srrs		/* protocol error... send abort */
112266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
113252889Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
114238253Stuexen		    use_mflowid, mflowid,
115179157Srrs		    vrf_id, port);
116168299Srrs		if (stcb)
117168299Srrs			*abort_no_unlock = 1;
118172396Srrs		goto outnow;
119163953Srrs	}
120163953Srrs	if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
121163953Srrs		/* invalid parameter... send abort */
122266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
123252889Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
124238253Stuexen		    use_mflowid, mflowid,
125179157Srrs		    vrf_id, port);
126171440Srrs		if (stcb)
127171440Srrs			*abort_no_unlock = 1;
128172396Srrs		goto outnow;
129163953Srrs	}
130163953Srrs	if (init->num_inbound_streams == 0) {
131163953Srrs		/* protocol error... send abort */
132266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
133252889Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
134238253Stuexen		    use_mflowid, mflowid,
135179157Srrs		    vrf_id, port);
136168299Srrs		if (stcb)
137168299Srrs			*abort_no_unlock = 1;
138172396Srrs		goto outnow;
139163953Srrs	}
140163953Srrs	if (init->num_outbound_streams == 0) {
141163953Srrs		/* protocol error... send abort */
142266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
143252889Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
144238253Stuexen		    use_mflowid, mflowid,
145179157Srrs		    vrf_id, port);
146168299Srrs		if (stcb)
147168299Srrs			*abort_no_unlock = 1;
148172396Srrs		goto outnow;
149163953Srrs	}
150163953Srrs	if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
151231041Stuexen	    offset + ntohs(cp->ch.chunk_length))) {
152163953Srrs		/* auth parameter(s) error... send abort */
153266181Stuexen		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
154266181Stuexen		    "Problem with AUTH parameters");
155266181Stuexen		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
156238253Stuexen		    use_mflowid, mflowid,
157238253Stuexen		    vrf_id, port);
158168299Srrs		if (stcb)
159168299Srrs			*abort_no_unlock = 1;
160172396Srrs		goto outnow;
161163953Srrs	}
162231041Stuexen	/*
163231041Stuexen	 * We are only accepting if we have a socket with positive
164231041Stuexen	 * so_qlimit.
165231041Stuexen	 */
166231041Stuexen	if ((stcb == NULL) &&
167231041Stuexen	    ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
168231041Stuexen	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
169231041Stuexen	    (inp->sctp_socket == NULL) ||
170231041Stuexen	    (inp->sctp_socket->so_qlimit == 0))) {
171231041Stuexen		/*
172231041Stuexen		 * FIX ME ?? What about TCP model and we have a
173231041Stuexen		 * match/restart case? Actually no fix is needed. the lookup
174231041Stuexen		 * will always find the existing assoc so stcb would not be
175231041Stuexen		 * NULL. It may be questionable to do this since we COULD
176231041Stuexen		 * just send back the INIT-ACK and hope that the app did
177231041Stuexen		 * accept()'s by the time the COOKIE was sent. But there is
178231041Stuexen		 * a price to pay for COOKIE generation and I don't want to
179231041Stuexen		 * pay it on the chance that the app will actually do some
180231041Stuexen		 * accepts(). The App just looses and should NOT be in this
181231041Stuexen		 * state :-)
182231041Stuexen		 */
183231045Stuexen		if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
184266181Stuexen			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
185266181Stuexen			    "No listener");
186266181Stuexen			sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
187238253Stuexen			    use_mflowid, mflowid,
188238253Stuexen			    vrf_id, port);
189231045Stuexen		}
190231041Stuexen		goto outnow;
191231041Stuexen	}
192231041Stuexen	if ((stcb != NULL) &&
193231041Stuexen	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
194231041Stuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending SHUTDOWN-ACK\n");
195231041Stuexen		sctp_send_shutdown_ack(stcb, NULL);
196231041Stuexen		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
197231041Stuexen	} else {
198231041Stuexen		SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
199252889Stuexen		sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, src, dst,
200252889Stuexen		    sh, cp,
201238253Stuexen		    use_mflowid, mflowid,
202238253Stuexen		    vrf_id, port,
203231041Stuexen		    ((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
204231041Stuexen	}
205172396Srrsoutnow:
206172396Srrs	if (stcb == NULL) {
207172396Srrs		SCTP_INP_RUNLOCK(inp);
208172396Srrs	}
209163953Srrs}
210163953Srrs
211163953Srrs/*
212163953Srrs * process peer "INIT/INIT-ACK" chunk returns value < 0 on error
213163953Srrs */
214171158Srrs
215171158Srrsint
216221627Stuexensctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
217221627Stuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
218221627Stuexen    SCTP_UNUSED
219221627Stuexen#endif
220221627Stuexen)
221171158Srrs{
222171158Srrs	int unsent_data = 0;
223217760Stuexen	unsigned int i;
224217760Stuexen	struct sctp_stream_queue_pending *sp;
225171158Srrs	struct sctp_association *asoc;
226171158Srrs
227171158Srrs	/*
228171158Srrs	 * This function returns the number of streams that have true unsent
229171158Srrs	 * data on them. Note that as it looks through it will clean up any
230171158Srrs	 * places that have old data that has been sent but left at top of
231171158Srrs	 * stream queue.
232171158Srrs	 */
233171158Srrs	asoc = &stcb->asoc;
234171158Srrs	SCTP_TCB_SEND_LOCK(stcb);
235217760Stuexen	if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
236217760Stuexen		/* Check to see if some data queued */
237217760Stuexen		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
238217760Stuexen			/* sa_ignore FREED_MEMORY */
239217760Stuexen			sp = TAILQ_FIRST(&stcb->asoc.strmout[i].outqueue);
240217760Stuexen			if (sp == NULL) {
241217760Stuexen				continue;
242217760Stuexen			}
243171158Srrs			if ((sp->msg_is_complete) &&
244171158Srrs			    (sp->length == 0) &&
245171158Srrs			    (sp->sender_all_done)) {
246171158Srrs				/*
247171158Srrs				 * We are doing differed cleanup. Last time
248171158Srrs				 * through when we took all the data the
249171158Srrs				 * sender_all_done was not set.
250171158Srrs				 */
251171158Srrs				if (sp->put_last_out == 0) {
252171158Srrs					SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
253171158Srrs					SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d\n",
254171158Srrs					    sp->sender_all_done,
255171158Srrs					    sp->length,
256171158Srrs					    sp->msg_is_complete,
257171158Srrs					    sp->put_last_out);
258171158Srrs				}
259217760Stuexen				atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1);
260217760Stuexen				TAILQ_REMOVE(&stcb->asoc.strmout[i].outqueue, sp, next);
261212712Stuexen				if (sp->net) {
262212712Stuexen					sctp_free_remote_addr(sp->net);
263212712Stuexen					sp->net = NULL;
264212712Stuexen				}
265171158Srrs				if (sp->data) {
266171158Srrs					sctp_m_freem(sp->data);
267171158Srrs					sp->data = NULL;
268171158Srrs				}
269221627Stuexen				sctp_free_a_strmoq(stcb, sp, so_locked);
270171158Srrs			} else {
271171158Srrs				unsent_data++;
272216822Stuexen				break;
273171158Srrs			}
274171158Srrs		}
275171158Srrs	}
276171158Srrs	SCTP_TCB_SEND_UNLOCK(stcb);
277171158Srrs	return (unsent_data);
278171158Srrs}
279171158Srrs
280163953Srrsstatic int
281231038Stuexensctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
282163953Srrs{
283163953Srrs	struct sctp_init *init;
284163953Srrs	struct sctp_association *asoc;
285163953Srrs	struct sctp_nets *lnet;
286163953Srrs	unsigned int i;
287163953Srrs
288163953Srrs	init = &cp->init;
289163953Srrs	asoc = &stcb->asoc;
290163953Srrs	/* save off parameters */
291163953Srrs	asoc->peer_vtag = ntohl(init->initiate_tag);
292163953Srrs	asoc->peers_rwnd = ntohl(init->a_rwnd);
293218129Srrs	/* init tsn's */
294218129Srrs	asoc->highest_tsn_inside_map = asoc->asconf_seq_in = ntohl(init->initial_tsn) - 1;
295218129Srrs
296212712Stuexen	if (!TAILQ_EMPTY(&asoc->nets)) {
297163953Srrs		/* update any ssthresh's that may have a default */
298163953Srrs		TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
299163953Srrs			lnet->ssthresh = asoc->peers_rwnd;
300179783Srrs			if (SCTP_BASE_SYSCTL(sctp_logging_level) & (SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) {
301170744Srrs				sctp_log_cwnd(stcb, lnet, 0, SCTP_CWND_INITIALIZATION);
302170744Srrs			}
303163953Srrs		}
304163953Srrs	}
305164181Srrs	SCTP_TCB_SEND_LOCK(stcb);
306163953Srrs	if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) {
307163953Srrs		unsigned int newcnt;
308163953Srrs		struct sctp_stream_out *outs;
309216822Stuexen		struct sctp_stream_queue_pending *sp, *nsp;
310216822Stuexen		struct sctp_tmit_chunk *chk, *nchk;
311163953Srrs
312196260Stuexen		/* abandon the upper streams */
313163953Srrs		newcnt = ntohs(init->num_inbound_streams);
314216822Stuexen		TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
315216822Stuexen			if (chk->rec.data.stream_number >= newcnt) {
316216822Stuexen				TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
317216822Stuexen				asoc->send_queue_cnt--;
318252942Stuexen				if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) {
319252942Stuexen					asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
320252942Stuexen#ifdef INVARIANTS
321252942Stuexen				} else {
322252942Stuexen					panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number);
323252942Stuexen#endif
324252942Stuexen				}
325216822Stuexen				if (chk->data != NULL) {
326216822Stuexen					sctp_free_bufspace(stcb, asoc, chk, 1);
327237889Stuexen					sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
328237889Stuexen					    0, chk, SCTP_SO_NOT_LOCKED);
329216822Stuexen					if (chk->data) {
330216822Stuexen						sctp_m_freem(chk->data);
331216822Stuexen						chk->data = NULL;
332196260Stuexen					}
333196260Stuexen				}
334221627Stuexen				sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
335216822Stuexen				/* sa_ignore FREED_MEMORY */
336196260Stuexen			}
337196260Stuexen		}
338163953Srrs		if (asoc->strmout) {
339163953Srrs			for (i = newcnt; i < asoc->pre_open_streams; i++) {
340163953Srrs				outs = &asoc->strmout[i];
341216822Stuexen				TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
342196260Stuexen					TAILQ_REMOVE(&outs->outqueue, sp, next);
343163953Srrs					asoc->stream_queue_cnt--;
344163953Srrs					sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL,
345237889Stuexen					    stcb, 0, sp, SCTP_SO_NOT_LOCKED);
346163953Srrs					if (sp->data) {
347163953Srrs						sctp_m_freem(sp->data);
348163953Srrs						sp->data = NULL;
349163953Srrs					}
350212712Stuexen					if (sp->net) {
351212712Stuexen						sctp_free_remote_addr(sp->net);
352212712Stuexen						sp->net = NULL;
353212712Stuexen					}
354163953Srrs					/* Free the chunk */
355221627Stuexen					sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED);
356169655Srrs					/* sa_ignore FREED_MEMORY */
357163953Srrs				}
358163953Srrs			}
359163953Srrs		}
360196260Stuexen		/* cut back the count */
361163953Srrs		asoc->pre_open_streams = newcnt;
362163953Srrs	}
363164181Srrs	SCTP_TCB_SEND_UNLOCK(stcb);
364188854Srrs	asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams;
365218129Srrs
366185694Srrs	/* EY - nr_sack: initialize highest tsn in nr_mapping_array */
367185694Srrs	asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
368179783Srrs	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
369170744Srrs		sctp_log_map(0, 5, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
370170744Srrs	}
371163953Srrs	/* This is the next one we expect */
372163953Srrs	asoc->str_reset_seq_in = asoc->asconf_seq_in + 1;
373163953Srrs
374163953Srrs	asoc->mapping_array_base_tsn = ntohl(init->initial_tsn);
375180955Srrs	asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->asconf_seq_in;
376218129Srrs
377163953Srrs	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
378163953Srrs	/* open the requested streams */
379170091Srrs
380163953Srrs	if (asoc->strmin != NULL) {
381163953Srrs		/* Free the old ones */
382216822Stuexen		struct sctp_queued_to_read *ctl, *nctl;
383164181Srrs
384164181Srrs		for (i = 0; i < asoc->streamincnt; i++) {
385216822Stuexen			TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[i].inqueue, next, nctl) {
386164181Srrs				TAILQ_REMOVE(&asoc->strmin[i].inqueue, ctl, next);
387164181Srrs				sctp_free_remote_addr(ctl->whoFrom);
388171158Srrs				ctl->whoFrom = NULL;
389164181Srrs				sctp_m_freem(ctl->data);
390164181Srrs				ctl->data = NULL;
391164181Srrs				sctp_free_a_readq(stcb, ctl);
392164181Srrs			}
393164181Srrs		}
394170091Srrs		SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
395163953Srrs	}
396252978Stuexen	if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) {
397252978Stuexen		asoc->streamincnt = ntohs(init->num_outbound_streams);
398252978Stuexen	} else {
399252978Stuexen		asoc->streamincnt = asoc->max_inbound_streams;
400164181Srrs	}
401163953Srrs	SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
402170091Srrs	    sizeof(struct sctp_stream_in), SCTP_M_STRMI);
403163953Srrs	if (asoc->strmin == NULL) {
404163953Srrs		/* we didn't get memory for the streams! */
405169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "process_init: couldn't get memory for the streams!\n");
406163953Srrs		return (-1);
407163953Srrs	}
408163953Srrs	for (i = 0; i < asoc->streamincnt; i++) {
409163953Srrs		asoc->strmin[i].stream_no = i;
410163953Srrs		asoc->strmin[i].last_sequence_delivered = 0xffff;
411163953Srrs		TAILQ_INIT(&asoc->strmin[i].inqueue);
412168943Srrs		asoc->strmin[i].delivery_started = 0;
413163953Srrs	}
414163953Srrs	/*
415163953Srrs	 * load_address_from_init will put the addresses into the
416163953Srrs	 * association when the COOKIE is processed or the INIT-ACK is
417163953Srrs	 * processed. Both types of COOKIE's existing and new call this
418163953Srrs	 * routine. It will remove addresses that are no longer in the
419163953Srrs	 * association (for the restarting case where addresses are
420163953Srrs	 * removed). Up front when the INIT arrives we will discard it if it
421163953Srrs	 * is a restart and new addresses have been added.
422163953Srrs	 */
423169655Srrs	/* sa_ignore MEMLEAK */
424163953Srrs	return (0);
425163953Srrs}
426163953Srrs
427163953Srrs/*
428163953Srrs * INIT-ACK message processing/consumption returns value < 0 on error
429163953Srrs */
430163953Srrsstatic int
431252889Stuexensctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
432252889Stuexen    struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
433238253Stuexen    struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
434238253Stuexen    struct sctp_nets *net, int *abort_no_unlock,
435238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
436238253Stuexen    uint32_t vrf_id)
437163953Srrs{
438163953Srrs	struct sctp_association *asoc;
439163953Srrs	struct mbuf *op_err;
440163953Srrs	int retval, abort_flag;
441163953Srrs	uint32_t initack_limit;
442185694Srrs	int nat_friendly = 0;
443163953Srrs
444163953Srrs	/* First verify that we have no illegal param's */
445163953Srrs	abort_flag = 0;
446163953Srrs
447163953Srrs	op_err = sctp_arethere_unrecognized_parameters(m,
448163953Srrs	    (offset + sizeof(struct sctp_init_chunk)),
449185694Srrs	    &abort_flag, (struct sctp_chunkhdr *)cp, &nat_friendly);
450163953Srrs	if (abort_flag) {
451163953Srrs		/* Send an abort and notify peer */
452237884Stuexen		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
453170056Srrs		*abort_no_unlock = 1;
454163953Srrs		return (-1);
455163953Srrs	}
456163953Srrs	asoc = &stcb->asoc;
457185694Srrs	asoc->peer_supports_nat = (uint8_t) nat_friendly;
458163953Srrs	/* process the peer's parameters in the INIT-ACK */
459231038Stuexen	retval = sctp_process_init((struct sctp_init_chunk *)cp, stcb);
460163953Srrs	if (retval < 0) {
461163953Srrs		return (retval);
462163953Srrs	}
463163953Srrs	initack_limit = offset + ntohs(cp->ch.chunk_length);
464163953Srrs	/* load all addresses */
465231038Stuexen	if ((retval = sctp_load_addresses_from_init(stcb, m,
466252889Stuexen	    (offset + sizeof(struct sctp_init_chunk)), initack_limit,
467252889Stuexen	    src, dst, NULL))) {
468266181Stuexen		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
469266181Stuexen		    "Problem with address parameters");
470169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1,
471169420Srrs		    "Load addresses from INIT causes an abort %d\n",
472169420Srrs		    retval);
473252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
474266181Stuexen		    src, dst, sh, op_err,
475238253Stuexen		    use_mflowid, mflowid,
476238253Stuexen		    vrf_id, net->port);
477168299Srrs		*abort_no_unlock = 1;
478163953Srrs		return (-1);
479163953Srrs	}
480171477Srrs	/* if the peer doesn't support asconf, flush the asconf queue */
481171477Srrs	if (asoc->peer_supports_asconf == 0) {
482216822Stuexen		struct sctp_asconf_addr *param, *nparam;
483171477Srrs
484216822Stuexen		TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) {
485216822Stuexen			TAILQ_REMOVE(&asoc->asconf_queue, param, next);
486216822Stuexen			SCTP_FREE(param, SCTP_M_ASC_ADDR);
487171477Srrs		}
488171477Srrs	}
489163953Srrs	stcb->asoc.peer_hmac_id = sctp_negotiate_hmacid(stcb->asoc.peer_hmacs,
490163953Srrs	    stcb->asoc.local_hmacs);
491163953Srrs	if (op_err) {
492163953Srrs		sctp_queue_op_err(stcb, op_err);
493163953Srrs		/* queuing will steal away the mbuf chain to the out queue */
494163953Srrs		op_err = NULL;
495163953Srrs	}
496163953Srrs	/* extract the cookie and queue it to "echo" it back... */
497179783Srrs	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
498171943Srrs		sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
499171943Srrs		    stcb->asoc.overall_error_count,
500171943Srrs		    0,
501171943Srrs		    SCTP_FROM_SCTP_INPUT,
502171943Srrs		    __LINE__);
503171943Srrs	}
504163953Srrs	stcb->asoc.overall_error_count = 0;
505163953Srrs	net->error_count = 0;
506163953Srrs
507163953Srrs	/*
508163953Srrs	 * Cancel the INIT timer, We do this first before queueing the
509163953Srrs	 * cookie. We always cancel at the primary to assue that we are
510163953Srrs	 * canceling the timer started by the INIT which always goes to the
511163953Srrs	 * primary.
512163953Srrs	 */
513163953Srrs	sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, stcb,
514165220Srrs	    asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_4);
515163953Srrs
516165220Srrs	/* calculate the RTO */
517218186Srrs	net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy,
518219397Srrs	    SCTP_RTT_FROM_NON_DATA);
519165220Srrs
520163953Srrs	retval = sctp_send_cookie_echo(m, offset, stcb, net);
521163953Srrs	if (retval < 0) {
522163953Srrs		/*
523163953Srrs		 * No cookie, we probably should send a op error. But in any
524163953Srrs		 * case if there is no cookie in the INIT-ACK, we can
525163953Srrs		 * abandon the peer, its broke.
526163953Srrs		 */
527163953Srrs		if (retval == -3) {
528163953Srrs			/* We abort with an error of missing mandatory param */
529266181Stuexen			op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
530163953Srrs			if (op_err) {
531163953Srrs				/*
532163953Srrs				 * Expand beyond to include the mandatory
533163953Srrs				 * param cookie
534163953Srrs				 */
535163953Srrs				struct sctp_inv_mandatory_param *mp;
536163953Srrs
537165647Srrs				SCTP_BUF_LEN(op_err) =
538163953Srrs				    sizeof(struct sctp_inv_mandatory_param);
539163953Srrs				mp = mtod(op_err,
540163953Srrs				    struct sctp_inv_mandatory_param *);
541163953Srrs				/* Subtract the reserved param */
542163953Srrs				mp->length =
543163953Srrs				    htons(sizeof(struct sctp_inv_mandatory_param) - 2);
544163953Srrs				mp->num_param = htonl(1);
545163953Srrs				mp->param = htons(SCTP_STATE_COOKIE);
546163953Srrs				mp->resv = 0;
547163953Srrs			}
548163953Srrs			sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
549252889Stuexen			    src, dst, sh, op_err,
550238253Stuexen			    use_mflowid, mflowid,
551238253Stuexen			    vrf_id, net->port);
552168299Srrs			*abort_no_unlock = 1;
553163953Srrs		}
554163953Srrs		return (retval);
555163953Srrs	}
556163953Srrs	return (0);
557163953Srrs}
558163953Srrs
559163953Srrsstatic void
560163953Srrssctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
561163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net)
562163953Srrs{
563163953Srrs	struct sockaddr_storage store;
564212225Srrs	struct sctp_nets *r_net, *f_net;
565163953Srrs	struct timeval tv;
566172396Srrs	int req_prim = 0;
567224641Stuexen	uint16_t old_error_counter;
568163953Srrs
569221249Stuexen#ifdef INET
570221249Stuexen	struct sockaddr_in *sin;
571221249Stuexen
572221249Stuexen#endif
573221249Stuexen#ifdef INET6
574221249Stuexen	struct sockaddr_in6 *sin6;
575221249Stuexen
576221249Stuexen#endif
577221249Stuexen
578163953Srrs	if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
579163953Srrs		/* Invalid length */
580163953Srrs		return;
581163953Srrs	}
582163953Srrs	memset(&store, 0, sizeof(store));
583221249Stuexen	switch (cp->heartbeat.hb_info.addr_family) {
584221249Stuexen#ifdef INET
585221249Stuexen	case AF_INET:
586221249Stuexen		if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
587221249Stuexen			sin = (struct sockaddr_in *)&store;
588221249Stuexen			sin->sin_family = cp->heartbeat.hb_info.addr_family;
589221249Stuexen			sin->sin_len = cp->heartbeat.hb_info.addr_len;
590221249Stuexen			sin->sin_port = stcb->rport;
591221249Stuexen			memcpy(&sin->sin_addr, cp->heartbeat.hb_info.address,
592221249Stuexen			    sizeof(sin->sin_addr));
593221249Stuexen		} else {
594221249Stuexen			return;
595221249Stuexen		}
596221249Stuexen		break;
597221249Stuexen#endif
598221249Stuexen#ifdef INET6
599221249Stuexen	case AF_INET6:
600221249Stuexen		if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
601221249Stuexen			sin6 = (struct sockaddr_in6 *)&store;
602221249Stuexen			sin6->sin6_family = cp->heartbeat.hb_info.addr_family;
603221249Stuexen			sin6->sin6_len = cp->heartbeat.hb_info.addr_len;
604221249Stuexen			sin6->sin6_port = stcb->rport;
605221249Stuexen			memcpy(&sin6->sin6_addr, cp->heartbeat.hb_info.address,
606221249Stuexen			    sizeof(sin6->sin6_addr));
607221249Stuexen		} else {
608221249Stuexen			return;
609221249Stuexen		}
610221249Stuexen		break;
611221249Stuexen#endif
612221249Stuexen	default:
613163953Srrs		return;
614163953Srrs	}
615221249Stuexen	r_net = sctp_findnet(stcb, (struct sockaddr *)&store);
616163953Srrs	if (r_net == NULL) {
617169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "Huh? I can't find the address I sent it to, discard\n");
618163953Srrs		return;
619163953Srrs	}
620163953Srrs	if ((r_net && (r_net->dest_state & SCTP_ADDR_UNCONFIRMED)) &&
621163953Srrs	    (r_net->heartbeat_random1 == cp->heartbeat.hb_info.random_value1) &&
622163953Srrs	    (r_net->heartbeat_random2 == cp->heartbeat.hb_info.random_value2)) {
623163953Srrs		/*
624163953Srrs		 * If the its a HB and it's random value is correct when can
625163953Srrs		 * confirm the destination.
626163953Srrs		 */
627163953Srrs		r_net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
628167598Srrs		if (r_net->dest_state & SCTP_ADDR_REQ_PRIMARY) {
629167598Srrs			stcb->asoc.primary_destination = r_net;
630167598Srrs			r_net->dest_state &= ~SCTP_ADDR_REQ_PRIMARY;
631212225Srrs			f_net = TAILQ_FIRST(&stcb->asoc.nets);
632212225Srrs			if (f_net != r_net) {
633167598Srrs				/*
634167598Srrs				 * first one on the list is NOT the primary
635167598Srrs				 * sctp_cmpaddr() is much more efficent if
636167598Srrs				 * the primary is the first on the list,
637167598Srrs				 * make it so.
638167598Srrs				 */
639212225Srrs				TAILQ_REMOVE(&stcb->asoc.nets, r_net, sctp_next);
640212225Srrs				TAILQ_INSERT_HEAD(&stcb->asoc.nets, r_net, sctp_next);
641167598Srrs			}
642172396Srrs			req_prim = 1;
643167598Srrs		}
644163953Srrs		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
645172090Srrs		    stcb, 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
646224641Stuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
647224641Stuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
648163953Srrs	}
649224641Stuexen	old_error_counter = r_net->error_count;
650163953Srrs	r_net->error_count = 0;
651163953Srrs	r_net->hb_responded = 1;
652163953Srrs	tv.tv_sec = cp->heartbeat.hb_info.time_value_1;
653163953Srrs	tv.tv_usec = cp->heartbeat.hb_info.time_value_2;
654224641Stuexen	/* Now lets do a RTO with this */
655224641Stuexen	r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy,
656224641Stuexen	    SCTP_RTT_FROM_NON_DATA);
657224641Stuexen	if (!(r_net->dest_state & SCTP_ADDR_REACHABLE)) {
658163953Srrs		r_net->dest_state |= SCTP_ADDR_REACHABLE;
659163953Srrs		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb,
660237888Stuexen		    0, (void *)r_net, SCTP_SO_NOT_LOCKED);
661163953Srrs	}
662224641Stuexen	if (r_net->dest_state & SCTP_ADDR_PF) {
663224641Stuexen		r_net->dest_state &= ~SCTP_ADDR_PF;
664224641Stuexen		stcb->asoc.cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
665224641Stuexen	}
666224641Stuexen	if (old_error_counter > 0) {
667224641Stuexen		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
668224641Stuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
669224641Stuexen	}
670224641Stuexen	if (r_net == stcb->asoc.primary_destination) {
671224641Stuexen		if (stcb->asoc.alternate) {
672224641Stuexen			/* release the alternate, primary is good */
673224641Stuexen			sctp_free_remote_addr(stcb->asoc.alternate);
674224641Stuexen			stcb->asoc.alternate = NULL;
675171440Srrs		}
676171440Srrs	}
677172396Srrs	/* Mobility adaptation */
678172396Srrs	if (req_prim) {
679172396Srrs		if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
680172396Srrs		    SCTP_MOBILITY_BASE) ||
681172396Srrs		    sctp_is_mobility_feature_on(stcb->sctp_ep,
682172396Srrs		    SCTP_MOBILITY_FASTHANDOFF)) &&
683172396Srrs		    sctp_is_mobility_feature_on(stcb->sctp_ep,
684172396Srrs		    SCTP_MOBILITY_PRIM_DELETED)) {
685172396Srrs
686172396Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
687172396Srrs			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
688172396Srrs			    SCTP_MOBILITY_FASTHANDOFF)) {
689172396Srrs				sctp_assoc_immediate_retrans(stcb,
690172396Srrs				    stcb->asoc.primary_destination);
691172396Srrs			}
692172396Srrs			if (sctp_is_mobility_feature_on(stcb->sctp_ep,
693172396Srrs			    SCTP_MOBILITY_BASE)) {
694212712Stuexen				sctp_move_chunks_from_net(stcb,
695212712Stuexen				    stcb->asoc.deleted_primary);
696172396Srrs			}
697172396Srrs			sctp_delete_prim_timer(stcb->sctp_ep, stcb,
698172396Srrs			    stcb->asoc.deleted_primary);
699172396Srrs		}
700172396Srrs	}
701163953Srrs}
702163953Srrs
703185694Srrsstatic int
704185694Srrssctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
705185694Srrs{
706185694Srrs	/*
707185694Srrs	 * return 0 means we want you to proceed with the abort non-zero
708185694Srrs	 * means no abort processing
709185694Srrs	 */
710185694Srrs	struct sctpasochead *head;
711185694Srrs
712185694Srrs	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
713185694Srrs		/* generate a new vtag and send init */
714185694Srrs		LIST_REMOVE(stcb, sctp_asocs);
715185694Srrs		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
716185694Srrs		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
717185694Srrs		/*
718185694Srrs		 * put it in the bucket in the vtag hash of assoc's for the
719185694Srrs		 * system
720185694Srrs		 */
721185694Srrs		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
722185694Srrs		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
723185694Srrs		return (1);
724185694Srrs	}
725185694Srrs	if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
726185694Srrs		/*
727185694Srrs		 * treat like a case where the cookie expired i.e.: - dump
728185694Srrs		 * current cookie. - generate a new vtag. - resend init.
729185694Srrs		 */
730185694Srrs		/* generate a new vtag and send init */
731185694Srrs		LIST_REMOVE(stcb, sctp_asocs);
732185694Srrs		stcb->asoc.state &= ~SCTP_STATE_COOKIE_ECHOED;
733185694Srrs		stcb->asoc.state |= SCTP_STATE_COOKIE_WAIT;
734185694Srrs		sctp_stop_all_cookie_timers(stcb);
735185694Srrs		sctp_toss_old_cookies(stcb, &stcb->asoc);
736185694Srrs		stcb->asoc.my_vtag = sctp_select_a_tag(stcb->sctp_ep, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
737185694Srrs		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
738185694Srrs		/*
739185694Srrs		 * put it in the bucket in the vtag hash of assoc's for the
740185694Srrs		 * system
741185694Srrs		 */
742185694Srrs		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
743185694Srrs		sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
744185694Srrs		return (1);
745185694Srrs	}
746185694Srrs	return (0);
747185694Srrs}
748185694Srrs
749185694Srrsstatic int
750185694Srrssctp_handle_nat_missing_state(struct sctp_tcb *stcb,
751185694Srrs    struct sctp_nets *net)
752185694Srrs{
753185694Srrs	/*
754185694Srrs	 * return 0 means we want you to proceed with the abort non-zero
755185694Srrs	 * means no abort processing
756185694Srrs	 */
757185694Srrs	if (stcb->asoc.peer_supports_auth == 0) {
758185694Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_nat_missing_state: Peer does not support AUTH, cannot send an asconf\n");
759185694Srrs		return (0);
760185694Srrs	}
761185694Srrs	sctp_asconf_send_nat_state_update(stcb, net);
762185694Srrs	return (1);
763185694Srrs}
764185694Srrs
765185694Srrs
766163953Srrsstatic void
767237884Stuexensctp_handle_abort(struct sctp_abort_chunk *abort,
768163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net)
769163953Srrs{
770252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
771172090Srrs	struct socket *so;
772172090Srrs
773172090Srrs#endif
774185694Srrs	uint16_t len;
775237884Stuexen	uint16_t error;
776172090Srrs
777169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: handling ABORT\n");
778163953Srrs	if (stcb == NULL)
779163953Srrs		return;
780163953Srrs
781237884Stuexen	len = ntohs(abort->ch.chunk_length);
782185694Srrs	if (len > sizeof(struct sctp_chunkhdr)) {
783185694Srrs		/*
784185694Srrs		 * Need to check the cause codes for our two magic nat
785185694Srrs		 * aborts which don't kill the assoc necessarily.
786185694Srrs		 */
787185694Srrs		struct sctp_missing_nat_state *natc;
788185694Srrs
789237884Stuexen		natc = (struct sctp_missing_nat_state *)(abort + 1);
790237884Stuexen		error = ntohs(natc->cause);
791237884Stuexen		if (error == SCTP_CAUSE_NAT_COLLIDING_STATE) {
792185694Srrs			SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
793237884Stuexen			    abort->ch.chunk_flags);
794185694Srrs			if (sctp_handle_nat_colliding_state(stcb)) {
795185694Srrs				return;
796185694Srrs			}
797237884Stuexen		} else if (error == SCTP_CAUSE_NAT_MISSING_STATE) {
798185694Srrs			SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
799237884Stuexen			    abort->ch.chunk_flags);
800185694Srrs			if (sctp_handle_nat_missing_state(stcb, net)) {
801185694Srrs				return;
802185694Srrs			}
803185694Srrs		}
804237884Stuexen	} else {
805237884Stuexen		error = 0;
806185694Srrs	}
807163953Srrs	/* stop any receive timers */
808171440Srrs	sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
809163953Srrs	/* notify user of the abort and clean up... */
810237886Stuexen	sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
811163953Srrs	/* free the tcb */
812163953Srrs	SCTP_STAT_INCR_COUNTER32(sctps_aborted);
813163953Srrs	if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
814163953Srrs	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
815163953Srrs		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
816163953Srrs	}
817168859Srrs#ifdef SCTP_ASOCLOG_OF_TSNS
818168859Srrs	sctp_print_out_track_log(stcb);
819168859Srrs#endif
820252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
821172090Srrs	so = SCTP_INP_SO(stcb->sctp_ep);
822172090Srrs	atomic_add_int(&stcb->asoc.refcnt, 1);
823172090Srrs	SCTP_TCB_UNLOCK(stcb);
824172090Srrs	SCTP_SOCKET_LOCK(so, 1);
825172090Srrs	SCTP_TCB_LOCK(stcb);
826172090Srrs	atomic_subtract_int(&stcb->asoc.refcnt, 1);
827172090Srrs#endif
828171990Srrs	stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
829171943Srrs	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
830171943Srrs	    SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
831252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
832172090Srrs	SCTP_SOCKET_UNLOCK(so, 1);
833172090Srrs#endif
834169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_abort: finished\n");
835163953Srrs}
836163953Srrs
837163953Srrsstatic void
838224641Stuexensctp_start_net_timers(struct sctp_tcb *stcb)
839224641Stuexen{
840224641Stuexen	uint32_t cnt_hb_sent;
841224641Stuexen	struct sctp_nets *net;
842224641Stuexen
843224641Stuexen	cnt_hb_sent = 0;
844224641Stuexen	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
845224641Stuexen		/*
846224641Stuexen		 * For each network start: 1) A pmtu timer. 2) A HB timer 3)
847224641Stuexen		 * If the dest in unconfirmed send a hb as well if under
848224641Stuexen		 * max_hb_burst have been sent.
849224641Stuexen		 */
850224641Stuexen		sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
851224641Stuexen		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
852224641Stuexen		if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
853224641Stuexen		    (cnt_hb_sent < SCTP_BASE_SYSCTL(sctp_hb_maxburst))) {
854224641Stuexen			sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
855224641Stuexen			cnt_hb_sent++;
856224641Stuexen		}
857224641Stuexen	}
858224641Stuexen	if (cnt_hb_sent) {
859224641Stuexen		sctp_chunk_output(stcb->sctp_ep, stcb,
860224641Stuexen		    SCTP_OUTPUT_FROM_COOKIE_ACK,
861224641Stuexen		    SCTP_SO_NOT_LOCKED);
862224641Stuexen	}
863224641Stuexen}
864224641Stuexen
865224641Stuexen
866224641Stuexenstatic void
867163953Srrssctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
868163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net, int *abort_flag)
869163953Srrs{
870163953Srrs	struct sctp_association *asoc;
871163953Srrs	int some_on_streamwheel;
872163953Srrs
873252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
874172090Srrs	struct socket *so;
875172090Srrs
876172090Srrs#endif
877172090Srrs
878169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
879169420Srrs	    "sctp_handle_shutdown: handling SHUTDOWN\n");
880163953Srrs	if (stcb == NULL)
881163953Srrs		return;
882165220Srrs	asoc = &stcb->asoc;
883165220Srrs	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
884165220Srrs	    (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
885163953Srrs		return;
886163953Srrs	}
887163953Srrs	if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_shutdown_chunk)) {
888163953Srrs		/* Shutdown NOT the expected size */
889163953Srrs		return;
890163953Srrs	} else {
891231038Stuexen		sctp_update_acked(stcb, cp, abort_flag);
892199477Stuexen		if (*abort_flag) {
893199477Stuexen			return;
894199477Stuexen		}
895163953Srrs	}
896165220Srrs	if (asoc->control_pdapi) {
897163953Srrs		/*
898163953Srrs		 * With a normal shutdown we assume the end of last record.
899163953Srrs		 */
900163953Srrs		SCTP_INP_READ_LOCK(stcb->sctp_ep);
901165220Srrs		asoc->control_pdapi->end_added = 1;
902165220Srrs		asoc->control_pdapi->pdapi_aborted = 1;
903165220Srrs		asoc->control_pdapi = NULL;
904163953Srrs		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
905252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
906172090Srrs		so = SCTP_INP_SO(stcb->sctp_ep);
907172090Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
908172090Srrs		SCTP_TCB_UNLOCK(stcb);
909172090Srrs		SCTP_SOCKET_LOCK(so, 1);
910172090Srrs		SCTP_TCB_LOCK(stcb);
911172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
912172090Srrs		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
913172090Srrs			/* assoc was freed while we were unlocked */
914172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
915172090Srrs			return;
916172090Srrs		}
917172090Srrs#endif
918163996Srrs		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
919252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
920172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
921172090Srrs#endif
922163953Srrs	}
923163953Srrs	/* goto SHUTDOWN_RECEIVED state to block new requests */
924163953Srrs	if (stcb->sctp_socket) {
925163953Srrs		if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
926170056Srrs		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) &&
927163953Srrs		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
928171943Srrs			SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_RECEIVED);
929172703Srrs			SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
930163953Srrs			/*
931163953Srrs			 * notify upper layer that peer has initiated a
932163953Srrs			 * shutdown
933163953Srrs			 */
934172090Srrs			sctp_ulp_notify(SCTP_NOTIFY_PEER_SHUTDOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
935163953Srrs
936163953Srrs			/* reset time */
937169378Srrs			(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
938163953Srrs		}
939163953Srrs	}
940163953Srrs	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_SENT) {
941163953Srrs		/*
942163953Srrs		 * stop the shutdown timer, since we WILL move to
943163953Srrs		 * SHUTDOWN-ACK-SENT.
944163953Srrs		 */
945171440Srrs		sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
946163953Srrs	}
947171158Srrs	/* Now is there unsent data on a stream somewhere? */
948221627Stuexen	some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
949163953Srrs
950163953Srrs	if (!TAILQ_EMPTY(&asoc->send_queue) ||
951163953Srrs	    !TAILQ_EMPTY(&asoc->sent_queue) ||
952163953Srrs	    some_on_streamwheel) {
953163953Srrs		/* By returning we will push more data out */
954163953Srrs		return;
955163953Srrs	} else {
956163953Srrs		/* no outstanding data to send, so move on... */
957163953Srrs		/* send SHUTDOWN-ACK */
958163953Srrs		/* move to SHUTDOWN-ACK-SENT state */
959166675Srrs		if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
960166675Srrs		    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
961163953Srrs			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
962163953Srrs		}
963171943Srrs		SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
964172703Srrs		SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
965214918Stuexen		sctp_stop_timers_for_shutdown(stcb);
966252960Stuexen		sctp_send_shutdown_ack(stcb, net);
967163953Srrs		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
968163953Srrs		    stcb, net);
969163953Srrs	}
970163953Srrs}
971163953Srrs
972163953Srrsstatic void
973231038Stuexensctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
974204141Stuexen    struct sctp_tcb *stcb,
975204141Stuexen    struct sctp_nets *net)
976163953Srrs{
977163953Srrs	struct sctp_association *asoc;
978163953Srrs
979252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
980172090Srrs	struct socket *so;
981172090Srrs
982172090Srrs	so = SCTP_INP_SO(stcb->sctp_ep);
983172090Srrs#endif
984169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
985169420Srrs	    "sctp_handle_shutdown_ack: handling SHUTDOWN ACK\n");
986163953Srrs	if (stcb == NULL)
987163953Srrs		return;
988163953Srrs
989163953Srrs	asoc = &stcb->asoc;
990163953Srrs	/* process according to association state */
991204141Stuexen	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_WAIT) ||
992204141Stuexen	    (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)) {
993204141Stuexen		/* unexpected SHUTDOWN-ACK... do OOTB handling... */
994204141Stuexen		sctp_send_shutdown_complete(stcb, net, 1);
995204141Stuexen		SCTP_TCB_UNLOCK(stcb);
996204141Stuexen		return;
997204141Stuexen	}
998163953Srrs	if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
999163953Srrs	    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
1000163953Srrs		/* unexpected SHUTDOWN-ACK... so ignore... */
1001163953Srrs		SCTP_TCB_UNLOCK(stcb);
1002163953Srrs		return;
1003163953Srrs	}
1004165220Srrs	if (asoc->control_pdapi) {
1005163953Srrs		/*
1006163953Srrs		 * With a normal shutdown we assume the end of last record.
1007163953Srrs		 */
1008163953Srrs		SCTP_INP_READ_LOCK(stcb->sctp_ep);
1009165220Srrs		asoc->control_pdapi->end_added = 1;
1010165220Srrs		asoc->control_pdapi->pdapi_aborted = 1;
1011165220Srrs		asoc->control_pdapi = NULL;
1012163953Srrs		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
1013252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1014172090Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
1015172090Srrs		SCTP_TCB_UNLOCK(stcb);
1016172090Srrs		SCTP_SOCKET_LOCK(so, 1);
1017172090Srrs		SCTP_TCB_LOCK(stcb);
1018172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
1019172090Srrs		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
1020172090Srrs			/* assoc was freed while we were unlocked */
1021172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
1022172090Srrs			return;
1023172090Srrs		}
1024172090Srrs#endif
1025163996Srrs		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
1026252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1027172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
1028172090Srrs#endif
1029163953Srrs	}
1030252976Stuexen#ifdef INVARIANTS
1031163953Srrs	if (!TAILQ_EMPTY(&asoc->send_queue) ||
1032163953Srrs	    !TAILQ_EMPTY(&asoc->sent_queue) ||
1033217760Stuexen	    !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
1034252976Stuexen		panic("Queues are not empty when handling SHUTDOWN-ACK");
1035163953Srrs	}
1036252976Stuexen#endif
1037163953Srrs	/* stop the timer */
1038171440Srrs	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
1039163953Srrs	/* send SHUTDOWN-COMPLETE */
1040204141Stuexen	sctp_send_shutdown_complete(stcb, net, 0);
1041163953Srrs	/* notify upper layer protocol */
1042163953Srrs	if (stcb->sctp_socket) {
1043163953Srrs		if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
1044163953Srrs		    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
1045231041Stuexen			stcb->sctp_socket->so_snd.sb_cc = 0;
1046163953Srrs		}
1047231052Stuexen		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
1048163953Srrs	}
1049163953Srrs	SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
1050163953Srrs	/* free the TCB but first save off the ep */
1051252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1052172090Srrs	atomic_add_int(&stcb->asoc.refcnt, 1);
1053172090Srrs	SCTP_TCB_UNLOCK(stcb);
1054172090Srrs	SCTP_SOCKET_LOCK(so, 1);
1055172090Srrs	SCTP_TCB_LOCK(stcb);
1056172090Srrs	atomic_subtract_int(&stcb->asoc.refcnt, 1);
1057172090Srrs#endif
1058171943Srrs	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
1059171440Srrs	    SCTP_FROM_SCTP_INPUT + SCTP_LOC_10);
1060252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1061172090Srrs	SCTP_SOCKET_UNLOCK(so, 1);
1062172090Srrs#endif
1063163953Srrs}
1064163953Srrs
1065163953Srrs/*
1066163953Srrs * Skip past the param header and then we will find the chunk that caused the
1067163953Srrs * problem. There are two possiblities ASCONF or FWD-TSN other than that and
1068163953Srrs * our peer must be broken.
1069163953Srrs */
1070163953Srrsstatic void
1071163953Srrssctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr,
1072163953Srrs    struct sctp_nets *net)
1073163953Srrs{
1074163953Srrs	struct sctp_chunkhdr *chk;
1075163953Srrs
1076163953Srrs	chk = (struct sctp_chunkhdr *)((caddr_t)phdr + sizeof(*phdr));
1077163953Srrs	switch (chk->chunk_type) {
1078163953Srrs	case SCTP_ASCONF_ACK:
1079163953Srrs	case SCTP_ASCONF:
1080163953Srrs		sctp_asconf_cleanup(stcb, net);
1081163953Srrs		break;
1082163953Srrs	case SCTP_FORWARD_CUM_TSN:
1083163953Srrs		stcb->asoc.peer_supports_prsctp = 0;
1084163953Srrs		break;
1085163953Srrs	default:
1086169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
1087169420Srrs		    "Peer does not support chunk type %d(%x)??\n",
1088169420Srrs		    chk->chunk_type, (uint32_t) chk->chunk_type);
1089163953Srrs		break;
1090163953Srrs	}
1091163953Srrs}
1092163953Srrs
1093163953Srrs/*
1094163953Srrs * Skip past the param header and then we will find the param that caused the
1095163953Srrs * problem.  There are a number of param's in a ASCONF OR the prsctp param
1096163953Srrs * these will turn of specific features.
1097163953Srrs */
1098163953Srrsstatic void
1099163953Srrssctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
1100163953Srrs{
1101163953Srrs	struct sctp_paramhdr *pbad;
1102163953Srrs
1103163953Srrs	pbad = phdr + 1;
1104163953Srrs	switch (ntohs(pbad->param_type)) {
1105163953Srrs		/* pr-sctp draft */
1106163953Srrs	case SCTP_PRSCTP_SUPPORTED:
1107163953Srrs		stcb->asoc.peer_supports_prsctp = 0;
1108163953Srrs		break;
1109163953Srrs	case SCTP_SUPPORTED_CHUNK_EXT:
1110163953Srrs		break;
1111163953Srrs		/* draft-ietf-tsvwg-addip-sctp */
1112185694Srrs	case SCTP_HAS_NAT_SUPPORT:
1113185694Srrs		stcb->asoc.peer_supports_nat = 0;
1114185694Srrs		break;
1115163953Srrs	case SCTP_ADD_IP_ADDRESS:
1116163953Srrs	case SCTP_DEL_IP_ADDRESS:
1117163953Srrs	case SCTP_SET_PRIM_ADDR:
1118163953Srrs		stcb->asoc.peer_supports_asconf = 0;
1119163953Srrs		break;
1120163953Srrs	case SCTP_SUCCESS_REPORT:
1121163953Srrs	case SCTP_ERROR_CAUSE_IND:
1122169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "Huh, the peer does not support success? or error cause?\n");
1123169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
1124169420Srrs		    "Turning off ASCONF to this strange peer\n");
1125163953Srrs		stcb->asoc.peer_supports_asconf = 0;
1126163953Srrs		break;
1127163953Srrs	default:
1128169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
1129169420Srrs		    "Peer does not support param type %d(%x)??\n",
1130169420Srrs		    pbad->param_type, (uint32_t) pbad->param_type);
1131163953Srrs		break;
1132163953Srrs	}
1133163953Srrs}
1134163953Srrs
1135163953Srrsstatic int
1136163953Srrssctp_handle_error(struct sctp_chunkhdr *ch,
1137163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net)
1138163953Srrs{
1139163953Srrs	int chklen;
1140163953Srrs	struct sctp_paramhdr *phdr;
1141237890Stuexen	uint16_t error, error_type;
1142163953Srrs	uint16_t error_len;
1143163953Srrs	struct sctp_association *asoc;
1144163953Srrs	int adjust;
1145163953Srrs
1146252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1147172090Srrs	struct socket *so;
1148172090Srrs
1149172090Srrs#endif
1150172090Srrs
1151163953Srrs	/* parse through all of the errors and process */
1152163953Srrs	asoc = &stcb->asoc;
1153163953Srrs	phdr = (struct sctp_paramhdr *)((caddr_t)ch +
1154163953Srrs	    sizeof(struct sctp_chunkhdr));
1155163953Srrs	chklen = ntohs(ch->chunk_length) - sizeof(struct sctp_chunkhdr);
1156237890Stuexen	error = 0;
1157163953Srrs	while ((size_t)chklen >= sizeof(struct sctp_paramhdr)) {
1158163953Srrs		/* Process an Error Cause */
1159163953Srrs		error_type = ntohs(phdr->param_type);
1160163953Srrs		error_len = ntohs(phdr->param_length);
1161163953Srrs		if ((error_len > chklen) || (error_len == 0)) {
1162163953Srrs			/* invalid param length for this param */
1163169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT1, "Bogus length in error param- chunk left:%d errorlen:%d\n",
1164169420Srrs			    chklen, error_len);
1165163953Srrs			return (0);
1166163953Srrs		}
1167237890Stuexen		if (error == 0) {
1168237890Stuexen			/* report the first error cause */
1169237890Stuexen			error = error_type;
1170237890Stuexen		}
1171163953Srrs		switch (error_type) {
1172163953Srrs		case SCTP_CAUSE_INVALID_STREAM:
1173163953Srrs		case SCTP_CAUSE_MISSING_PARAM:
1174163953Srrs		case SCTP_CAUSE_INVALID_PARAM:
1175163953Srrs		case SCTP_CAUSE_NO_USER_DATA:
1176169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT1, "Software error we got a %d back? We have a bug :/ (or do they?)\n",
1177169420Srrs			    error_type);
1178163953Srrs			break;
1179185694Srrs		case SCTP_CAUSE_NAT_COLLIDING_STATE:
1180185694Srrs			SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state abort flags:%x\n",
1181185694Srrs			    ch->chunk_flags);
1182185694Srrs			if (sctp_handle_nat_colliding_state(stcb)) {
1183185694Srrs				return (0);
1184185694Srrs			}
1185185694Srrs			break;
1186185694Srrs		case SCTP_CAUSE_NAT_MISSING_STATE:
1187185694Srrs			SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state abort flags:%x\n",
1188185694Srrs			    ch->chunk_flags);
1189185694Srrs			if (sctp_handle_nat_missing_state(stcb, net)) {
1190185694Srrs				return (0);
1191185694Srrs			}
1192185694Srrs			break;
1193163953Srrs		case SCTP_CAUSE_STALE_COOKIE:
1194163953Srrs			/*
1195163953Srrs			 * We only act if we have echoed a cookie and are
1196163953Srrs			 * waiting.
1197163953Srrs			 */
1198163953Srrs			if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
1199163953Srrs				int *p;
1200163953Srrs
1201163953Srrs				p = (int *)((caddr_t)phdr + sizeof(*phdr));
1202163953Srrs				/* Save the time doubled */
1203163953Srrs				asoc->cookie_preserve_req = ntohl(*p) << 1;
1204163953Srrs				asoc->stale_cookie_count++;
1205163953Srrs				if (asoc->stale_cookie_count >
1206163953Srrs				    asoc->max_init_times) {
1207237886Stuexen					sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
1208163953Srrs					/* now free the asoc */
1209252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1210172090Srrs					so = SCTP_INP_SO(stcb->sctp_ep);
1211172090Srrs					atomic_add_int(&stcb->asoc.refcnt, 1);
1212172090Srrs					SCTP_TCB_UNLOCK(stcb);
1213172090Srrs					SCTP_SOCKET_LOCK(so, 1);
1214172090Srrs					SCTP_TCB_LOCK(stcb);
1215172090Srrs					atomic_subtract_int(&stcb->asoc.refcnt, 1);
1216172090Srrs#endif
1217171943Srrs					(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
1218171943Srrs					    SCTP_FROM_SCTP_INPUT + SCTP_LOC_11);
1219252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1220172090Srrs					SCTP_SOCKET_UNLOCK(so, 1);
1221172090Srrs#endif
1222163953Srrs					return (-1);
1223163953Srrs				}
1224163953Srrs				/* blast back to INIT state */
1225185694Srrs				sctp_toss_old_cookies(stcb, &stcb->asoc);
1226163953Srrs				asoc->state &= ~SCTP_STATE_COOKIE_ECHOED;
1227163953Srrs				asoc->state |= SCTP_STATE_COOKIE_WAIT;
1228163953Srrs				sctp_stop_all_cookie_timers(stcb);
1229172090Srrs				sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
1230163953Srrs			}
1231163953Srrs			break;
1232163953Srrs		case SCTP_CAUSE_UNRESOLVABLE_ADDR:
1233163953Srrs			/*
1234163953Srrs			 * Nothing we can do here, we don't do hostname
1235163953Srrs			 * addresses so if the peer does not like my IPv6
1236163953Srrs			 * (or IPv4 for that matter) it does not matter. If
1237163953Srrs			 * they don't support that type of address, they can
1238163953Srrs			 * NOT possibly get that packet type... i.e. with no
1239163953Srrs			 * IPv6 you can't recieve a IPv6 packet. so we can
1240163953Srrs			 * safely ignore this one. If we ever added support
1241163953Srrs			 * for HOSTNAME Addresses, then we would need to do
1242163953Srrs			 * something here.
1243163953Srrs			 */
1244163953Srrs			break;
1245163953Srrs		case SCTP_CAUSE_UNRECOG_CHUNK:
1246163953Srrs			sctp_process_unrecog_chunk(stcb, phdr, net);
1247163953Srrs			break;
1248163953Srrs		case SCTP_CAUSE_UNRECOG_PARAM:
1249163953Srrs			sctp_process_unrecog_param(stcb, phdr);
1250163953Srrs			break;
1251163953Srrs		case SCTP_CAUSE_COOKIE_IN_SHUTDOWN:
1252163953Srrs			/*
1253163953Srrs			 * We ignore this since the timer will drive out a
1254163953Srrs			 * new cookie anyway and there timer will drive us
1255163953Srrs			 * to send a SHUTDOWN_COMPLETE. We can't send one
1256163953Srrs			 * here since we don't have their tag.
1257163953Srrs			 */
1258163953Srrs			break;
1259163953Srrs		case SCTP_CAUSE_DELETING_LAST_ADDR:
1260163953Srrs		case SCTP_CAUSE_RESOURCE_SHORTAGE:
1261163953Srrs		case SCTP_CAUSE_DELETING_SRC_ADDR:
1262163953Srrs			/*
1263163953Srrs			 * We should NOT get these here, but in a
1264166086Srrs			 * ASCONF-ACK.
1265163953Srrs			 */
1266169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT2, "Peer sends ASCONF errors in a Operational Error?<%d>?\n",
1267169420Srrs			    error_type);
1268163953Srrs			break;
1269163953Srrs		case SCTP_CAUSE_OUT_OF_RESC:
1270163953Srrs			/*
1271163953Srrs			 * And what, pray tell do we do with the fact that
1272163953Srrs			 * the peer is out of resources? Not really sure we
1273166086Srrs			 * could do anything but abort. I suspect this
1274163953Srrs			 * should have came WITH an abort instead of in a
1275163953Srrs			 * OP-ERROR.
1276163953Srrs			 */
1277163953Srrs			break;
1278163953Srrs		default:
1279169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_handle_error: unknown error type = 0x%xh\n",
1280169420Srrs			    error_type);
1281163953Srrs			break;
1282163953Srrs		}
1283163953Srrs		adjust = SCTP_SIZE32(error_len);
1284163953Srrs		chklen -= adjust;
1285163953Srrs		phdr = (struct sctp_paramhdr *)((caddr_t)phdr + adjust);
1286163953Srrs	}
1287237890Stuexen	sctp_ulp_notify(SCTP_NOTIFY_REMOTE_ERROR, stcb, error, ch, SCTP_SO_NOT_LOCKED);
1288163953Srrs	return (0);
1289163953Srrs}
1290163953Srrs
1291163953Srrsstatic int
1292252889Stuexensctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
1293252889Stuexen    struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
1294238253Stuexen    struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
1295238253Stuexen    struct sctp_nets *net, int *abort_no_unlock,
1296238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
1297238253Stuexen    uint32_t vrf_id)
1298163953Srrs{
1299163953Srrs	struct sctp_init_ack *init_ack;
1300163953Srrs	struct mbuf *op_err;
1301163953Srrs
1302169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
1303169420Srrs	    "sctp_handle_init_ack: handling INIT-ACK\n");
1304169420Srrs
1305163953Srrs	if (stcb == NULL) {
1306169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
1307169420Srrs		    "sctp_handle_init_ack: TCB is null\n");
1308163953Srrs		return (-1);
1309163953Srrs	}
1310163953Srrs	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
1311163953Srrs		/* Invalid length */
1312266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1313252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1314252889Stuexen		    src, dst, sh, op_err,
1315238253Stuexen		    use_mflowid, mflowid,
1316238253Stuexen		    vrf_id, net->port);
1317168299Srrs		*abort_no_unlock = 1;
1318163953Srrs		return (-1);
1319163953Srrs	}
1320163953Srrs	init_ack = &cp->init;
1321163953Srrs	/* validate parameters */
1322163953Srrs	if (init_ack->initiate_tag == 0) {
1323163953Srrs		/* protocol error... send an abort */
1324266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1325252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1326252889Stuexen		    src, dst, sh, op_err,
1327238253Stuexen		    use_mflowid, mflowid,
1328238253Stuexen		    vrf_id, net->port);
1329168299Srrs		*abort_no_unlock = 1;
1330163953Srrs		return (-1);
1331163953Srrs	}
1332163953Srrs	if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
1333163953Srrs		/* protocol error... send an abort */
1334266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1335252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1336252889Stuexen		    src, dst, sh, op_err,
1337238253Stuexen		    use_mflowid, mflowid,
1338238253Stuexen		    vrf_id, net->port);
1339168299Srrs		*abort_no_unlock = 1;
1340163953Srrs		return (-1);
1341163953Srrs	}
1342163953Srrs	if (init_ack->num_inbound_streams == 0) {
1343163953Srrs		/* protocol error... send an abort */
1344266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1345252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1346252889Stuexen		    src, dst, sh, op_err,
1347238253Stuexen		    use_mflowid, mflowid,
1348238253Stuexen		    vrf_id, net->port);
1349168299Srrs		*abort_no_unlock = 1;
1350163953Srrs		return (-1);
1351163953Srrs	}
1352163953Srrs	if (init_ack->num_outbound_streams == 0) {
1353163953Srrs		/* protocol error... send an abort */
1354266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
1355252889Stuexen		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
1356252889Stuexen		    src, dst, sh, op_err,
1357238253Stuexen		    use_mflowid, mflowid,
1358238253Stuexen		    vrf_id, net->port);
1359168299Srrs		*abort_no_unlock = 1;
1360163953Srrs		return (-1);
1361163953Srrs	}
1362163953Srrs	/* process according to association state... */
1363171943Srrs	switch (stcb->asoc.state & SCTP_STATE_MASK) {
1364163953Srrs	case SCTP_STATE_COOKIE_WAIT:
1365163953Srrs		/* this is the expected state for this chunk */
1366163953Srrs		/* process the INIT-ACK parameters */
1367163953Srrs		if (stcb->asoc.primary_destination->dest_state &
1368163953Srrs		    SCTP_ADDR_UNCONFIRMED) {
1369163953Srrs			/*
1370163953Srrs			 * The primary is where we sent the INIT, we can
1371163953Srrs			 * always consider it confirmed when the INIT-ACK is
1372163953Srrs			 * returned. Do this before we load addresses
1373163953Srrs			 * though.
1374163953Srrs			 */
1375163953Srrs			stcb->asoc.primary_destination->dest_state &=
1376163953Srrs			    ~SCTP_ADDR_UNCONFIRMED;
1377163953Srrs			sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
1378172090Srrs			    stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED);
1379163953Srrs		}
1380252889Stuexen		if (sctp_process_init_ack(m, iphlen, offset, src, dst, sh, cp, stcb,
1381238253Stuexen		    net, abort_no_unlock,
1382238253Stuexen		    use_mflowid, mflowid,
1383238253Stuexen		    vrf_id) < 0) {
1384163953Srrs			/* error in parsing parameters */
1385163953Srrs			return (-1);
1386163953Srrs		}
1387163953Srrs		/* update our state */
1388169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "moving to COOKIE-ECHOED state\n");
1389171943Srrs		SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_ECHOED);
1390163953Srrs
1391163953Srrs		/* reset the RTO calc */
1392179783Srrs		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1393171943Srrs			sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1394171943Srrs			    stcb->asoc.overall_error_count,
1395171943Srrs			    0,
1396171943Srrs			    SCTP_FROM_SCTP_INPUT,
1397171943Srrs			    __LINE__);
1398171943Srrs		}
1399163953Srrs		stcb->asoc.overall_error_count = 0;
1400169378Srrs		(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1401163953Srrs		/*
1402163953Srrs		 * collapse the init timer back in case of a exponential
1403165220Srrs		 * backoff
1404163953Srrs		 */
1405163953Srrs		sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, stcb->sctp_ep,
1406163953Srrs		    stcb, net);
1407163953Srrs		/*
1408163953Srrs		 * the send at the end of the inbound data processing will
1409163953Srrs		 * cause the cookie to be sent
1410163953Srrs		 */
1411163953Srrs		break;
1412163953Srrs	case SCTP_STATE_SHUTDOWN_SENT:
1413163953Srrs		/* incorrect state... discard */
1414163953Srrs		break;
1415163953Srrs	case SCTP_STATE_COOKIE_ECHOED:
1416163953Srrs		/* incorrect state... discard */
1417163953Srrs		break;
1418163953Srrs	case SCTP_STATE_OPEN:
1419163953Srrs		/* incorrect state... discard */
1420163953Srrs		break;
1421163953Srrs	case SCTP_STATE_EMPTY:
1422163953Srrs	case SCTP_STATE_INUSE:
1423163953Srrs	default:
1424163953Srrs		/* incorrect state... discard */
1425163953Srrs		return (-1);
1426163953Srrs		break;
1427163953Srrs	}
1428169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT1, "Leaving handle-init-ack end\n");
1429163953Srrs	return (0);
1430163953Srrs}
1431163953Srrs
1432185694Srrsstatic struct sctp_tcb *
1433185694Srrssctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
1434252889Stuexen    struct sockaddr *src, struct sockaddr *dst,
1435185694Srrs    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
1436185694Srrs    struct sctp_inpcb *inp, struct sctp_nets **netp,
1437185694Srrs    struct sockaddr *init_src, int *notification,
1438185694Srrs    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
1439238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
1440185694Srrs    uint32_t vrf_id, uint16_t port);
1441163953Srrs
1442185694Srrs
1443163953Srrs/*
1444163953Srrs * handle a state cookie for an existing association m: input packet mbuf
1445163953Srrs * chain-- assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a
1446163953Srrs * "split" mbuf and the cookie signature does not exist offset: offset into
1447163953Srrs * mbuf to the cookie-echo chunk
1448163953Srrs */
1449163953Srrsstatic struct sctp_tcb *
1450163953Srrssctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
1451252889Stuexen    struct sockaddr *src, struct sockaddr *dst,
1452163953Srrs    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
1453185694Srrs    struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp,
1454231038Stuexen    struct sockaddr *init_src, int *notification,
1455238253Stuexen    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
1456238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
1457238253Stuexen    uint32_t vrf_id, uint16_t port)
1458163953Srrs{
1459163953Srrs	struct sctp_association *asoc;
1460163953Srrs	struct sctp_init_chunk *init_cp, init_buf;
1461163953Srrs	struct sctp_init_ack_chunk *initack_cp, initack_buf;
1462185694Srrs	struct sctp_nets *net;
1463185694Srrs	struct mbuf *op_err;
1464165220Srrs	int init_offset, initack_offset, i;
1465163953Srrs	int retval;
1466164205Srrs	int spec_flag = 0;
1467170140Srrs	uint32_t how_indx;
1468163953Srrs
1469185694Srrs	net = *netp;
1470163953Srrs	/* I know that the TCB is non-NULL from the caller */
1471163953Srrs	asoc = &stcb->asoc;
1472166675Srrs	for (how_indx = 0; how_indx < sizeof(asoc->cookie_how); how_indx++) {
1473166023Srrs		if (asoc->cookie_how[how_indx] == 0)
1474166023Srrs			break;
1475166023Srrs	}
1476166023Srrs	if (how_indx < sizeof(asoc->cookie_how)) {
1477166023Srrs		asoc->cookie_how[how_indx] = 1;
1478166023Srrs	}
1479163953Srrs	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
1480163953Srrs		/* SHUTDOWN came in after sending INIT-ACK */
1481163953Srrs		sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
1482266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
1483252889Stuexen		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
1484238253Stuexen		    use_mflowid, mflowid,
1485179157Srrs		    vrf_id, net->port);
1486166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1487166023Srrs			asoc->cookie_how[how_indx] = 2;
1488163953Srrs		return (NULL);
1489163953Srrs	}
1490163953Srrs	/*
1491163953Srrs	 * find and validate the INIT chunk in the cookie (peer's info) the
1492163953Srrs	 * INIT should start after the cookie-echo header struct (chunk
1493163953Srrs	 * header, state cookie header struct)
1494163953Srrs	 */
1495163953Srrs	init_offset = offset += sizeof(struct sctp_cookie_echo_chunk);
1496163953Srrs
1497163953Srrs	init_cp = (struct sctp_init_chunk *)
1498163953Srrs	    sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
1499163953Srrs	    (uint8_t *) & init_buf);
1500163953Srrs	if (init_cp == NULL) {
1501163953Srrs		/* could not pull a INIT chunk in cookie */
1502163953Srrs		return (NULL);
1503163953Srrs	}
1504163953Srrs	if (init_cp->ch.chunk_type != SCTP_INITIATION) {
1505163953Srrs		return (NULL);
1506163953Srrs	}
1507163953Srrs	/*
1508163953Srrs	 * find and validate the INIT-ACK chunk in the cookie (my info) the
1509163953Srrs	 * INIT-ACK follows the INIT chunk
1510163953Srrs	 */
1511231039Stuexen	initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
1512163953Srrs	initack_cp = (struct sctp_init_ack_chunk *)
1513163953Srrs	    sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
1514163953Srrs	    (uint8_t *) & initack_buf);
1515163953Srrs	if (initack_cp == NULL) {
1516163953Srrs		/* could not pull INIT-ACK chunk in cookie */
1517163953Srrs		return (NULL);
1518163953Srrs	}
1519163953Srrs	if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
1520163953Srrs		return (NULL);
1521163953Srrs	}
1522163953Srrs	if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
1523163953Srrs	    (ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag)) {
1524163953Srrs		/*
1525163953Srrs		 * case D in Section 5.2.4 Table 2: MMAA process accordingly
1526163953Srrs		 * to get into the OPEN state
1527163953Srrs		 */
1528166023Srrs		if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
1529172091Srrs			/*-
1530172091Srrs			 * Opps, this means that we somehow generated two vtag's
1531172091Srrs			 * the same. I.e. we did:
1532172091Srrs			 *  Us               Peer
1533172091Srrs			 *   <---INIT(tag=a)------
1534172091Srrs			 *   ----INIT-ACK(tag=t)-->
1535172091Srrs			 *   ----INIT(tag=t)------> *1
1536172091Srrs			 *   <---INIT-ACK(tag=a)---
1537172091Srrs                         *   <----CE(tag=t)------------- *2
1538172091Srrs			 *
1539172091Srrs			 * At point *1 we should be generating a different
1540172091Srrs			 * tag t'. Which means we would throw away the CE and send
1541172091Srrs			 * ours instead. Basically this is case C (throw away side).
1542172091Srrs			 */
1543172091Srrs			if (how_indx < sizeof(asoc->cookie_how))
1544172091Srrs				asoc->cookie_how[how_indx] = 17;
1545172091Srrs			return (NULL);
1546172091Srrs
1547166023Srrs		}
1548266071Stuexen		switch (SCTP_GET_STATE(asoc)) {
1549163953Srrs		case SCTP_STATE_COOKIE_WAIT:
1550166023Srrs		case SCTP_STATE_COOKIE_ECHOED:
1551163953Srrs			/*
1552169352Srrs			 * INIT was sent but got a COOKIE_ECHO with the
1553166023Srrs			 * correct tags... just accept it...but we must
1554166023Srrs			 * process the init so that we can make sure we have
1555166023Srrs			 * the right seq no's.
1556163953Srrs			 */
1557163953Srrs			/* First we must process the INIT !! */
1558231038Stuexen			retval = sctp_process_init(init_cp, stcb);
1559163953Srrs			if (retval < 0) {
1560166023Srrs				if (how_indx < sizeof(asoc->cookie_how))
1561166023Srrs					asoc->cookie_how[how_indx] = 3;
1562163953Srrs				return (NULL);
1563163953Srrs			}
1564163953Srrs			/* we have already processed the INIT so no problem */
1565163953Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb,
1566171440Srrs			    net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
1567171440Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_13);
1568163953Srrs			/* update current state */
1569166675Srrs			if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
1570166675Srrs				SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
1571166675Srrs			else
1572166675Srrs				SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
1573171943Srrs
1574171943Srrs			SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
1575163953Srrs			if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
1576163953Srrs				sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1577163953Srrs				    stcb->sctp_ep, stcb, asoc->primary_destination);
1578163953Srrs			}
1579166675Srrs			SCTP_STAT_INCR_GAUGE32(sctps_currestab);
1580165220Srrs			sctp_stop_all_cookie_timers(stcb);
1581163953Srrs			if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
1582163953Srrs			    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
1583163953Srrs			    (inp->sctp_socket->so_qlimit == 0)
1584163953Srrs			    ) {
1585252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1586172090Srrs				struct socket *so;
1587172090Srrs
1588172090Srrs#endif
1589163953Srrs				/*
1590163953Srrs				 * Here is where collision would go if we
1591163953Srrs				 * did a connect() and instead got a
1592163953Srrs				 * init/init-ack/cookie done before the
1593163953Srrs				 * init-ack came back..
1594163953Srrs				 */
1595163953Srrs				stcb->sctp_ep->sctp_flags |=
1596163953Srrs				    SCTP_PCB_FLAGS_CONNECTED;
1597252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1598172090Srrs				so = SCTP_INP_SO(stcb->sctp_ep);
1599172090Srrs				atomic_add_int(&stcb->asoc.refcnt, 1);
1600172090Srrs				SCTP_TCB_UNLOCK(stcb);
1601172090Srrs				SCTP_SOCKET_LOCK(so, 1);
1602172090Srrs				SCTP_TCB_LOCK(stcb);
1603172090Srrs				atomic_add_int(&stcb->asoc.refcnt, -1);
1604172090Srrs				if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
1605172090Srrs					SCTP_SOCKET_UNLOCK(so, 1);
1606172090Srrs					return (NULL);
1607172090Srrs				}
1608172090Srrs#endif
1609172090Srrs				soisconnected(stcb->sctp_socket);
1610252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1611172090Srrs				SCTP_SOCKET_UNLOCK(so, 1);
1612172090Srrs#endif
1613163953Srrs			}
1614163953Srrs			/* notify upper layer */
1615163953Srrs			*notification = SCTP_NOTIFY_ASSOC_UP;
1616163953Srrs			/*
1617163953Srrs			 * since we did not send a HB make sure we don't
1618163953Srrs			 * double things
1619163953Srrs			 */
1620163953Srrs			net->hb_responded = 1;
1621170642Srrs			net->RTO = sctp_calculate_rto(stcb, asoc, net,
1622218186Srrs			    &cookie->time_entered,
1623218186Srrs			    sctp_align_unsafe_makecopy,
1624219397Srrs			    SCTP_RTT_FROM_NON_DATA);
1625163953Srrs
1626163953Srrs			if (stcb->asoc.sctp_autoclose_ticks &&
1627163953Srrs			    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))) {
1628163953Srrs				sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
1629163953Srrs				    inp, stcb, NULL);
1630163953Srrs			}
1631163953Srrs			break;
1632163953Srrs		default:
1633163953Srrs			/*
1634163953Srrs			 * we're in the OPEN state (or beyond), so peer must
1635163953Srrs			 * have simply lost the COOKIE-ACK
1636163953Srrs			 */
1637163953Srrs			break;
1638266071Stuexen		}		/* end switch */
1639165220Srrs		sctp_stop_all_cookie_timers(stcb);
1640163953Srrs		/*
1641163953Srrs		 * We ignore the return code here.. not sure if we should
1642163953Srrs		 * somehow abort.. but we do have an existing asoc. This
1643163953Srrs		 * really should not fail.
1644163953Srrs		 */
1645231038Stuexen		if (sctp_load_addresses_from_init(stcb, m,
1646163953Srrs		    init_offset + sizeof(struct sctp_init_chunk),
1647252889Stuexen		    initack_offset, src, dst, init_src)) {
1648166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1649166023Srrs				asoc->cookie_how[how_indx] = 4;
1650163953Srrs			return (NULL);
1651163953Srrs		}
1652163953Srrs		/* respond with a COOKIE-ACK */
1653165220Srrs		sctp_toss_old_cookies(stcb, asoc);
1654163953Srrs		sctp_send_cookie_ack(stcb);
1655166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1656166023Srrs			asoc->cookie_how[how_indx] = 5;
1657163953Srrs		return (stcb);
1658169352Srrs	}
1659163953Srrs	if (ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
1660163953Srrs	    ntohl(init_cp->init.initiate_tag) == asoc->peer_vtag &&
1661163953Srrs	    cookie->tie_tag_my_vtag == 0 &&
1662163953Srrs	    cookie->tie_tag_peer_vtag == 0) {
1663163953Srrs		/*
1664163953Srrs		 * case C in Section 5.2.4 Table 2: XMOO silently discard
1665163953Srrs		 */
1666166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1667166023Srrs			asoc->cookie_how[how_indx] = 6;
1668163953Srrs		return (NULL);
1669163953Srrs	}
1670185694Srrs	/*
1671185694Srrs	 * If nat support, and the below and stcb is established, send back
1672185694Srrs	 * a ABORT(colliding state) if we are established.
1673185694Srrs	 */
1674185694Srrs	if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) &&
1675185694Srrs	    (asoc->peer_supports_nat) &&
1676185694Srrs	    ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
1677185694Srrs	    ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
1678185694Srrs	    (asoc->peer_vtag == 0)))) {
1679163953Srrs		/*
1680185694Srrs		 * Special case - Peer's support nat. We may have two init's
1681185694Srrs		 * that we gave out the same tag on since one was not
1682185694Srrs		 * established.. i.e. we get INIT from host-1 behind the nat
1683185694Srrs		 * and we respond tag-a, we get a INIT from host-2 behind
1684185694Srrs		 * the nat and we get tag-a again. Then we bring up host-1
1685185694Srrs		 * (or 2's) assoc, Then comes the cookie from hsot-2 (or 1).
1686185694Srrs		 * Now we have colliding state. We must send an abort here
1687185694Srrs		 * with colliding state indication.
1688185694Srrs		 */
1689266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
1690252889Stuexen		sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
1691238253Stuexen		    use_mflowid, mflowid,
1692238253Stuexen		    vrf_id, port);
1693185694Srrs		return (NULL);
1694185694Srrs	}
1695185694Srrs	if ((ntohl(initack_cp->init.initiate_tag) == asoc->my_vtag) &&
1696185694Srrs	    ((ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) ||
1697185694Srrs	    (asoc->peer_vtag == 0))) {
1698185694Srrs		/*
1699163953Srrs		 * case B in Section 5.2.4 Table 2: MXAA or MOAA my info
1700163953Srrs		 * should be ok, re-accept peer info
1701163953Srrs		 */
1702166023Srrs		if (ntohl(initack_cp->init.initial_tsn) != asoc->init_seq_number) {
1703166023Srrs			/*
1704166023Srrs			 * Extension of case C. If we hit this, then the
1705166023Srrs			 * random number generator returned the same vtag
1706166023Srrs			 * when we first sent our INIT-ACK and when we later
1707166023Srrs			 * sent our INIT. The side with the seq numbers that
1708166023Srrs			 * are different will be the one that normnally
1709166023Srrs			 * would have hit case C. This in effect "extends"
1710166023Srrs			 * our vtags in this collision case to be 64 bits.
1711166023Srrs			 * The same collision could occur aka you get both
1712166023Srrs			 * vtag and seq number the same twice in a row.. but
1713166023Srrs			 * is much less likely. If it did happen then we
1714166023Srrs			 * would proceed through and bring up the assoc.. we
1715166023Srrs			 * may end up with the wrong stream setup however..
1716166023Srrs			 * which would be bad.. but there is no way to
1717166023Srrs			 * tell.. until we send on a stream that does not
1718166023Srrs			 * exist :-)
1719166023Srrs			 */
1720166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1721166023Srrs				asoc->cookie_how[how_indx] = 7;
1722166023Srrs
1723166023Srrs			return (NULL);
1724166023Srrs		}
1725166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1726166023Srrs			asoc->cookie_how[how_indx] = 8;
1727171440Srrs		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
1728163953Srrs		sctp_stop_all_cookie_timers(stcb);
1729163953Srrs		/*
1730163953Srrs		 * since we did not send a HB make sure we don't double
1731163953Srrs		 * things
1732163953Srrs		 */
1733163953Srrs		net->hb_responded = 1;
1734163953Srrs		if (stcb->asoc.sctp_autoclose_ticks &&
1735163953Srrs		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
1736163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb,
1737163953Srrs			    NULL);
1738163953Srrs		}
1739163953Srrs		asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
1740164205Srrs		asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
1741164205Srrs
1742164205Srrs		if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
1743164205Srrs			/*
1744164205Srrs			 * Ok the peer probably discarded our data (if we
1745164205Srrs			 * echoed a cookie+data). So anything on the
1746164205Srrs			 * sent_queue should be marked for retransmit, we
1747164205Srrs			 * may not get something to kick us so it COULD
1748164205Srrs			 * still take a timeout to move these.. but it can't
1749164205Srrs			 * hurt to mark them.
1750164205Srrs			 */
1751164205Srrs			struct sctp_tmit_chunk *chk;
1752163953Srrs
1753164205Srrs			TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1754164205Srrs				if (chk->sent < SCTP_DATAGRAM_RESEND) {
1755164205Srrs					chk->sent = SCTP_DATAGRAM_RESEND;
1756171440Srrs					sctp_flight_size_decrease(chk);
1757171440Srrs					sctp_total_flight_decrease(stcb, chk);
1758168124Srrs					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1759164205Srrs					spec_flag++;
1760164205Srrs				}
1761164205Srrs			}
1762164205Srrs
1763164205Srrs		}
1764163953Srrs		/* process the INIT info (peer's info) */
1765231038Stuexen		retval = sctp_process_init(init_cp, stcb);
1766163953Srrs		if (retval < 0) {
1767166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1768166023Srrs				asoc->cookie_how[how_indx] = 9;
1769163953Srrs			return (NULL);
1770163953Srrs		}
1771231038Stuexen		if (sctp_load_addresses_from_init(stcb, m,
1772163953Srrs		    init_offset + sizeof(struct sctp_init_chunk),
1773252889Stuexen		    initack_offset, src, dst, init_src)) {
1774166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1775166023Srrs				asoc->cookie_how[how_indx] = 10;
1776163953Srrs			return (NULL);
1777163953Srrs		}
1778163953Srrs		if ((asoc->state & SCTP_STATE_COOKIE_WAIT) ||
1779163953Srrs		    (asoc->state & SCTP_STATE_COOKIE_ECHOED)) {
1780163953Srrs			*notification = SCTP_NOTIFY_ASSOC_UP;
1781163953Srrs
1782163953Srrs			if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
1783163953Srrs			    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
1784163953Srrs			    (inp->sctp_socket->so_qlimit == 0)) {
1785252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1786172090Srrs				struct socket *so;
1787172090Srrs
1788172090Srrs#endif
1789163953Srrs				stcb->sctp_ep->sctp_flags |=
1790163953Srrs				    SCTP_PCB_FLAGS_CONNECTED;
1791252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1792172090Srrs				so = SCTP_INP_SO(stcb->sctp_ep);
1793172090Srrs				atomic_add_int(&stcb->asoc.refcnt, 1);
1794172090Srrs				SCTP_TCB_UNLOCK(stcb);
1795172090Srrs				SCTP_SOCKET_LOCK(so, 1);
1796172090Srrs				SCTP_TCB_LOCK(stcb);
1797172090Srrs				atomic_add_int(&stcb->asoc.refcnt, -1);
1798172090Srrs				if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
1799172090Srrs					SCTP_SOCKET_UNLOCK(so, 1);
1800172090Srrs					return (NULL);
1801172090Srrs				}
1802172090Srrs#endif
1803172090Srrs				soisconnected(stcb->sctp_socket);
1804252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1805172090Srrs				SCTP_SOCKET_UNLOCK(so, 1);
1806172090Srrs#endif
1807163953Srrs			}
1808166675Srrs			if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
1809166675Srrs				SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
1810166675Srrs			else
1811166675Srrs				SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
1812166675Srrs			SCTP_STAT_INCR_GAUGE32(sctps_currestab);
1813166675Srrs		} else if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
1814166675Srrs			SCTP_STAT_INCR_COUNTER32(sctps_restartestab);
1815166675Srrs		} else {
1816166675Srrs			SCTP_STAT_INCR_COUNTER32(sctps_collisionestab);
1817163953Srrs		}
1818171943Srrs		SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
1819163953Srrs		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
1820163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1821163953Srrs			    stcb->sctp_ep, stcb, asoc->primary_destination);
1822163953Srrs		}
1823163953Srrs		sctp_stop_all_cookie_timers(stcb);
1824165220Srrs		sctp_toss_old_cookies(stcb, asoc);
1825163953Srrs		sctp_send_cookie_ack(stcb);
1826164205Srrs		if (spec_flag) {
1827164205Srrs			/*
1828164205Srrs			 * only if we have retrans set do we do this. What
1829164205Srrs			 * this call does is get only the COOKIE-ACK out and
1830164205Srrs			 * then when we return the normal call to
1831164205Srrs			 * sctp_chunk_output will get the retrans out behind
1832164205Srrs			 * this.
1833164205Srrs			 */
1834172090Srrs			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_COOKIE_ACK, SCTP_SO_NOT_LOCKED);
1835164205Srrs		}
1836166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1837166023Srrs			asoc->cookie_how[how_indx] = 11;
1838166023Srrs
1839163953Srrs		return (stcb);
1840163953Srrs	}
1841163953Srrs	if ((ntohl(initack_cp->init.initiate_tag) != asoc->my_vtag &&
1842163953Srrs	    ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) &&
1843163953Srrs	    cookie->tie_tag_my_vtag == asoc->my_vtag_nonce &&
1844163953Srrs	    cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
1845163953Srrs	    cookie->tie_tag_peer_vtag != 0) {
1846163953Srrs		struct sctpasochead *head;
1847163953Srrs
1848252976Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1849252976Stuexen		struct socket *so;
1850252976Stuexen
1851252976Stuexen#endif
1852252976Stuexen
1853185694Srrs		if (asoc->peer_supports_nat) {
1854185694Srrs			/*
1855252976Stuexen			 * This is a gross gross hack. Just call the
1856185694Srrs			 * cookie_new code since we are allowing a duplicate
1857185694Srrs			 * association. I hope this works...
1858185694Srrs			 */
1859252889Stuexen			return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
1860252889Stuexen			    sh, cookie, cookie_len,
1861185694Srrs			    inp, netp, init_src, notification,
1862185694Srrs			    auth_skipped, auth_offset, auth_len,
1863238253Stuexen			    use_mflowid, mflowid,
1864185694Srrs			    vrf_id, port));
1865185694Srrs		}
1866163953Srrs		/*
1867163953Srrs		 * case A in Section 5.2.4 Table 2: XXMM (peer restarted)
1868163953Srrs		 */
1869165220Srrs		/* temp code */
1870166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1871166023Srrs			asoc->cookie_how[how_indx] = 12;
1872171440Srrs		sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_15);
1873171440Srrs		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
1874165647Srrs
1875163953Srrs		/* notify upper layer */
1876163953Srrs		*notification = SCTP_NOTIFY_ASSOC_RESTART;
1877165220Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
1878166675Srrs		if ((SCTP_GET_STATE(asoc) != SCTP_STATE_OPEN) &&
1879166675Srrs		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
1880166675Srrs		    (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT)) {
1881166675Srrs			SCTP_STAT_INCR_GAUGE32(sctps_currestab);
1882166675Srrs		}
1883166675Srrs		if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
1884166675Srrs			SCTP_STAT_INCR_GAUGE32(sctps_restartestab);
1885166675Srrs		} else if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
1886166675Srrs			SCTP_STAT_INCR_GAUGE32(sctps_collisionestab);
1887166675Srrs		}
1888165647Srrs		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
1889171943Srrs			SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
1890165647Srrs			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
1891165647Srrs			    stcb->sctp_ep, stcb, asoc->primary_destination);
1892165647Srrs
1893165647Srrs		} else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
1894165647Srrs			/* move to OPEN state, if not in SHUTDOWN_SENT */
1895171943Srrs			SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
1896165647Srrs		}
1897165647Srrs		asoc->pre_open_streams =
1898165647Srrs		    ntohs(initack_cp->init.num_outbound_streams);
1899165647Srrs		asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
1900165647Srrs		asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
1901179157Srrs		asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
1902165647Srrs
1903165647Srrs		asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
1904165647Srrs
1905165647Srrs		asoc->str_reset_seq_in = asoc->init_seq_number;
1906165647Srrs
1907165647Srrs		asoc->advanced_peer_ack_point = asoc->last_acked_seq;
1908170138Srrs		if (asoc->mapping_array) {
1909165647Srrs			memset(asoc->mapping_array, 0,
1910165647Srrs			    asoc->mapping_array_size);
1911170138Srrs		}
1912205627Srrs		if (asoc->nr_mapping_array) {
1913185694Srrs			memset(asoc->nr_mapping_array, 0,
1914206137Stuexen			    asoc->mapping_array_size);
1915185694Srrs		}
1916165220Srrs		SCTP_TCB_UNLOCK(stcb);
1917252976Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1918252976Stuexen		so = SCTP_INP_SO(stcb->sctp_ep);
1919252976Stuexen		SCTP_SOCKET_LOCK(so, 1);
1920252976Stuexen#endif
1921165220Srrs		SCTP_INP_INFO_WLOCK();
1922165220Srrs		SCTP_INP_WLOCK(stcb->sctp_ep);
1923165220Srrs		SCTP_TCB_LOCK(stcb);
1924165220Srrs		atomic_add_int(&stcb->asoc.refcnt, -1);
1925163953Srrs		/* send up all the data */
1926164205Srrs		SCTP_TCB_SEND_LOCK(stcb);
1927165220Srrs
1928252976Stuexen		sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
1929165220Srrs		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
1930252943Stuexen			stcb->asoc.strmout[i].chunks_on_queues = 0;
1931165220Srrs			stcb->asoc.strmout[i].stream_no = i;
1932252940Stuexen			stcb->asoc.strmout[i].next_sequence_send = 0;
1933165220Srrs			stcb->asoc.strmout[i].last_msg_incomplete = 0;
1934165220Srrs		}
1935163953Srrs		/* process the INIT-ACK info (my info) */
1936163953Srrs		asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
1937163953Srrs		asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
1938163953Srrs
1939163953Srrs		/* pull from vtag hash */
1940163953Srrs		LIST_REMOVE(stcb, sctp_asocs);
1941163953Srrs		/* re-insert to new vtag position */
1942179783Srrs		head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag,
1943179783Srrs		    SCTP_BASE_INFO(hashasocmark))];
1944163953Srrs		/*
1945163953Srrs		 * put it in the bucket in the vtag hash of assoc's for the
1946163953Srrs		 * system
1947163953Srrs		 */
1948163953Srrs		LIST_INSERT_HEAD(head, stcb, sctp_asocs);
1949163953Srrs
1950164205Srrs		SCTP_TCB_SEND_UNLOCK(stcb);
1951165220Srrs		SCTP_INP_WUNLOCK(stcb->sctp_ep);
1952165220Srrs		SCTP_INP_INFO_WUNLOCK();
1953252976Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1954252976Stuexen		SCTP_SOCKET_UNLOCK(so, 1);
1955252976Stuexen#endif
1956252976Stuexen		asoc->total_flight = 0;
1957252976Stuexen		asoc->total_flight_count = 0;
1958252976Stuexen		/* process the INIT info (peer's info) */
1959231038Stuexen		retval = sctp_process_init(init_cp, stcb);
1960163953Srrs		if (retval < 0) {
1961166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1962166023Srrs				asoc->cookie_how[how_indx] = 13;
1963166023Srrs
1964163953Srrs			return (NULL);
1965163953Srrs		}
1966163953Srrs		/*
1967163953Srrs		 * since we did not send a HB make sure we don't double
1968163953Srrs		 * things
1969163953Srrs		 */
1970163953Srrs		net->hb_responded = 1;
1971163953Srrs
1972231038Stuexen		if (sctp_load_addresses_from_init(stcb, m,
1973163953Srrs		    init_offset + sizeof(struct sctp_init_chunk),
1974252889Stuexen		    initack_offset, src, dst, init_src)) {
1975166023Srrs			if (how_indx < sizeof(asoc->cookie_how))
1976166023Srrs				asoc->cookie_how[how_indx] = 14;
1977166023Srrs
1978163953Srrs			return (NULL);
1979163953Srrs		}
1980163953Srrs		/* respond with a COOKIE-ACK */
1981163953Srrs		sctp_stop_all_cookie_timers(stcb);
1982165220Srrs		sctp_toss_old_cookies(stcb, asoc);
1983163953Srrs		sctp_send_cookie_ack(stcb);
1984166023Srrs		if (how_indx < sizeof(asoc->cookie_how))
1985166023Srrs			asoc->cookie_how[how_indx] = 15;
1986163953Srrs
1987163953Srrs		return (stcb);
1988163953Srrs	}
1989166023Srrs	if (how_indx < sizeof(asoc->cookie_how))
1990166023Srrs		asoc->cookie_how[how_indx] = 16;
1991163953Srrs	/* all other cases... */
1992163953Srrs	return (NULL);
1993163953Srrs}
1994163953Srrs
1995166086Srrs
1996163953Srrs/*
1997163953Srrs * handle a state cookie for a new association m: input packet mbuf chain--
1998163953Srrs * assumes a pullup on IP/SCTP/COOKIE-ECHO chunk note: this is a "split" mbuf
1999163953Srrs * and the cookie signature does not exist offset: offset into mbuf to the
2000163953Srrs * cookie-echo chunk length: length of the cookie chunk to: where the init
2001163953Srrs * was from returns a new TCB
2002163953Srrs */
2003238253Stuexenstatic struct sctp_tcb *
2004163953Srrssctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
2005252889Stuexen    struct sockaddr *src, struct sockaddr *dst,
2006163953Srrs    struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
2007163953Srrs    struct sctp_inpcb *inp, struct sctp_nets **netp,
2008163953Srrs    struct sockaddr *init_src, int *notification,
2009169352Srrs    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
2010238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
2011179157Srrs    uint32_t vrf_id, uint16_t port)
2012163953Srrs{
2013163953Srrs	struct sctp_tcb *stcb;
2014163953Srrs	struct sctp_init_chunk *init_cp, init_buf;
2015163953Srrs	struct sctp_init_ack_chunk *initack_cp, initack_buf;
2016163953Srrs	struct sockaddr_storage sa_store;
2017163953Srrs	struct sockaddr *initack_src = (struct sockaddr *)&sa_store;
2018163953Srrs	struct sctp_association *asoc;
2019163953Srrs	int init_offset, initack_offset, initack_limit;
2020163953Srrs	int retval;
2021163953Srrs	int error = 0;
2022166675Srrs	uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
2023163953Srrs
2024221249Stuexen#ifdef INET
2025221249Stuexen	struct sockaddr_in *sin;
2026221249Stuexen
2027221249Stuexen#endif
2028221249Stuexen#ifdef INET6
2029221249Stuexen	struct sockaddr_in6 *sin6;
2030221249Stuexen
2031221249Stuexen#endif
2032252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2033172090Srrs	struct socket *so;
2034172090Srrs
2035172090Srrs	so = SCTP_INP_SO(inp);
2036172090Srrs#endif
2037172090Srrs
2038163953Srrs	/*
2039163953Srrs	 * find and validate the INIT chunk in the cookie (peer's info) the
2040163953Srrs	 * INIT should start after the cookie-echo header struct (chunk
2041163953Srrs	 * header, state cookie header struct)
2042163953Srrs	 */
2043163953Srrs	init_offset = offset + sizeof(struct sctp_cookie_echo_chunk);
2044163953Srrs	init_cp = (struct sctp_init_chunk *)
2045163953Srrs	    sctp_m_getptr(m, init_offset, sizeof(struct sctp_init_chunk),
2046163953Srrs	    (uint8_t *) & init_buf);
2047163953Srrs	if (init_cp == NULL) {
2048163953Srrs		/* could not pull a INIT chunk in cookie */
2049169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1,
2050169420Srrs		    "process_cookie_new: could not pull INIT chunk hdr\n");
2051163953Srrs		return (NULL);
2052163953Srrs	}
2053163953Srrs	if (init_cp->ch.chunk_type != SCTP_INITIATION) {
2054169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "HUH? process_cookie_new: could not find INIT chunk!\n");
2055163953Srrs		return (NULL);
2056163953Srrs	}
2057231039Stuexen	initack_offset = init_offset + SCTP_SIZE32(ntohs(init_cp->ch.chunk_length));
2058163953Srrs	/*
2059163953Srrs	 * find and validate the INIT-ACK chunk in the cookie (my info) the
2060163953Srrs	 * INIT-ACK follows the INIT chunk
2061163953Srrs	 */
2062163953Srrs	initack_cp = (struct sctp_init_ack_chunk *)
2063163953Srrs	    sctp_m_getptr(m, initack_offset, sizeof(struct sctp_init_ack_chunk),
2064163953Srrs	    (uint8_t *) & initack_buf);
2065163953Srrs	if (initack_cp == NULL) {
2066163953Srrs		/* could not pull INIT-ACK chunk in cookie */
2067169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: could not pull INIT-ACK chunk hdr\n");
2068163953Srrs		return (NULL);
2069163953Srrs	}
2070163953Srrs	if (initack_cp->ch.chunk_type != SCTP_INITIATION_ACK) {
2071163953Srrs		return (NULL);
2072163953Srrs	}
2073163953Srrs	/*
2074163953Srrs	 * NOTE: We can't use the INIT_ACK's chk_length to determine the
2075163953Srrs	 * "initack_limit" value.  This is because the chk_length field
2076163953Srrs	 * includes the length of the cookie, but the cookie is omitted when
2077163953Srrs	 * the INIT and INIT_ACK are tacked onto the cookie...
2078163953Srrs	 */
2079163953Srrs	initack_limit = offset + cookie_len;
2080163953Srrs
2081163953Srrs	/*
2082163953Srrs	 * now that we know the INIT/INIT-ACK are in place, create a new TCB
2083163953Srrs	 * and popluate
2084163953Srrs	 */
2085171531Srrs
2086171531Srrs	/*
2087171531Srrs	 * Here we do a trick, we set in NULL for the proc/thread argument.
2088171531Srrs	 * We do this since in effect we only use the p argument when the
2089171531Srrs	 * socket is unbound and we must do an implicit bind. Since we are
2090171531Srrs	 * getting a cookie, we cannot be unbound.
2091171531Srrs	 */
2092206137Stuexen	stcb = sctp_aloc_assoc(inp, init_src, &error,
2093171531Srrs	    ntohl(initack_cp->init.initiate_tag), vrf_id,
2094171531Srrs	    (struct thread *)NULL
2095171531Srrs	    );
2096163953Srrs	if (stcb == NULL) {
2097163953Srrs		struct mbuf *op_err;
2098163953Srrs
2099163953Srrs		/* memory problem? */
2100169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT1,
2101169420Srrs		    "process_cookie_new: no room for another TCB!\n");
2102266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
2103163953Srrs		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
2104252889Stuexen		    src, dst, sh, op_err,
2105238253Stuexen		    use_mflowid, mflowid,
2106238253Stuexen		    vrf_id, port);
2107163953Srrs		return (NULL);
2108163953Srrs	}
2109163953Srrs	/* get the correct sctp_nets */
2110169420Srrs	if (netp)
2111169420Srrs		*netp = sctp_findnet(stcb, init_src);
2112169420Srrs
2113163953Srrs	asoc = &stcb->asoc;
2114163953Srrs	/* get scope variables out of cookie */
2115252961Stuexen	asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
2116252961Stuexen	asoc->scope.site_scope = cookie->site_scope;
2117252961Stuexen	asoc->scope.local_scope = cookie->local_scope;
2118252961Stuexen	asoc->scope.loopback_scope = cookie->loopback_scope;
2119163953Srrs
2120252961Stuexen	if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) ||
2121252961Stuexen	    (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) {
2122163953Srrs		struct mbuf *op_err;
2123163953Srrs
2124163953Srrs		/*
2125163953Srrs		 * Houston we have a problem. The EP changed while the
2126163953Srrs		 * cookie was in flight. Only recourse is to abort the
2127163953Srrs		 * association.
2128163953Srrs		 */
2129170140Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
2130266181Stuexen		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
2131163953Srrs		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
2132252889Stuexen		    src, dst, sh, op_err,
2133238253Stuexen		    use_mflowid, mflowid,
2134238253Stuexen		    vrf_id, port);
2135252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2136172090Srrs		SCTP_TCB_UNLOCK(stcb);
2137172090Srrs		SCTP_SOCKET_LOCK(so, 1);
2138172090Srrs		SCTP_TCB_LOCK(stcb);
2139172090Srrs#endif
2140171943Srrs		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
2141171440Srrs		    SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
2142252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2143172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
2144172090Srrs#endif
2145172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2146163953Srrs		return (NULL);
2147163953Srrs	}
2148163953Srrs	/* process the INIT-ACK info (my info) */
2149185694Srrs	asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
2150163953Srrs	asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
2151163953Srrs	asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
2152163953Srrs	asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
2153163953Srrs	asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
2154179157Srrs	asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
2155163953Srrs	asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
2156163953Srrs	asoc->str_reset_seq_in = asoc->init_seq_number;
2157163953Srrs
2158163953Srrs	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
2159163953Srrs
2160163953Srrs	/* process the INIT info (peer's info) */
2161169420Srrs	if (netp)
2162231038Stuexen		retval = sctp_process_init(init_cp, stcb);
2163169420Srrs	else
2164169420Srrs		retval = 0;
2165163953Srrs	if (retval < 0) {
2166170140Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
2167252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2168172090Srrs		SCTP_TCB_UNLOCK(stcb);
2169172090Srrs		SCTP_SOCKET_LOCK(so, 1);
2170172090Srrs		SCTP_TCB_LOCK(stcb);
2171172090Srrs#endif
2172171943Srrs		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
2173252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2174172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
2175172090Srrs#endif
2176172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2177163953Srrs		return (NULL);
2178163953Srrs	}
2179163953Srrs	/* load all addresses */
2180231038Stuexen	if (sctp_load_addresses_from_init(stcb, m,
2181252889Stuexen	    init_offset + sizeof(struct sctp_init_chunk), initack_offset,
2182252889Stuexen	    src, dst, init_src)) {
2183170140Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
2184252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2185172090Srrs		SCTP_TCB_UNLOCK(stcb);
2186172090Srrs		SCTP_SOCKET_LOCK(so, 1);
2187172090Srrs		SCTP_TCB_LOCK(stcb);
2188172090Srrs#endif
2189171943Srrs		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_17);
2190252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2191172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
2192172090Srrs#endif
2193172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2194163953Srrs		return (NULL);
2195163953Srrs	}
2196163953Srrs	/*
2197163953Srrs	 * verify any preceding AUTH chunk that was skipped
2198163953Srrs	 */
2199163953Srrs	/* pull the local authentication parameters from the cookie/init-ack */
2200163953Srrs	sctp_auth_get_cookie_params(stcb, m,
2201163953Srrs	    initack_offset + sizeof(struct sctp_init_ack_chunk),
2202163953Srrs	    initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)));
2203163953Srrs	if (auth_skipped) {
2204163953Srrs		struct sctp_auth_chunk *auth;
2205163953Srrs
2206163953Srrs		auth = (struct sctp_auth_chunk *)
2207166675Srrs		    sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
2208169420Srrs		if ((auth == NULL) || sctp_handle_auth(stcb, auth, m, auth_offset)) {
2209163953Srrs			/* auth HMAC failed, dump the assoc and packet */
2210169420Srrs			SCTPDBG(SCTP_DEBUG_AUTH1,
2211169420Srrs			    "COOKIE-ECHO: AUTH failed\n");
2212171440Srrs			atomic_add_int(&stcb->asoc.refcnt, 1);
2213252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2214172090Srrs			SCTP_TCB_UNLOCK(stcb);
2215172090Srrs			SCTP_SOCKET_LOCK(so, 1);
2216172090Srrs			SCTP_TCB_LOCK(stcb);
2217172090Srrs#endif
2218171943Srrs			(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_18);
2219252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2220172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
2221172090Srrs#endif
2222172090Srrs			atomic_subtract_int(&stcb->asoc.refcnt, 1);
2223163953Srrs			return (NULL);
2224163953Srrs		} else {
2225163953Srrs			/* remaining chunks checked... good to go */
2226163953Srrs			stcb->asoc.authenticated = 1;
2227163953Srrs		}
2228163953Srrs	}
2229163953Srrs	/* update current state */
2230169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
2231171943Srrs	SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
2232163953Srrs	if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
2233163953Srrs		sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
2234163953Srrs		    stcb->sctp_ep, stcb, asoc->primary_destination);
2235163953Srrs	}
2236165220Srrs	sctp_stop_all_cookie_timers(stcb);
2237163953Srrs	SCTP_STAT_INCR_COUNTER32(sctps_passiveestab);
2238163953Srrs	SCTP_STAT_INCR_GAUGE32(sctps_currestab);
2239163953Srrs
2240163953Srrs	/*
2241163953Srrs	 * if we're doing ASCONFs, check to see if we have any new local
2242163953Srrs	 * addresses that need to get added to the peer (eg. addresses
2243163953Srrs	 * changed while cookie echo in flight).  This needs to be done
2244163953Srrs	 * after we go to the OPEN state to do the correct asconf
2245163953Srrs	 * processing. else, make sure we have the correct addresses in our
2246163953Srrs	 * lists
2247163953Srrs	 */
2248163953Srrs
2249163953Srrs	/* warning, we re-use sin, sin6, sa_store here! */
2250163953Srrs	/* pull in local_address (our "from" address) */
2251221249Stuexen	switch (cookie->laddr_type) {
2252221249Stuexen#ifdef INET
2253221249Stuexen	case SCTP_IPV4_ADDRESS:
2254163953Srrs		/* source addr is IPv4 */
2255163953Srrs		sin = (struct sockaddr_in *)initack_src;
2256163953Srrs		memset(sin, 0, sizeof(*sin));
2257163953Srrs		sin->sin_family = AF_INET;
2258163953Srrs		sin->sin_len = sizeof(struct sockaddr_in);
2259163953Srrs		sin->sin_addr.s_addr = cookie->laddress[0];
2260221249Stuexen		break;
2261221249Stuexen#endif
2262221249Stuexen#ifdef INET6
2263221249Stuexen	case SCTP_IPV6_ADDRESS:
2264163953Srrs		/* source addr is IPv6 */
2265163953Srrs		sin6 = (struct sockaddr_in6 *)initack_src;
2266163953Srrs		memset(sin6, 0, sizeof(*sin6));
2267163953Srrs		sin6->sin6_family = AF_INET6;
2268163953Srrs		sin6->sin6_len = sizeof(struct sockaddr_in6);
2269163953Srrs		sin6->sin6_scope_id = cookie->scope_id;
2270163953Srrs		memcpy(&sin6->sin6_addr, cookie->laddress,
2271163953Srrs		    sizeof(sin6->sin6_addr));
2272221249Stuexen		break;
2273221249Stuexen#endif
2274221249Stuexen	default:
2275170140Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
2276252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2277172090Srrs		SCTP_TCB_UNLOCK(stcb);
2278172090Srrs		SCTP_SOCKET_LOCK(so, 1);
2279172090Srrs		SCTP_TCB_LOCK(stcb);
2280172090Srrs#endif
2281171943Srrs		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_19);
2282252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2283172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
2284172090Srrs#endif
2285172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2286163953Srrs		return (NULL);
2287163953Srrs	}
2288163953Srrs
2289163953Srrs	/* set up to notify upper layer */
2290163953Srrs	*notification = SCTP_NOTIFY_ASSOC_UP;
2291163953Srrs	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2292163953Srrs	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
2293163953Srrs	    (inp->sctp_socket->so_qlimit == 0)) {
2294163953Srrs		/*
2295163953Srrs		 * This is an endpoint that called connect() how it got a
2296163953Srrs		 * cookie that is NEW is a bit of a mystery. It must be that
2297163953Srrs		 * the INIT was sent, but before it got there.. a complete
2298163953Srrs		 * INIT/INIT-ACK/COOKIE arrived. But of course then it
2299163953Srrs		 * should have went to the other code.. not here.. oh well..
2300163953Srrs		 * a bit of protection is worth having..
2301163953Srrs		 */
2302163953Srrs		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
2303252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2304172090Srrs		atomic_add_int(&stcb->asoc.refcnt, 1);
2305172090Srrs		SCTP_TCB_UNLOCK(stcb);
2306172090Srrs		SCTP_SOCKET_LOCK(so, 1);
2307172090Srrs		SCTP_TCB_LOCK(stcb);
2308172090Srrs		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2309172090Srrs		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2310172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
2311172090Srrs			return (NULL);
2312172090Srrs		}
2313172090Srrs#endif
2314172090Srrs		soisconnected(stcb->sctp_socket);
2315252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2316172090Srrs		SCTP_SOCKET_UNLOCK(so, 1);
2317172090Srrs#endif
2318163953Srrs	} else if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
2319163953Srrs	    (inp->sctp_socket->so_qlimit)) {
2320163953Srrs		/*
2321163953Srrs		 * We don't want to do anything with this one. Since it is
2322163953Srrs		 * the listening guy. The timer will get started for
2323163953Srrs		 * accepted connections in the caller.
2324163953Srrs		 */
2325163953Srrs		;
2326163953Srrs	}
2327163953Srrs	/* since we did not send a HB make sure we don't double things */
2328169420Srrs	if ((netp) && (*netp))
2329169420Srrs		(*netp)->hb_responded = 1;
2330163953Srrs
2331163953Srrs	if (stcb->asoc.sctp_autoclose_ticks &&
2332163953Srrs	    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
2333163953Srrs		sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
2334163953Srrs	}
2335165220Srrs	/* calculate the RTT */
2336171440Srrs	(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
2337170642Srrs	if ((netp) && (*netp)) {
2338169420Srrs		(*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
2339218186Srrs		    &cookie->time_entered, sctp_align_unsafe_makecopy,
2340219397Srrs		    SCTP_RTT_FROM_NON_DATA);
2341170642Srrs	}
2342172190Srrs	/* respond with a COOKIE-ACK */
2343163953Srrs	sctp_send_cookie_ack(stcb);
2344172190Srrs
2345172190Srrs	/*
2346172190Srrs	 * check the address lists for any ASCONFs that need to be sent
2347172190Srrs	 * AFTER the cookie-ack is sent
2348172190Srrs	 */
2349172190Srrs	sctp_check_address_list(stcb, m,
2350172190Srrs	    initack_offset + sizeof(struct sctp_init_ack_chunk),
2351172190Srrs	    initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)),
2352172190Srrs	    initack_src, cookie->local_scope, cookie->site_scope,
2353172190Srrs	    cookie->ipv4_scope, cookie->loopback_scope);
2354172190Srrs
2355172190Srrs
2356163953Srrs	return (stcb);
2357163953Srrs}
2358163953Srrs
2359185694Srrs/*
2360185694Srrs * CODE LIKE THIS NEEDS TO RUN IF the peer supports the NAT extension, i.e
2361185694Srrs * we NEED to make sure we are not already using the vtag. If so we
2362185694Srrs * need to send back an ABORT-TRY-AGAIN-WITH-NEW-TAG No middle box bit!
2363185694Srrs	head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(tag,
2364185694Srrs							    SCTP_BASE_INFO(hashasocmark))];
2365185694Srrs	LIST_FOREACH(stcb, head, sctp_asocs) {
2366185694Srrs	        if ((stcb->asoc.my_vtag == tag) && (stcb->rport == rport) && (inp == stcb->sctp_ep))  {
2367185694Srrs		       -- SEND ABORT - TRY AGAIN --
2368185694Srrs		}
2369185694Srrs	}
2370185694Srrs*/
2371163953Srrs
2372163953Srrs/*
2373163953Srrs * handles a COOKIE-ECHO message stcb: modified to either a new or left as
2374163953Srrs * existing (non-NULL) TCB
2375163953Srrs */
2376163953Srrsstatic struct mbuf *
2377163953Srrssctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
2378252889Stuexen    struct sockaddr *src, struct sockaddr *dst,
2379163953Srrs    struct sctphdr *sh, struct sctp_cookie_echo_chunk *cp,
2380163953Srrs    struct sctp_inpcb **inp_p, struct sctp_tcb **stcb, struct sctp_nets **netp,
2381169352Srrs    int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
2382238253Stuexen    struct sctp_tcb **locked_tcb,
2383238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
2384238253Stuexen    uint32_t vrf_id, uint16_t port)
2385163953Srrs{
2386163953Srrs	struct sctp_state_cookie *cookie;
2387163953Srrs	struct sctp_tcb *l_stcb = *stcb;
2388163953Srrs	struct sctp_inpcb *l_inp;
2389163953Srrs	struct sockaddr *to;
2390163953Srrs	struct sctp_pcb *ep;
2391163953Srrs	struct mbuf *m_sig;
2392163953Srrs	uint8_t calc_sig[SCTP_SIGNATURE_SIZE], tmp_sig[SCTP_SIGNATURE_SIZE];
2393163953Srrs	uint8_t *sig;
2394163953Srrs	uint8_t cookie_ok = 0;
2395252880Stuexen	unsigned int sig_offset, cookie_offset;
2396163953Srrs	unsigned int cookie_len;
2397163953Srrs	struct timeval now;
2398163953Srrs	struct timeval time_expires;
2399163953Srrs	int notification = 0;
2400163953Srrs	struct sctp_nets *netl;
2401163953Srrs	int had_a_existing_tcb = 0;
2402216887Stuexen	int send_int_conf = 0;
2403163953Srrs
2404221249Stuexen#ifdef INET
2405221249Stuexen	struct sockaddr_in sin;
2406221249Stuexen
2407221249Stuexen#endif
2408221249Stuexen#ifdef INET6
2409221249Stuexen	struct sockaddr_in6 sin6;
2410221249Stuexen
2411221249Stuexen#endif
2412221249Stuexen
2413169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
2414169420Srrs	    "sctp_handle_cookie: handling COOKIE-ECHO\n");
2415163953Srrs
2416163953Srrs	if (inp_p == NULL) {
2417163953Srrs		return (NULL);
2418163953Srrs	}
2419163953Srrs	cookie = &cp->cookie;
2420163953Srrs	cookie_offset = offset + sizeof(struct sctp_chunkhdr);
2421163953Srrs	cookie_len = ntohs(cp->ch.chunk_length);
2422163953Srrs
2423163953Srrs	if ((cookie->peerport != sh->src_port) &&
2424163953Srrs	    (cookie->myport != sh->dest_port) &&
2425163953Srrs	    (cookie->my_vtag != sh->v_tag)) {
2426163953Srrs		/*
2427163953Srrs		 * invalid ports or bad tag.  Note that we always leave the
2428163953Srrs		 * v_tag in the header in network order and when we stored
2429163953Srrs		 * it in the my_vtag slot we also left it in network order.
2430169352Srrs		 * This maintains the match even though it may be in the
2431163953Srrs		 * opposite byte order of the machine :->
2432163953Srrs		 */
2433163953Srrs		return (NULL);
2434163953Srrs	}
2435252880Stuexen	if (cookie_len < sizeof(struct sctp_cookie_echo_chunk) +
2436163953Srrs	    sizeof(struct sctp_init_chunk) +
2437163953Srrs	    sizeof(struct sctp_init_ack_chunk) + SCTP_SIGNATURE_SIZE) {
2438252880Stuexen		/* cookie too small */
2439163953Srrs		return (NULL);
2440163953Srrs	}
2441163953Srrs	/*
2442163953Srrs	 * split off the signature into its own mbuf (since it should not be
2443163953Srrs	 * calculated in the sctp_hmac_m() call).
2444163953Srrs	 */
2445163953Srrs	sig_offset = offset + cookie_len - SCTP_SIGNATURE_SIZE;
2446163953Srrs	m_sig = m_split(m, sig_offset, M_DONTWAIT);
2447163953Srrs	if (m_sig == NULL) {
2448163953Srrs		/* out of memory or ?? */
2449163953Srrs		return (NULL);
2450163953Srrs	}
2451178202Srrs#ifdef SCTP_MBUF_LOGGING
2452179783Srrs	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
2453178202Srrs		struct mbuf *mat;
2454178202Srrs
2455234797Stuexen		for (mat = m_sig; mat; mat = SCTP_BUF_NEXT(mat)) {
2456178202Srrs			if (SCTP_BUF_IS_EXTENDED(mat)) {
2457178202Srrs				sctp_log_mb(mat, SCTP_MBUF_SPLIT);
2458178202Srrs			}
2459178202Srrs		}
2460178202Srrs	}
2461178202Srrs#endif
2462178202Srrs
2463163953Srrs	/*
2464163953Srrs	 * compute the signature/digest for the cookie
2465163953Srrs	 */
2466163953Srrs	ep = &(*inp_p)->sctp_ep;
2467163953Srrs	l_inp = *inp_p;
2468163953Srrs	if (l_stcb) {
2469163953Srrs		SCTP_TCB_UNLOCK(l_stcb);
2470163953Srrs	}
2471163953Srrs	SCTP_INP_RLOCK(l_inp);
2472163953Srrs	if (l_stcb) {
2473163953Srrs		SCTP_TCB_LOCK(l_stcb);
2474163953Srrs	}
2475163953Srrs	/* which cookie is it? */
2476163953Srrs	if ((cookie->time_entered.tv_sec < (long)ep->time_of_secret_change) &&
2477163953Srrs	    (ep->current_secret_number != ep->last_secret_number)) {
2478163953Srrs		/* it's the old cookie */
2479169378Srrs		(void)sctp_hmac_m(SCTP_HMAC,
2480163953Srrs		    (uint8_t *) ep->secret_key[(int)ep->last_secret_number],
2481170462Srrs		    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
2482163953Srrs	} else {
2483163953Srrs		/* it's the current cookie */
2484169378Srrs		(void)sctp_hmac_m(SCTP_HMAC,
2485163953Srrs		    (uint8_t *) ep->secret_key[(int)ep->current_secret_number],
2486170462Srrs		    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
2487163953Srrs	}
2488163953Srrs	/* get the signature */
2489163953Srrs	SCTP_INP_RUNLOCK(l_inp);
2490163953Srrs	sig = (uint8_t *) sctp_m_getptr(m_sig, 0, SCTP_SIGNATURE_SIZE, (uint8_t *) & tmp_sig);
2491163953Srrs	if (sig == NULL) {
2492163953Srrs		/* couldn't find signature */
2493164085Srrs		sctp_m_freem(m_sig);
2494163953Srrs		return (NULL);
2495163953Srrs	}
2496163953Srrs	/* compare the received digest with the computed digest */
2497163953Srrs	if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
2498163953Srrs		/* try the old cookie? */
2499163953Srrs		if ((cookie->time_entered.tv_sec == (long)ep->time_of_secret_change) &&
2500163953Srrs		    (ep->current_secret_number != ep->last_secret_number)) {
2501163953Srrs			/* compute digest with old */
2502169378Srrs			(void)sctp_hmac_m(SCTP_HMAC,
2503163953Srrs			    (uint8_t *) ep->secret_key[(int)ep->last_secret_number],
2504170462Srrs			    SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
2505163953Srrs			/* compare */
2506163953Srrs			if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) == 0)
2507163953Srrs				cookie_ok = 1;
2508163953Srrs		}
2509163953Srrs	} else {
2510163953Srrs		cookie_ok = 1;
2511163953Srrs	}
2512163953Srrs
2513163953Srrs	/*
2514163953Srrs	 * Now before we continue we must reconstruct our mbuf so that
2515163953Srrs	 * normal processing of any other chunks will work.
2516163953Srrs	 */
2517163953Srrs	{
2518163953Srrs		struct mbuf *m_at;
2519163953Srrs
2520163953Srrs		m_at = m;
2521165647Srrs		while (SCTP_BUF_NEXT(m_at) != NULL) {
2522165647Srrs			m_at = SCTP_BUF_NEXT(m_at);
2523163953Srrs		}
2524165647Srrs		SCTP_BUF_NEXT(m_at) = m_sig;
2525163953Srrs	}
2526163953Srrs
2527163953Srrs	if (cookie_ok == 0) {
2528169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "handle_cookie_echo: cookie signature validation failed!\n");
2529169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
2530169420Srrs		    "offset = %u, cookie_offset = %u, sig_offset = %u\n",
2531169420Srrs		    (uint32_t) offset, cookie_offset, sig_offset);
2532163953Srrs		return (NULL);
2533163953Srrs	}
2534163953Srrs	/*
2535163953Srrs	 * check the cookie timestamps to be sure it's not stale
2536163953Srrs	 */
2537169378Srrs	(void)SCTP_GETTIME_TIMEVAL(&now);
2538163953Srrs	/* Expire time is in Ticks, so we convert to seconds */
2539169655Srrs	time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life);
2540163953Srrs	time_expires.tv_usec = cookie->time_entered.tv_usec;
2541180387Srrs	/*
2542180387Srrs	 * TODO sctp_constants.h needs alternative time macros when _KERNEL
2543180387Srrs	 * is undefined.
2544180387Srrs	 */
2545163953Srrs	if (timevalcmp(&now, &time_expires, >)) {
2546163953Srrs		/* cookie is stale! */
2547163953Srrs		struct mbuf *op_err;
2548163953Srrs		struct sctp_stale_cookie_msg *scm;
2549163953Srrs		uint32_t tim;
2550163953Srrs
2551163953Srrs		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_stale_cookie_msg),
2552165647Srrs		    0, M_DONTWAIT, 1, MT_DATA);
2553163953Srrs		if (op_err == NULL) {
2554163953Srrs			/* FOOBAR */
2555163953Srrs			return (NULL);
2556163953Srrs		}
2557163953Srrs		/* Set the len */
2558165647Srrs		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
2559163953Srrs		scm = mtod(op_err, struct sctp_stale_cookie_msg *);
2560163953Srrs		scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
2561163953Srrs		scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
2562163953Srrs		    (sizeof(uint32_t))));
2563163953Srrs		/* seconds to usec */
2564163953Srrs		tim = (now.tv_sec - time_expires.tv_sec) * 1000000;
2565163953Srrs		/* add in usec */
2566163953Srrs		if (tim == 0)
2567163953Srrs			tim = now.tv_usec - cookie->time_entered.tv_usec;
2568163953Srrs		scm->time_usec = htonl(tim);
2569252889Stuexen		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
2570238253Stuexen		    use_mflowid, mflowid,
2571179157Srrs		    vrf_id, port);
2572163953Srrs		return (NULL);
2573163953Srrs	}
2574163953Srrs	/*
2575163953Srrs	 * Now we must see with the lookup address if we have an existing
2576163953Srrs	 * asoc. This will only happen if we were in the COOKIE-WAIT state
2577163953Srrs	 * and a INIT collided with us and somewhere the peer sent the
2578163953Srrs	 * cookie on another address besides the single address our assoc
2579163953Srrs	 * had for him. In this case we will have one of the tie-tags set at
2580163953Srrs	 * least AND the address field in the cookie can be used to look it
2581163953Srrs	 * up.
2582163953Srrs	 */
2583163953Srrs	to = NULL;
2584221249Stuexen	switch (cookie->addr_type) {
2585221249Stuexen#ifdef INET6
2586221249Stuexen	case SCTP_IPV6_ADDRESS:
2587163953Srrs		memset(&sin6, 0, sizeof(sin6));
2588163953Srrs		sin6.sin6_family = AF_INET6;
2589163953Srrs		sin6.sin6_len = sizeof(sin6);
2590163953Srrs		sin6.sin6_port = sh->src_port;
2591163953Srrs		sin6.sin6_scope_id = cookie->scope_id;
2592163953Srrs		memcpy(&sin6.sin6_addr.s6_addr, cookie->address,
2593163953Srrs		    sizeof(sin6.sin6_addr.s6_addr));
2594163953Srrs		to = (struct sockaddr *)&sin6;
2595221249Stuexen		break;
2596221249Stuexen#endif
2597221249Stuexen#ifdef INET
2598221249Stuexen	case SCTP_IPV4_ADDRESS:
2599163953Srrs		memset(&sin, 0, sizeof(sin));
2600163953Srrs		sin.sin_family = AF_INET;
2601163953Srrs		sin.sin_len = sizeof(sin);
2602163953Srrs		sin.sin_port = sh->src_port;
2603163953Srrs		sin.sin_addr.s_addr = cookie->address[0];
2604163953Srrs		to = (struct sockaddr *)&sin;
2605221249Stuexen		break;
2606221249Stuexen#endif
2607221249Stuexen	default:
2608169420Srrs		/* This should not happen */
2609169420Srrs		return (NULL);
2610163953Srrs	}
2611163953Srrs	if ((*stcb == NULL) && to) {
2612163953Srrs		/* Yep, lets check */
2613252889Stuexen		*stcb = sctp_findassociation_ep_addr(inp_p, to, netp, dst, NULL);
2614163953Srrs		if (*stcb == NULL) {
2615163953Srrs			/*
2616163953Srrs			 * We should have only got back the same inp. If we
2617163953Srrs			 * got back a different ep we have a problem. The
2618163953Srrs			 * original findep got back l_inp and now
2619163953Srrs			 */
2620163953Srrs			if (l_inp != *inp_p) {
2621169420Srrs				SCTP_PRINTF("Bad problem find_ep got a diff inp then special_locate?\n");
2622163953Srrs			}
2623165220Srrs		} else {
2624165220Srrs			if (*locked_tcb == NULL) {
2625165220Srrs				/*
2626165220Srrs				 * In this case we found the assoc only
2627165220Srrs				 * after we locked the create lock. This
2628165220Srrs				 * means we are in a colliding case and we
2629165220Srrs				 * must make sure that we unlock the tcb if
2630165220Srrs				 * its one of the cases where we throw away
2631165220Srrs				 * the incoming packets.
2632165220Srrs				 */
2633165220Srrs				*locked_tcb = *stcb;
2634165220Srrs
2635165220Srrs				/*
2636165220Srrs				 * We must also increment the inp ref count
2637165220Srrs				 * since the ref_count flags was set when we
2638165220Srrs				 * did not find the TCB, now we found it
2639165220Srrs				 * which reduces the refcount.. we must
2640165220Srrs				 * raise it back out to balance it all :-)
2641165220Srrs				 */
2642165220Srrs				SCTP_INP_INCR_REF((*stcb)->sctp_ep);
2643165220Srrs				if ((*stcb)->sctp_ep != l_inp) {
2644169420Srrs					SCTP_PRINTF("Huh? ep:%p diff then l_inp:%p?\n",
2645252927Stuexen					    (void *)(*stcb)->sctp_ep, (void *)l_inp);
2646165220Srrs				}
2647165220Srrs			}
2648163953Srrs		}
2649163953Srrs	}
2650188067Srrs	if (to == NULL) {
2651169420Srrs		return (NULL);
2652188067Srrs	}
2653163953Srrs	cookie_len -= SCTP_SIGNATURE_SIZE;
2654163953Srrs	if (*stcb == NULL) {
2655163953Srrs		/* this is the "normal" case... get a new TCB */
2656252889Stuexen		*stcb = sctp_process_cookie_new(m, iphlen, offset, src, dst, sh,
2657252889Stuexen		    cookie, cookie_len, *inp_p,
2658252889Stuexen		    netp, to, &notification,
2659238253Stuexen		    auth_skipped, auth_offset, auth_len,
2660238253Stuexen		    use_mflowid, mflowid,
2661238253Stuexen		    vrf_id, port);
2662163953Srrs	} else {
2663163953Srrs		/* this is abnormal... cookie-echo on existing TCB */
2664163953Srrs		had_a_existing_tcb = 1;
2665252889Stuexen		*stcb = sctp_process_cookie_existing(m, iphlen, offset,
2666252889Stuexen		    src, dst, sh,
2667185694Srrs		    cookie, cookie_len, *inp_p, *stcb, netp, to,
2668238253Stuexen		    &notification, auth_skipped, auth_offset, auth_len,
2669238253Stuexen		    use_mflowid, mflowid,
2670238253Stuexen		    vrf_id, port);
2671163953Srrs	}
2672163953Srrs
2673163953Srrs	if (*stcb == NULL) {
2674163953Srrs		/* still no TCB... must be bad cookie-echo */
2675163953Srrs		return (NULL);
2676163953Srrs	}
2677238253Stuexen	if ((*netp != NULL) && (use_mflowid != 0)) {
2678238253Stuexen		(*netp)->flowid = mflowid;
2679218400Stuexen#ifdef INVARIANTS
2680218392Srrs		(*netp)->flowidset = 1;
2681218400Stuexen#endif
2682218335Stuexen	}
2683163953Srrs	/*
2684163953Srrs	 * Ok, we built an association so confirm the address we sent the
2685163953Srrs	 * INIT-ACK to.
2686163953Srrs	 */
2687163953Srrs	netl = sctp_findnet(*stcb, to);
2688163953Srrs	/*
2689163953Srrs	 * This code should in theory NOT run but
2690163953Srrs	 */
2691163953Srrs	if (netl == NULL) {
2692163953Srrs		/* TSNH! Huh, why do I need to add this address here? */
2693231039Stuexen		if (sctp_add_remote_addr(*stcb, to, NULL, SCTP_DONOT_SETSCOPE, SCTP_IN_COOKIE_PROC)) {
2694231039Stuexen			return (NULL);
2695231039Stuexen		}
2696163953Srrs		netl = sctp_findnet(*stcb, to);
2697163953Srrs	}
2698163953Srrs	if (netl) {
2699163953Srrs		if (netl->dest_state & SCTP_ADDR_UNCONFIRMED) {
2700163953Srrs			netl->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
2701169420Srrs			(void)sctp_set_primary_addr((*stcb), (struct sockaddr *)NULL,
2702163953Srrs			    netl);
2703216887Stuexen			send_int_conf = 1;
2704163953Srrs		}
2705163953Srrs	}
2706224641Stuexen	sctp_start_net_timers(*stcb);
2707163953Srrs	if ((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
2708163953Srrs		if (!had_a_existing_tcb ||
2709163953Srrs		    (((*inp_p)->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
2710163953Srrs			/*
2711163953Srrs			 * If we have a NEW cookie or the connect never
2712163953Srrs			 * reached the connected state during collision we
2713163953Srrs			 * must do the TCP accept thing.
2714163953Srrs			 */
2715163953Srrs			struct socket *so, *oso;
2716163953Srrs			struct sctp_inpcb *inp;
2717163953Srrs
2718163953Srrs			if (notification == SCTP_NOTIFY_ASSOC_RESTART) {
2719163953Srrs				/*
2720163953Srrs				 * For a restart we will keep the same
2721163953Srrs				 * socket, no need to do anything. I THINK!!
2722163953Srrs				 */
2723231038Stuexen				sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
2724216887Stuexen				if (send_int_conf) {
2725216887Stuexen					sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
2726216887Stuexen					    (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
2727216887Stuexen				}
2728163953Srrs				return (m);
2729163953Srrs			}
2730163953Srrs			oso = (*inp_p)->sctp_socket;
2731171858Srrs			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
2732163953Srrs			SCTP_TCB_UNLOCK((*stcb));
2733218757Sbz			CURVNET_SET(oso->so_vnet);
2734166086Srrs			so = sonewconn(oso, 0
2735163953Srrs			    );
2736218757Sbz			CURVNET_RESTORE();
2737163953Srrs			SCTP_TCB_LOCK((*stcb));
2738171858Srrs			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
2739171858Srrs
2740163953Srrs			if (so == NULL) {
2741163953Srrs				struct mbuf *op_err;
2742163953Srrs
2743252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2744172090Srrs				struct socket *pcb_so;
2745172090Srrs
2746172090Srrs#endif
2747163953Srrs				/* Too many sockets */
2748169420Srrs				SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
2749266181Stuexen				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
2750163953Srrs				sctp_abort_association(*inp_p, NULL, m, iphlen,
2751252889Stuexen				    src, dst, sh, op_err,
2752238253Stuexen				    use_mflowid, mflowid,
2753238253Stuexen				    vrf_id, port);
2754252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2755172090Srrs				pcb_so = SCTP_INP_SO(*inp_p);
2756172090Srrs				atomic_add_int(&(*stcb)->asoc.refcnt, 1);
2757172090Srrs				SCTP_TCB_UNLOCK((*stcb));
2758172090Srrs				SCTP_SOCKET_LOCK(pcb_so, 1);
2759172090Srrs				SCTP_TCB_LOCK((*stcb));
2760172090Srrs				atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
2761172090Srrs#endif
2762171943Srrs				(void)sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_20);
2763252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2764172090Srrs				SCTP_SOCKET_UNLOCK(pcb_so, 1);
2765172090Srrs#endif
2766163953Srrs				return (NULL);
2767163953Srrs			}
2768163953Srrs			inp = (struct sctp_inpcb *)so->so_pcb;
2769166086Srrs			SCTP_INP_INCR_REF(inp);
2770166086Srrs			/*
2771166086Srrs			 * We add the unbound flag here so that if we get an
2772166086Srrs			 * soabort() before we get the move_pcb done, we
2773166086Srrs			 * will properly cleanup.
2774166086Srrs			 */
2775163953Srrs			inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
2776163953Srrs			    SCTP_PCB_FLAGS_CONNECTED |
2777163953Srrs			    SCTP_PCB_FLAGS_IN_TCPPOOL |
2778166086Srrs			    SCTP_PCB_FLAGS_UNBOUND |
2779163953Srrs			    (SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) |
2780163953Srrs			    SCTP_PCB_FLAGS_DONT_WAKE);
2781163953Srrs			inp->sctp_features = (*inp_p)->sctp_features;
2782172091Srrs			inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
2783163953Srrs			inp->sctp_socket = so;
2784163953Srrs			inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
2785211944Stuexen			inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
2786218235Stuexen			inp->sctp_ecn_enable = (*inp_p)->sctp_ecn_enable;
2787163953Srrs			inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
2788163953Srrs			inp->sctp_context = (*inp_p)->sctp_context;
2789234790Stuexen			inp->local_strreset_support = (*inp_p)->local_strreset_support;
2790163953Srrs			inp->inp_starting_point_for_iterator = NULL;
2791163953Srrs			/*
2792163953Srrs			 * copy in the authentication parameters from the
2793163953Srrs			 * original endpoint
2794163953Srrs			 */
2795163953Srrs			if (inp->sctp_ep.local_hmacs)
2796163953Srrs				sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
2797163953Srrs			inp->sctp_ep.local_hmacs =
2798163953Srrs			    sctp_copy_hmaclist((*inp_p)->sctp_ep.local_hmacs);
2799163953Srrs			if (inp->sctp_ep.local_auth_chunks)
2800163953Srrs				sctp_free_chunklist(inp->sctp_ep.local_auth_chunks);
2801163953Srrs			inp->sctp_ep.local_auth_chunks =
2802163953Srrs			    sctp_copy_chunklist((*inp_p)->sctp_ep.local_auth_chunks);
2803163953Srrs
2804163953Srrs			/*
2805163953Srrs			 * Now we must move it from one hash table to
2806163953Srrs			 * another and get the tcb in the right place.
2807163953Srrs			 */
2808207924Srrs
2809207924Srrs			/*
2810207924Srrs			 * This is where the one-2-one socket is put into
2811207924Srrs			 * the accept state waiting for the accept!
2812207924Srrs			 */
2813207924Srrs			if (*stcb) {
2814207924Srrs				(*stcb)->asoc.state |= SCTP_STATE_IN_ACCEPT_QUEUE;
2815207924Srrs			}
2816163953Srrs			sctp_move_pcb_and_assoc(*inp_p, inp, *stcb);
2817170056Srrs
2818170056Srrs			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
2819170056Srrs			SCTP_TCB_UNLOCK((*stcb));
2820170056Srrs
2821175845Srwatson			sctp_pull_off_control_to_new_inp((*inp_p), inp, *stcb,
2822175845Srwatson			    0);
2823170056Srrs			SCTP_TCB_LOCK((*stcb));
2824170056Srrs			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
2825163953Srrs
2826170056Srrs
2827166086Srrs			/*
2828166086Srrs			 * now we must check to see if we were aborted while
2829166086Srrs			 * the move was going on and the lock/unlock
2830166086Srrs			 * happened.
2831166086Srrs			 */
2832166086Srrs			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2833166086Srrs				/*
2834166086Srrs				 * yep it was, we leave the assoc attached
2835166086Srrs				 * to the socket since the sctp_inpcb_free()
2836166086Srrs				 * call will send an abort for us.
2837166086Srrs				 */
2838166086Srrs				SCTP_INP_DECR_REF(inp);
2839166086Srrs				return (NULL);
2840166086Srrs			}
2841166086Srrs			SCTP_INP_DECR_REF(inp);
2842163953Srrs			/* Switch over to the new guy */
2843163953Srrs			*inp_p = inp;
2844172090Srrs			sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
2845216887Stuexen			if (send_int_conf) {
2846216887Stuexen				sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
2847216887Stuexen				    (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
2848216887Stuexen			}
2849166086Srrs			/*
2850166086Srrs			 * Pull it from the incomplete queue and wake the
2851166086Srrs			 * guy
2852166086Srrs			 */
2853252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2854172090Srrs			atomic_add_int(&(*stcb)->asoc.refcnt, 1);
2855172090Srrs			SCTP_TCB_UNLOCK((*stcb));
2856172090Srrs			SCTP_SOCKET_LOCK(so, 1);
2857172090Srrs#endif
2858166086Srrs			soisconnected(so);
2859252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2860172118Srrs			SCTP_TCB_LOCK((*stcb));
2861172118Srrs			atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
2862172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
2863172090Srrs#endif
2864163953Srrs			return (m);
2865163953Srrs		}
2866163953Srrs	}
2867238548Stuexen	if (notification) {
2868238548Stuexen		sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
2869163953Srrs	}
2870238548Stuexen	if (send_int_conf) {
2871238548Stuexen		sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
2872238548Stuexen		    (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
2873238548Stuexen	}
2874163953Srrs	return (m);
2875163953Srrs}
2876163953Srrs
2877163953Srrsstatic void
2878231038Stuexensctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
2879163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net)
2880163953Srrs{
2881163953Srrs	/* cp must not be used, others call this without a c-ack :-) */
2882163953Srrs	struct sctp_association *asoc;
2883163953Srrs
2884169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
2885169420Srrs	    "sctp_handle_cookie_ack: handling COOKIE-ACK\n");
2886163953Srrs	if (stcb == NULL)
2887163953Srrs		return;
2888163953Srrs
2889163953Srrs	asoc = &stcb->asoc;
2890163953Srrs
2891163953Srrs	sctp_stop_all_cookie_timers(stcb);
2892163953Srrs	/* process according to association state */
2893163953Srrs	if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED) {
2894163953Srrs		/* state change only needed when I am in right state */
2895169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "moving to OPEN state\n");
2896171943Srrs		SCTP_SET_STATE(asoc, SCTP_STATE_OPEN);
2897224641Stuexen		sctp_start_net_timers(stcb);
2898163953Srrs		if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
2899163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
2900163953Srrs			    stcb->sctp_ep, stcb, asoc->primary_destination);
2901163953Srrs
2902163953Srrs		}
2903163953Srrs		/* update RTO */
2904163953Srrs		SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
2905163953Srrs		SCTP_STAT_INCR_GAUGE32(sctps_currestab);
2906163953Srrs		if (asoc->overall_error_count == 0) {
2907163953Srrs			net->RTO = sctp_calculate_rto(stcb, asoc, net,
2908218186Srrs			    &asoc->time_entered, sctp_align_safe_nocopy,
2909219397Srrs			    SCTP_RTT_FROM_NON_DATA);
2910163953Srrs		}
2911169378Srrs		(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
2912172090Srrs		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_UP, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
2913163953Srrs		if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2914163953Srrs		    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
2915252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2916172090Srrs			struct socket *so;
2917172090Srrs
2918172090Srrs#endif
2919163953Srrs			stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
2920252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2921172090Srrs			so = SCTP_INP_SO(stcb->sctp_ep);
2922172090Srrs			atomic_add_int(&stcb->asoc.refcnt, 1);
2923172090Srrs			SCTP_TCB_UNLOCK(stcb);
2924172090Srrs			SCTP_SOCKET_LOCK(so, 1);
2925172090Srrs			SCTP_TCB_LOCK(stcb);
2926172090Srrs			atomic_subtract_int(&stcb->asoc.refcnt, 1);
2927218641Srrs#endif
2928218641Srrs			if ((stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) == 0) {
2929218641Srrs				soisconnected(stcb->sctp_socket);
2930172090Srrs			}
2931252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2932172090Srrs			SCTP_SOCKET_UNLOCK(so, 1);
2933172090Srrs#endif
2934163953Srrs		}
2935163953Srrs		/*
2936163953Srrs		 * since we did not send a HB make sure we don't double
2937163953Srrs		 * things
2938163953Srrs		 */
2939163953Srrs		net->hb_responded = 1;
2940163953Srrs
2941218641Srrs		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2942218641Srrs			/*
2943218641Srrs			 * We don't need to do the asconf thing, nor hb or
2944218641Srrs			 * autoclose if the socket is closed.
2945218641Srrs			 */
2946218641Srrs			goto closed_socket;
2947218641Srrs		}
2948218641Srrs		sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
2949218641Srrs		    stcb, net);
2950218641Srrs
2951218641Srrs
2952163953Srrs		if (stcb->asoc.sctp_autoclose_ticks &&
2953163953Srrs		    sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTOCLOSE)) {
2954163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
2955163953Srrs			    stcb->sctp_ep, stcb, NULL);
2956163953Srrs		}
2957163953Srrs		/*
2958171572Srrs		 * send ASCONF if parameters are pending and ASCONFs are
2959171572Srrs		 * allowed (eg. addresses changed when init/cookie echo were
2960171572Srrs		 * in flight)
2961163953Srrs		 */
2962163953Srrs		if ((sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DO_ASCONF)) &&
2963163953Srrs		    (stcb->asoc.peer_supports_asconf) &&
2964163953Srrs		    (!TAILQ_EMPTY(&stcb->asoc.asconf_queue))) {
2965171572Srrs#ifdef SCTP_TIMER_BASED_ASCONF
2966163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2967163953Srrs			    stcb->sctp_ep, stcb,
2968163953Srrs			    stcb->asoc.primary_destination);
2969171572Srrs#else
2970172190Srrs			sctp_send_asconf(stcb, stcb->asoc.primary_destination,
2971172190Srrs			    SCTP_ADDR_NOT_LOCKED);
2972171572Srrs#endif
2973163953Srrs		}
2974163953Srrs	}
2975218641Srrsclosed_socket:
2976163953Srrs	/* Toss the cookie if I can */
2977163953Srrs	sctp_toss_old_cookies(stcb, asoc);
2978163953Srrs	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
2979163953Srrs		/* Restart the timer if we have pending data */
2980163953Srrs		struct sctp_tmit_chunk *chk;
2981163953Srrs
2982163953Srrs		chk = TAILQ_FIRST(&asoc->sent_queue);
2983216822Stuexen		sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
2984163953Srrs	}
2985163953Srrs}
2986163953Srrs
2987163953Srrsstatic void
2988163953Srrssctp_handle_ecn_echo(struct sctp_ecne_chunk *cp,
2989163953Srrs    struct sctp_tcb *stcb)
2990163953Srrs{
2991163953Srrs	struct sctp_nets *net;
2992163953Srrs	struct sctp_tmit_chunk *lchk;
2993218072Srrs	struct sctp_ecne_chunk bkup;
2994231039Stuexen	uint8_t override_bit;
2995218072Srrs	uint32_t tsn, window_data_tsn;
2996218072Srrs	int len;
2997218232Srrs	unsigned int pkt_cnt;
2998163953Srrs
2999218072Srrs	len = ntohs(cp->ch.chunk_length);
3000218072Srrs	if ((len != sizeof(struct sctp_ecne_chunk)) &&
3001218072Srrs	    (len != sizeof(struct old_sctp_ecne_chunk))) {
3002163953Srrs		return;
3003163953Srrs	}
3004218072Srrs	if (len == sizeof(struct old_sctp_ecne_chunk)) {
3005218072Srrs		/* Its the old format */
3006218072Srrs		memcpy(&bkup, cp, sizeof(struct old_sctp_ecne_chunk));
3007218072Srrs		bkup.num_pkts_since_cwr = htonl(1);
3008218072Srrs		cp = &bkup;
3009218072Srrs	}
3010163953Srrs	SCTP_STAT_INCR(sctps_recvecne);
3011163953Srrs	tsn = ntohl(cp->tsn);
3012218072Srrs	pkt_cnt = ntohl(cp->num_pkts_since_cwr);
3013218072Srrs	lchk = TAILQ_LAST(&stcb->asoc.send_queue, sctpchunk_listhead);
3014163953Srrs	if (lchk == NULL) {
3015218129Srrs		window_data_tsn = stcb->asoc.sending_seq - 1;
3016163953Srrs	} else {
3017218129Srrs		window_data_tsn = lchk->rec.data.TSN_seq;
3018163953Srrs	}
3019163953Srrs
3020218072Srrs	/* Find where it was sent to if possible. */
3021163953Srrs	net = NULL;
3022216822Stuexen	TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
3023163953Srrs		if (lchk->rec.data.TSN_seq == tsn) {
3024163953Srrs			net = lchk->whoTo;
3025218186Srrs			net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send;
3026163953Srrs			break;
3027163953Srrs		}
3028216825Stuexen		if (SCTP_TSN_GT(lchk->rec.data.TSN_seq, tsn)) {
3029163953Srrs			break;
3030216825Stuexen		}
3031163953Srrs	}
3032218072Srrs	if (net == NULL) {
3033163953Srrs		/*
3034218072Srrs		 * What to do. A previous send of a CWR was possibly lost.
3035218072Srrs		 * See how old it is, we may have it marked on the actual
3036218072Srrs		 * net.
3037218072Srrs		 */
3038218072Srrs		TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3039218072Srrs			if (tsn == net->last_cwr_tsn) {
3040218072Srrs				/* Found him, send it off */
3041231039Stuexen				break;
3042218072Srrs			}
3043218072Srrs		}
3044231039Stuexen		if (net == NULL) {
3045231039Stuexen			/*
3046231039Stuexen			 * If we reach here, we need to send a special CWR
3047231039Stuexen			 * that says hey, we did this a long time ago and
3048231039Stuexen			 * you lost the response.
3049231039Stuexen			 */
3050231039Stuexen			net = TAILQ_FIRST(&stcb->asoc.nets);
3051231039Stuexen			if (net == NULL) {
3052231039Stuexen				/* TSNH */
3053231039Stuexen				return;
3054231039Stuexen			}
3055231039Stuexen			override_bit = SCTP_CWR_REDUCE_OVERRIDE;
3056231039Stuexen		} else {
3057231039Stuexen			override_bit = 0;
3058231039Stuexen		}
3059231039Stuexen	} else {
3060231039Stuexen		override_bit = 0;
3061218072Srrs	}
3062218129Srrs	if (SCTP_TSN_GT(tsn, net->cwr_window_tsn) &&
3063218129Srrs	    ((override_bit & SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
3064218072Srrs		/*
3065171440Srrs		 * JRS - Use the congestion control given in the pluggable
3066171440Srrs		 * CC module
3067171440Srrs		 */
3068218129Srrs		stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 0, pkt_cnt);
3069171440Srrs		/*
3070218072Srrs		 * We reduce once every RTT. So we will only lower cwnd at
3071218072Srrs		 * the next sending seq i.e. the window_data_tsn
3072163953Srrs		 */
3073218072Srrs		net->cwr_window_tsn = window_data_tsn;
3074218072Srrs		net->ecn_ce_pkt_cnt += pkt_cnt;
3075218072Srrs		net->lost_cnt = pkt_cnt;
3076218072Srrs		net->last_cwr_tsn = tsn;
3077218072Srrs	} else {
3078218072Srrs		override_bit |= SCTP_CWR_IN_SAME_WINDOW;
3079218129Srrs		if (SCTP_TSN_GT(tsn, net->last_cwr_tsn) &&
3080218129Srrs		    ((override_bit & SCTP_CWR_REDUCE_OVERRIDE) == 0)) {
3081218072Srrs			/*
3082218129Srrs			 * Another loss in the same window update how many
3083218129Srrs			 * marks/packets lost we have had.
3084218072Srrs			 */
3085218129Srrs			int cnt = 1;
3086218072Srrs
3087218072Srrs			if (pkt_cnt > net->lost_cnt) {
3088218072Srrs				/* Should be the case */
3089218129Srrs				cnt = (pkt_cnt - net->lost_cnt);
3090218129Srrs				net->ecn_ce_pkt_cnt += cnt;
3091218072Srrs			}
3092218129Srrs			net->lost_cnt = pkt_cnt;
3093218072Srrs			net->last_cwr_tsn = tsn;
3094218129Srrs			/*
3095218129Srrs			 * Most CC functions will ignore this call, since we
3096218129Srrs			 * are in-window yet of the initial CE the peer saw.
3097218129Srrs			 */
3098218129Srrs			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo(stcb, net, 1, cnt);
3099218072Srrs		}
3100163953Srrs	}
3101163953Srrs	/*
3102163953Srrs	 * We always send a CWR this way if our previous one was lost our
3103163953Srrs	 * peer will get an update, or if it is not time again to reduce we
3104218072Srrs	 * still get the cwr to the peer. Note we set the override when we
3105218072Srrs	 * could not find the TSN on the chunk or the destination network.
3106163953Srrs	 */
3107218072Srrs	sctp_send_cwr(stcb, net, net->last_cwr_tsn, override_bit);
3108163953Srrs}
3109163953Srrs
3110163953Srrsstatic void
3111218072Srrssctp_handle_ecn_cwr(struct sctp_cwr_chunk *cp, struct sctp_tcb *stcb, struct sctp_nets *net)
3112163953Srrs{
3113163953Srrs	/*
3114163953Srrs	 * Here we get a CWR from the peer. We must look in the outqueue and
3115240580Seadler	 * make sure that we have a covered ECNE in the control chunk part.
3116163953Srrs	 * If so remove it.
3117163953Srrs	 */
3118163953Srrs	struct sctp_tmit_chunk *chk;
3119163953Srrs	struct sctp_ecne_chunk *ecne;
3120218072Srrs	int override;
3121218072Srrs	uint32_t cwr_tsn;
3122163953Srrs
3123218072Srrs	cwr_tsn = ntohl(cp->tsn);
3124218072Srrs
3125218072Srrs	override = cp->ch.chunk_flags & SCTP_CWR_REDUCE_OVERRIDE;
3126163953Srrs	TAILQ_FOREACH(chk, &stcb->asoc.control_send_queue, sctp_next) {
3127163953Srrs		if (chk->rec.chunk_id.id != SCTP_ECN_ECHO) {
3128163953Srrs			continue;
3129163953Srrs		}
3130218072Srrs		if ((override == 0) && (chk->whoTo != net)) {
3131218072Srrs			/* Must be from the right src unless override is set */
3132218072Srrs			continue;
3133218072Srrs		}
3134163953Srrs		ecne = mtod(chk->data, struct sctp_ecne_chunk *);
3135218072Srrs		if (SCTP_TSN_GE(cwr_tsn, ntohl(ecne->tsn))) {
3136163953Srrs			/* this covers this ECNE, we can remove it */
3137163953Srrs			stcb->asoc.ecn_echo_cnt_onq--;
3138163953Srrs			TAILQ_REMOVE(&stcb->asoc.control_send_queue, chk,
3139163953Srrs			    sctp_next);
3140163953Srrs			if (chk->data) {
3141163953Srrs				sctp_m_freem(chk->data);
3142163953Srrs				chk->data = NULL;
3143163953Srrs			}
3144163953Srrs			stcb->asoc.ctrl_queue_cnt--;
3145221627Stuexen			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
3146218072Srrs			if (override == 0) {
3147218072Srrs				break;
3148218072Srrs			}
3149163953Srrs		}
3150163953Srrs	}
3151163953Srrs}
3152163953Srrs
3153163953Srrsstatic void
3154231038Stuexensctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSED,
3155163953Srrs    struct sctp_tcb *stcb, struct sctp_nets *net)
3156163953Srrs{
3157163953Srrs	struct sctp_association *asoc;
3158163953Srrs
3159252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3160172090Srrs	struct socket *so;
3161172090Srrs
3162172090Srrs#endif
3163172090Srrs
3164169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
3165169420Srrs	    "sctp_handle_shutdown_complete: handling SHUTDOWN-COMPLETE\n");
3166163953Srrs	if (stcb == NULL)
3167163953Srrs		return;
3168163953Srrs
3169163953Srrs	asoc = &stcb->asoc;
3170163953Srrs	/* process according to association state */
3171163953Srrs	if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT) {
3172163953Srrs		/* unexpected SHUTDOWN-COMPLETE... so ignore... */
3173171990Srrs		SCTPDBG(SCTP_DEBUG_INPUT2,
3174171990Srrs		    "sctp_handle_shutdown_complete: not in SCTP_STATE_SHUTDOWN_ACK_SENT --- ignore\n");
3175163953Srrs		SCTP_TCB_UNLOCK(stcb);
3176163953Srrs		return;
3177163953Srrs	}
3178163953Srrs	/* notify upper layer protocol */
3179163953Srrs	if (stcb->sctp_socket) {
3180172090Srrs		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
3181163953Srrs	}
3182252976Stuexen#ifdef INVARIANTS
3183252976Stuexen	if (!TAILQ_EMPTY(&asoc->send_queue) ||
3184252976Stuexen	    !TAILQ_EMPTY(&asoc->sent_queue) ||
3185252976Stuexen	    !stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
3186252976Stuexen		panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
3187252976Stuexen	}
3188252976Stuexen#endif
3189163953Srrs	/* stop the timer */
3190178202Srrs	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_22);
3191163953Srrs	SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
3192163953Srrs	/* free the TCB */
3193171990Srrs	SCTPDBG(SCTP_DEBUG_INPUT2,
3194171990Srrs	    "sctp_handle_shutdown_complete: calls free-asoc\n");
3195252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3196172090Srrs	so = SCTP_INP_SO(stcb->sctp_ep);
3197172090Srrs	atomic_add_int(&stcb->asoc.refcnt, 1);
3198172090Srrs	SCTP_TCB_UNLOCK(stcb);
3199172090Srrs	SCTP_SOCKET_LOCK(so, 1);
3200172090Srrs	SCTP_TCB_LOCK(stcb);
3201172090Srrs	atomic_subtract_int(&stcb->asoc.refcnt, 1);
3202172090Srrs#endif
3203171943Srrs	(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_23);
3204252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3205172090Srrs	SCTP_SOCKET_UNLOCK(so, 1);
3206172090Srrs#endif
3207163953Srrs	return;
3208163953Srrs}
3209163953Srrs
3210163953Srrsstatic int
3211163953Srrsprocess_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
3212163953Srrs    struct sctp_nets *net, uint8_t flg)
3213163953Srrs{
3214163953Srrs	switch (desc->chunk_type) {
3215211969Stuexen	case SCTP_DATA:
3216163953Srrs		/* find the tsn to resend (possibly */
3217163953Srrs		{
3218163953Srrs			uint32_t tsn;
3219163953Srrs			struct sctp_tmit_chunk *tp1;
3220163953Srrs
3221163953Srrs			tsn = ntohl(desc->tsn_ifany);
3222216822Stuexen			TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
3223163953Srrs				if (tp1->rec.data.TSN_seq == tsn) {
3224163953Srrs					/* found it */
3225163953Srrs					break;
3226163953Srrs				}
3227216825Stuexen				if (SCTP_TSN_GT(tp1->rec.data.TSN_seq, tsn)) {
3228163953Srrs					/* not found */
3229163953Srrs					tp1 = NULL;
3230163953Srrs					break;
3231163953Srrs				}
3232163953Srrs			}
3233163953Srrs			if (tp1 == NULL) {
3234163953Srrs				/*
3235163953Srrs				 * Do it the other way , aka without paying
3236163953Srrs				 * attention to queue seq order.
3237163953Srrs				 */
3238163953Srrs				SCTP_STAT_INCR(sctps_pdrpdnfnd);
3239216822Stuexen				TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
3240163953Srrs					if (tp1->rec.data.TSN_seq == tsn) {
3241163953Srrs						/* found it */
3242163953Srrs						break;
3243163953Srrs					}
3244163953Srrs				}
3245163953Srrs			}
3246163953Srrs			if (tp1 == NULL) {
3247163953Srrs				SCTP_STAT_INCR(sctps_pdrptsnnf);
3248163953Srrs			}
3249163953Srrs			if ((tp1) && (tp1->sent < SCTP_DATAGRAM_ACKED)) {
3250163953Srrs				uint8_t *ddp;
3251163953Srrs
3252214877Stuexen				if (((flg & SCTP_BADCRC) == 0) &&
3253214877Stuexen				    ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
3254214877Stuexen					return (0);
3255214877Stuexen				}
3256163953Srrs				if ((stcb->asoc.peers_rwnd == 0) &&
3257163953Srrs				    ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) {
3258163953Srrs					SCTP_STAT_INCR(sctps_pdrpdiwnp);
3259163953Srrs					return (0);
3260163953Srrs				}
3261163953Srrs				if (stcb->asoc.peers_rwnd == 0 &&
3262163953Srrs				    (flg & SCTP_FROM_MIDDLE_BOX)) {
3263163953Srrs					SCTP_STAT_INCR(sctps_pdrpdizrw);
3264163953Srrs					return (0);
3265163953Srrs				}
3266163953Srrs				ddp = (uint8_t *) (mtod(tp1->data, caddr_t)+
3267163953Srrs				    sizeof(struct sctp_data_chunk));
3268163953Srrs				{
3269163953Srrs					unsigned int iii;
3270163953Srrs
3271163953Srrs					for (iii = 0; iii < sizeof(desc->data_bytes);
3272163953Srrs					    iii++) {
3273163953Srrs						if (ddp[iii] != desc->data_bytes[iii]) {
3274163953Srrs							SCTP_STAT_INCR(sctps_pdrpbadd);
3275163953Srrs							return (-1);
3276163953Srrs						}
3277163953Srrs					}
3278163953Srrs				}
3279163953Srrs
3280163953Srrs				if (tp1->do_rtt) {
3281163953Srrs					/*
3282163953Srrs					 * this guy had a RTO calculation
3283163953Srrs					 * pending on it, cancel it
3284163953Srrs					 */
3285219397Srrs					if (tp1->whoTo->rto_needed == 0) {
3286219397Srrs						tp1->whoTo->rto_needed = 1;
3287219397Srrs					}
3288163953Srrs					tp1->do_rtt = 0;
3289163953Srrs				}
3290163953Srrs				SCTP_STAT_INCR(sctps_pdrpmark);
3291163953Srrs				if (tp1->sent != SCTP_DATAGRAM_RESEND)
3292163953Srrs					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
3293163953Srrs				/*
3294163953Srrs				 * mark it as if we were doing a FR, since
3295163953Srrs				 * we will be getting gap ack reports behind
3296163953Srrs				 * the info from the router.
3297163953Srrs				 */
3298163953Srrs				tp1->rec.data.doing_fast_retransmit = 1;
3299163953Srrs				/*
3300163953Srrs				 * mark the tsn with what sequences can
3301163953Srrs				 * cause a new FR.
3302163953Srrs				 */
3303163953Srrs				if (TAILQ_EMPTY(&stcb->asoc.send_queue)) {
3304163953Srrs					tp1->rec.data.fast_retran_tsn = stcb->asoc.sending_seq;
3305163953Srrs				} else {
3306163953Srrs					tp1->rec.data.fast_retran_tsn = (TAILQ_FIRST(&stcb->asoc.send_queue))->rec.data.TSN_seq;
3307163953Srrs				}
3308163953Srrs
3309163953Srrs				/* restart the timer */
3310163953Srrs				sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
3311171440Srrs				    stcb, tp1->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_24);
3312163953Srrs				sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
3313163953Srrs				    stcb, tp1->whoTo);
3314163953Srrs
3315163953Srrs				/* fix counts and things */
3316179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
3317170744Srrs					sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PDRP,
3318170744Srrs					    tp1->whoTo->flight_size,
3319170744Srrs					    tp1->book_size,
3320170744Srrs					    (uintptr_t) stcb,
3321170744Srrs					    tp1->rec.data.TSN_seq);
3322170744Srrs				}
3323190689Srrs				if (tp1->sent < SCTP_DATAGRAM_RESEND) {
3324190689Srrs					sctp_flight_size_decrease(tp1);
3325190689Srrs					sctp_total_flight_decrease(stcb, tp1);
3326190689Srrs				}
3327216502Stuexen				tp1->sent = SCTP_DATAGRAM_RESEND;
3328163953Srrs			} {
3329163953Srrs				/* audit code */
3330163953Srrs				unsigned int audit;
3331163953Srrs
3332163953Srrs				audit = 0;
3333163953Srrs				TAILQ_FOREACH(tp1, &stcb->asoc.sent_queue, sctp_next) {
3334163953Srrs					if (tp1->sent == SCTP_DATAGRAM_RESEND)
3335163953Srrs						audit++;
3336163953Srrs				}
3337163953Srrs				TAILQ_FOREACH(tp1, &stcb->asoc.control_send_queue,
3338163953Srrs				    sctp_next) {
3339163953Srrs					if (tp1->sent == SCTP_DATAGRAM_RESEND)
3340163953Srrs						audit++;
3341163953Srrs				}
3342163953Srrs				if (audit != stcb->asoc.sent_queue_retran_cnt) {
3343169420Srrs					SCTP_PRINTF("**Local Audit finds cnt:%d asoc cnt:%d\n",
3344163953Srrs					    audit, stcb->asoc.sent_queue_retran_cnt);
3345163953Srrs#ifndef SCTP_AUDITING_ENABLED
3346163953Srrs					stcb->asoc.sent_queue_retran_cnt = audit;
3347163953Srrs#endif
3348163953Srrs				}
3349163953Srrs			}
3350163953Srrs		}
3351163953Srrs		break;
3352163953Srrs	case SCTP_ASCONF:
3353163953Srrs		{
3354163953Srrs			struct sctp_tmit_chunk *asconf;
3355163953Srrs
3356163953Srrs			TAILQ_FOREACH(asconf, &stcb->asoc.control_send_queue,
3357163953Srrs			    sctp_next) {
3358163953Srrs				if (asconf->rec.chunk_id.id == SCTP_ASCONF) {
3359163953Srrs					break;
3360163953Srrs				}
3361163953Srrs			}
3362163953Srrs			if (asconf) {
3363163953Srrs				if (asconf->sent != SCTP_DATAGRAM_RESEND)
3364163953Srrs					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
3365163953Srrs				asconf->sent = SCTP_DATAGRAM_RESEND;
3366163953Srrs				asconf->snd_count--;
3367163953Srrs			}
3368163953Srrs		}
3369163953Srrs		break;
3370163953Srrs	case SCTP_INITIATION:
3371163953Srrs		/* resend the INIT */
3372163953Srrs		stcb->asoc.dropped_special_cnt++;
3373163953Srrs		if (stcb->asoc.dropped_special_cnt < SCTP_RETRY_DROPPED_THRESH) {
3374163953Srrs			/*
3375163953Srrs			 * If we can get it in, in a few attempts we do
3376163953Srrs			 * this, otherwise we let the timer fire.
3377163953Srrs			 */
3378163953Srrs			sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep,
3379171440Srrs			    stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_25);
3380172090Srrs			sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
3381163953Srrs		}
3382163953Srrs		break;
3383163953Srrs	case SCTP_SELECTIVE_ACK:
3384206137Stuexen	case SCTP_NR_SELECTIVE_ACK:
3385163953Srrs		/* resend the sack */
3386221627Stuexen		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
3387163953Srrs		break;
3388163953Srrs	case SCTP_HEARTBEAT_REQUEST:
3389163953Srrs		/* resend a demand HB */
3390171440Srrs		if ((stcb->asoc.overall_error_count + 3) < stcb->asoc.max_send_times) {
3391171440Srrs			/*
3392171440Srrs			 * Only retransmit if we KNOW we wont destroy the
3393171440Srrs			 * tcb
3394171440Srrs			 */
3395224641Stuexen			sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
3396171440Srrs		}
3397163953Srrs		break;
3398163953Srrs	case SCTP_SHUTDOWN:
3399163953Srrs		sctp_send_shutdown(stcb, net);
3400163953Srrs		break;
3401163953Srrs	case SCTP_SHUTDOWN_ACK:
3402163953Srrs		sctp_send_shutdown_ack(stcb, net);
3403163953Srrs		break;
3404163953Srrs	case SCTP_COOKIE_ECHO:
3405163953Srrs		{
3406163953Srrs			struct sctp_tmit_chunk *cookie;
3407163953Srrs
3408163953Srrs			cookie = NULL;
3409163953Srrs			TAILQ_FOREACH(cookie, &stcb->asoc.control_send_queue,
3410163953Srrs			    sctp_next) {
3411163953Srrs				if (cookie->rec.chunk_id.id == SCTP_COOKIE_ECHO) {
3412163953Srrs					break;
3413163953Srrs				}
3414163953Srrs			}
3415163953Srrs			if (cookie) {
3416163953Srrs				if (cookie->sent != SCTP_DATAGRAM_RESEND)
3417163953Srrs					sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
3418163953Srrs				cookie->sent = SCTP_DATAGRAM_RESEND;
3419163953Srrs				sctp_stop_all_cookie_timers(stcb);
3420163953Srrs			}
3421163953Srrs		}
3422163953Srrs		break;
3423163953Srrs	case SCTP_COOKIE_ACK:
3424163953Srrs		sctp_send_cookie_ack(stcb);
3425163953Srrs		break;
3426163953Srrs	case SCTP_ASCONF_ACK:
3427163953Srrs		/* resend last asconf ack */
3428171990Srrs		sctp_send_asconf_ack(stcb);
3429163953Srrs		break;
3430163953Srrs	case SCTP_FORWARD_CUM_TSN:
3431163953Srrs		send_forward_tsn(stcb, &stcb->asoc);
3432163953Srrs		break;
3433163953Srrs		/* can't do anything with these */
3434163953Srrs	case SCTP_PACKET_DROPPED:
3435163953Srrs	case SCTP_INITIATION_ACK:	/* this should not happen */
3436163953Srrs	case SCTP_HEARTBEAT_ACK:
3437163953Srrs	case SCTP_ABORT_ASSOCIATION:
3438163953Srrs	case SCTP_OPERATION_ERROR:
3439163953Srrs	case SCTP_SHUTDOWN_COMPLETE:
3440163953Srrs	case SCTP_ECN_ECHO:
3441163953Srrs	case SCTP_ECN_CWR:
3442163953Srrs	default:
3443163953Srrs		break;
3444163953Srrs	}
3445163953Srrs	return (0);
3446163953Srrs}
3447163953Srrs
3448163953Srrsvoid
3449252929Stuexensctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t * list)
3450163953Srrs{
3451252929Stuexen	uint32_t i;
3452163953Srrs	uint16_t temp;
3453163953Srrs
3454163953Srrs	/*
3455163953Srrs	 * We set things to 0xffff since this is the last delivered sequence
3456163953Srrs	 * and we will be sending in 0 after the reset.
3457163953Srrs	 */
3458163953Srrs
3459163953Srrs	if (number_entries) {
3460163953Srrs		for (i = 0; i < number_entries; i++) {
3461163953Srrs			temp = ntohs(list[i]);
3462163953Srrs			if (temp >= stcb->asoc.streamincnt) {
3463163953Srrs				continue;
3464163953Srrs			}
3465163953Srrs			stcb->asoc.strmin[temp].last_sequence_delivered = 0xffff;
3466163953Srrs		}
3467163953Srrs	} else {
3468163953Srrs		list = NULL;
3469163953Srrs		for (i = 0; i < stcb->asoc.streamincnt; i++) {
3470163953Srrs			stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
3471163953Srrs		}
3472163953Srrs	}
3473172090Srrs	sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_RECV, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
3474163953Srrs}
3475163953Srrs
3476163953Srrsstatic void
3477252976Stuexensctp_reset_out_streams(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t * list)
3478163953Srrs{
3479252976Stuexen	uint32_t i;
3480252976Stuexen	uint16_t temp;
3481163953Srrs
3482252976Stuexen	if (number_entries > 0) {
3483163953Srrs		for (i = 0; i < number_entries; i++) {
3484163953Srrs			temp = ntohs(list[i]);
3485163953Srrs			if (temp >= stcb->asoc.streamoutcnt) {
3486163953Srrs				/* no such stream */
3487163953Srrs				continue;
3488163953Srrs			}
3489252940Stuexen			stcb->asoc.strmout[temp].next_sequence_send = 0;
3490163953Srrs		}
3491252976Stuexen	} else {
3492252976Stuexen		for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
3493252976Stuexen			stcb->asoc.strmout[i].next_sequence_send = 0;
3494252976Stuexen		}
3495163953Srrs	}
3496172090Srrs	sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
3497163953Srrs}
3498163953Srrs
3499163953Srrs
3500163953Srrsstruct sctp_stream_reset_out_request *
3501163953Srrssctp_find_stream_reset(struct sctp_tcb *stcb, uint32_t seq, struct sctp_tmit_chunk **bchk)
3502163953Srrs{
3503163953Srrs	struct sctp_association *asoc;
3504252929Stuexen	struct sctp_chunkhdr *ch;
3505163953Srrs	struct sctp_stream_reset_out_request *r;
3506163953Srrs	struct sctp_tmit_chunk *chk;
3507163953Srrs	int len, clen;
3508163953Srrs
3509163953Srrs	asoc = &stcb->asoc;
3510163953Srrs	if (TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
3511169208Srrs		asoc->stream_reset_outstanding = 0;
3512163953Srrs		return (NULL);
3513163953Srrs	}
3514163953Srrs	if (stcb->asoc.str_reset == NULL) {
3515169208Srrs		asoc->stream_reset_outstanding = 0;
3516163953Srrs		return (NULL);
3517163953Srrs	}
3518163953Srrs	chk = stcb->asoc.str_reset;
3519163953Srrs	if (chk->data == NULL) {
3520163953Srrs		return (NULL);
3521163953Srrs	}
3522163953Srrs	if (bchk) {
3523163953Srrs		/* he wants a copy of the chk pointer */
3524163953Srrs		*bchk = chk;
3525163953Srrs	}
3526163953Srrs	clen = chk->send_size;
3527252929Stuexen	ch = mtod(chk->data, struct sctp_chunkhdr *);
3528252929Stuexen	r = (struct sctp_stream_reset_out_request *)(ch + 1);
3529163953Srrs	if (ntohl(r->request_seq) == seq) {
3530163953Srrs		/* found it */
3531163953Srrs		return (r);
3532163953Srrs	}
3533163953Srrs	len = SCTP_SIZE32(ntohs(r->ph.param_length));
3534163953Srrs	if (clen > (len + (int)sizeof(struct sctp_chunkhdr))) {
3535163953Srrs		/* move to the next one, there can only be a max of two */
3536163953Srrs		r = (struct sctp_stream_reset_out_request *)((caddr_t)r + len);
3537163953Srrs		if (ntohl(r->request_seq) == seq) {
3538163953Srrs			return (r);
3539163953Srrs		}
3540163953Srrs	}
3541163953Srrs	/* that seq is not here */
3542163953Srrs	return (NULL);
3543163953Srrs}
3544163953Srrs
3545163953Srrsstatic void
3546163953Srrssctp_clean_up_stream_reset(struct sctp_tcb *stcb)
3547163953Srrs{
3548163953Srrs	struct sctp_association *asoc;
3549163953Srrs	struct sctp_tmit_chunk *chk = stcb->asoc.str_reset;
3550163953Srrs
3551163953Srrs	if (stcb->asoc.str_reset == NULL) {
3552163953Srrs		return;
3553163953Srrs	}
3554166675Srrs	asoc = &stcb->asoc;
3555166675Srrs
3556171440Srrs	sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_26);
3557163953Srrs	TAILQ_REMOVE(&asoc->control_send_queue,
3558163953Srrs	    chk,
3559163953Srrs	    sctp_next);
3560163953Srrs	if (chk->data) {
3561163953Srrs		sctp_m_freem(chk->data);
3562163953Srrs		chk->data = NULL;
3563163953Srrs	}
3564163953Srrs	asoc->ctrl_queue_cnt--;
3565221627Stuexen	sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
3566172156Srrs	/* sa_ignore NO_NULL_CHK */
3567163953Srrs	stcb->asoc.str_reset = NULL;
3568163953Srrs}
3569163953Srrs
3570163953Srrs
3571163953Srrsstatic int
3572163953Srrssctp_handle_stream_reset_response(struct sctp_tcb *stcb,
3573163953Srrs    uint32_t seq, uint32_t action,
3574164139Srrs    struct sctp_stream_reset_response *respin)
3575163953Srrs{
3576163953Srrs	uint16_t type;
3577163953Srrs	int lparm_len;
3578163953Srrs	struct sctp_association *asoc = &stcb->asoc;
3579163953Srrs	struct sctp_tmit_chunk *chk;
3580163953Srrs	struct sctp_stream_reset_out_request *srparam;
3581252976Stuexen	uint32_t number_entries;
3582163953Srrs
3583163953Srrs	if (asoc->stream_reset_outstanding == 0) {
3584163953Srrs		/* duplicate */
3585163953Srrs		return (0);
3586163953Srrs	}
3587163953Srrs	if (seq == stcb->asoc.str_reset_seq_out) {
3588163953Srrs		srparam = sctp_find_stream_reset(stcb, seq, &chk);
3589163953Srrs		if (srparam) {
3590163953Srrs			stcb->asoc.str_reset_seq_out++;
3591163953Srrs			type = ntohs(srparam->ph.param_type);
3592163953Srrs			lparm_len = ntohs(srparam->ph.param_length);
3593163953Srrs			if (type == SCTP_STR_RESET_OUT_REQUEST) {
3594164139Srrs				number_entries = (lparm_len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t);
3595163953Srrs				asoc->stream_reset_out_is_outstanding = 0;
3596163953Srrs				if (asoc->stream_reset_outstanding)
3597163953Srrs					asoc->stream_reset_outstanding--;
3598235170Stuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
3599163953Srrs					/* do it */
3600163953Srrs					sctp_reset_out_streams(stcb, number_entries, srparam->list_of_streams);
3601235171Stuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3602235171Stuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3603163953Srrs				} else {
3604172090Srrs					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_OUT, stcb, number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3605163953Srrs				}
3606163953Srrs			} else if (type == SCTP_STR_RESET_IN_REQUEST) {
3607163953Srrs				/* Answered my request */
3608164139Srrs				number_entries = (lparm_len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t);
3609163953Srrs				if (asoc->stream_reset_outstanding)
3610163953Srrs					asoc->stream_reset_outstanding--;
3611235171Stuexen				if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3612235171Stuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_DENIED_IN, stcb,
3613235171Stuexen					    number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3614235171Stuexen				} else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
3615234790Stuexen					sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_FAILED_IN, stcb,
3616234790Stuexen					    number_entries, srparam->list_of_streams, SCTP_SO_NOT_LOCKED);
3617163953Srrs				}
3618234790Stuexen			} else if (type == SCTP_STR_RESET_ADD_OUT_STREAMS) {
3619188854Srrs				/* Ok we now may have more streams */
3620234790Stuexen				int num_stream;
3621234790Stuexen
3622234790Stuexen				num_stream = stcb->asoc.strm_pending_add_size;
3623234790Stuexen				if (num_stream > (stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt)) {
3624234790Stuexen					/* TSNH */
3625234790Stuexen					num_stream = stcb->asoc.strm_realoutsize - stcb->asoc.streamoutcnt;
3626234790Stuexen				}
3627234790Stuexen				stcb->asoc.strm_pending_add_size = 0;
3628189121Srrs				if (asoc->stream_reset_outstanding)
3629189121Srrs					asoc->stream_reset_outstanding--;
3630235170Stuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
3631188854Srrs					/* Put the new streams into effect */
3632234790Stuexen					stcb->asoc.streamoutcnt += num_stream;
3633234790Stuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
3634235171Stuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3635235171Stuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3636235171Stuexen					    SCTP_STREAM_CHANGE_DENIED);
3637188854Srrs				} else {
3638234790Stuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3639235171Stuexen					    SCTP_STREAM_CHANGE_FAILED);
3640188854Srrs				}
3641234790Stuexen			} else if (type == SCTP_STR_RESET_ADD_IN_STREAMS) {
3642234790Stuexen				if (asoc->stream_reset_outstanding)
3643234790Stuexen					asoc->stream_reset_outstanding--;
3644235171Stuexen				if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3645234790Stuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3646235171Stuexen					    SCTP_STREAM_CHANGE_DENIED);
3647235171Stuexen				} else if (action != SCTP_STREAM_RESET_RESULT_PERFORMED) {
3648235171Stuexen					sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt,
3649235171Stuexen					    SCTP_STREAM_CHANGE_FAILED);
3650234790Stuexen				}
3651163953Srrs			} else if (type == SCTP_STR_RESET_TSN_REQUEST) {
3652163953Srrs				/**
3653163953Srrs				 * a) Adopt the new in tsn.
3654163953Srrs				 * b) reset the map
3655163953Srrs				 * c) Adopt the new out-tsn
3656163953Srrs				 */
3657163953Srrs				struct sctp_stream_reset_response_tsn *resp;
3658163953Srrs				struct sctp_forward_tsn_chunk fwdtsn;
3659163953Srrs				int abort_flag = 0;
3660163953Srrs
3661163953Srrs				if (respin == NULL) {
3662163953Srrs					/* huh ? */
3663163953Srrs					return (0);
3664163953Srrs				}
3665277808Sdelphij				if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
3666277808Sdelphij					return (0);
3667277808Sdelphij				}
3668235170Stuexen				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
3669163953Srrs					resp = (struct sctp_stream_reset_response_tsn *)respin;
3670163953Srrs					asoc->stream_reset_outstanding--;
3671163953Srrs					fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
3672163953Srrs					fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
3673163953Srrs					fwdtsn.new_cumulative_tsn = htonl(ntohl(resp->senders_next_tsn) - 1);
3674170992Srrs					sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
3675163953Srrs					if (abort_flag) {
3676163953Srrs						return (1);
3677163953Srrs					}
3678163953Srrs					stcb->asoc.highest_tsn_inside_map = (ntohl(resp->senders_next_tsn) - 1);
3679179783Srrs					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
3680179783Srrs						sctp_log_map(0, 7, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
3681179783Srrs					}
3682180955Srrs					stcb->asoc.tsn_last_delivered = stcb->asoc.cumulative_tsn = stcb->asoc.highest_tsn_inside_map;
3683163953Srrs					stcb->asoc.mapping_array_base_tsn = ntohl(resp->senders_next_tsn);
3684163953Srrs					memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size);
3685185694Srrs
3686205627Srrs					stcb->asoc.highest_tsn_inside_nr_map = stcb->asoc.highest_tsn_inside_map;
3687206137Stuexen					memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size);
3688205627Srrs
3689163953Srrs					stcb->asoc.sending_seq = ntohl(resp->receivers_next_tsn);
3690163953Srrs					stcb->asoc.last_acked_seq = stcb->asoc.cumulative_tsn;
3691163953Srrs
3692163953Srrs					sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3693163953Srrs					sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3694234790Stuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1), 0);
3695235171Stuexen				} else if (action == SCTP_STREAM_RESET_RESULT_DENIED) {
3696235171Stuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
3697235171Stuexen					    SCTP_ASSOC_RESET_DENIED);
3698234790Stuexen				} else {
3699234790Stuexen					sctp_notify_stream_reset_tsn(stcb, stcb->asoc.sending_seq, (stcb->asoc.mapping_array_base_tsn + 1),
3700235171Stuexen					    SCTP_ASSOC_RESET_FAILED);
3701163953Srrs				}
3702163953Srrs			}
3703163953Srrs			/* get rid of the request and get the request flags */
3704163953Srrs			if (asoc->stream_reset_outstanding == 0) {
3705163953Srrs				sctp_clean_up_stream_reset(stcb);
3706163953Srrs			}
3707163953Srrs		}
3708163953Srrs	}
3709163953Srrs	return (0);
3710163953Srrs}
3711163953Srrs
3712163953Srrsstatic void
3713163953Srrssctp_handle_str_reset_request_in(struct sctp_tcb *stcb,
3714163953Srrs    struct sctp_tmit_chunk *chk,
3715170992Srrs    struct sctp_stream_reset_in_request *req, int trunc)
3716163953Srrs{
3717163953Srrs	uint32_t seq;
3718163953Srrs	int len, i;
3719163953Srrs	int number_entries;
3720163953Srrs	uint16_t temp;
3721163953Srrs
3722163953Srrs	/*
3723163953Srrs	 * peer wants me to send a str-reset to him for my outgoing seq's if
3724163953Srrs	 * seq_in is right.
3725163953Srrs	 */
3726163953Srrs	struct sctp_association *asoc = &stcb->asoc;
3727163953Srrs
3728163953Srrs	seq = ntohl(req->request_seq);
3729163953Srrs	if (asoc->str_reset_seq_in == seq) {
3730235170Stuexen		asoc->last_reset_action[1] = asoc->last_reset_action[0];
3731235170Stuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
3732235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3733235170Stuexen		} else if (trunc) {
3734170992Srrs			/* Can't do it, since they exceeded our buffer size  */
3735235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3736170992Srrs		} else if (stcb->asoc.stream_reset_out_is_outstanding == 0) {
3737163953Srrs			len = ntohs(req->ph.param_length);
3738163953Srrs			number_entries = ((len - sizeof(struct sctp_stream_reset_in_request)) / sizeof(uint16_t));
3739163953Srrs			for (i = 0; i < number_entries; i++) {
3740163953Srrs				temp = ntohs(req->list_of_streams[i]);
3741163953Srrs				req->list_of_streams[i] = temp;
3742163953Srrs			}
3743235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
3744163953Srrs			sctp_add_stream_reset_out(chk, number_entries, req->list_of_streams,
3745163953Srrs			    asoc->str_reset_seq_out,
3746163953Srrs			    seq, (asoc->sending_seq - 1));
3747163953Srrs			asoc->stream_reset_out_is_outstanding = 1;
3748163953Srrs			asoc->str_reset = chk;
3749163953Srrs			sctp_timer_start(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo);
3750163953Srrs			stcb->asoc.stream_reset_outstanding++;
3751163953Srrs		} else {
3752163953Srrs			/* Can't do it, since we have sent one out */
3753235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
3754163953Srrs		}
3755234790Stuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3756163953Srrs		asoc->str_reset_seq_in++;
3757163953Srrs	} else if (asoc->str_reset_seq_in - 1 == seq) {
3758163953Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3759163953Srrs	} else if (asoc->str_reset_seq_in - 2 == seq) {
3760163953Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3761163953Srrs	} else {
3762235170Stuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
3763163953Srrs	}
3764163953Srrs}
3765163953Srrs
3766163953Srrsstatic int
3767163953Srrssctp_handle_str_reset_request_tsn(struct sctp_tcb *stcb,
3768163953Srrs    struct sctp_tmit_chunk *chk,
3769163953Srrs    struct sctp_stream_reset_tsn_request *req)
3770163953Srrs{
3771163953Srrs	/* reset all in and out and update the tsn */
3772163953Srrs	/*
3773163953Srrs	 * A) reset my str-seq's on in and out. B) Select a receive next,
3774163953Srrs	 * and set cum-ack to it. Also process this selected number as a
3775163953Srrs	 * fwd-tsn as well. C) set in the response my next sending seq.
3776163953Srrs	 */
3777163953Srrs	struct sctp_forward_tsn_chunk fwdtsn;
3778163953Srrs	struct sctp_association *asoc = &stcb->asoc;
3779163953Srrs	int abort_flag = 0;
3780163953Srrs	uint32_t seq;
3781163953Srrs
3782163953Srrs	seq = ntohl(req->request_seq);
3783163953Srrs	if (asoc->str_reset_seq_in == seq) {
3784235433Stuexen		asoc->last_reset_action[1] = stcb->asoc.last_reset_action[0];
3785235170Stuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
3786235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3787235433Stuexen		} else {
3788235170Stuexen			fwdtsn.ch.chunk_length = htons(sizeof(struct sctp_forward_tsn_chunk));
3789235433Stuexen			fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
3790235433Stuexen			fwdtsn.ch.chunk_flags = 0;
3791235433Stuexen			fwdtsn.new_cumulative_tsn = htonl(stcb->asoc.highest_tsn_inside_map + 1);
3792235433Stuexen			sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
3793235433Stuexen			if (abort_flag) {
3794235433Stuexen				return (1);
3795235433Stuexen			}
3796235433Stuexen			asoc->highest_tsn_inside_map += SCTP_STREAM_RESET_TSN_DELTA;
3797235433Stuexen			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
3798235433Stuexen				sctp_log_map(0, 10, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
3799235433Stuexen			}
3800235433Stuexen			asoc->tsn_last_delivered = asoc->cumulative_tsn = asoc->highest_tsn_inside_map;
3801235433Stuexen			asoc->mapping_array_base_tsn = asoc->highest_tsn_inside_map + 1;
3802235433Stuexen			memset(asoc->mapping_array, 0, asoc->mapping_array_size);
3803235433Stuexen			asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
3804235433Stuexen			memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
3805235433Stuexen			atomic_add_int(&asoc->sending_seq, 1);
3806235433Stuexen			/* save off historical data for retrans */
3807235433Stuexen			asoc->last_sending_seq[1] = asoc->last_sending_seq[0];
3808235433Stuexen			asoc->last_sending_seq[0] = asoc->sending_seq;
3809235433Stuexen			asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0];
3810235433Stuexen			asoc->last_base_tsnsent[0] = asoc->mapping_array_base_tsn;
3811235433Stuexen			sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
3812235433Stuexen			sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
3813235433Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
3814235433Stuexen			sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, (asoc->mapping_array_base_tsn + 1), 0);
3815163953Srrs		}
3816235433Stuexen		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
3817235433Stuexen		    asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
3818163953Srrs		asoc->str_reset_seq_in++;
3819163953Srrs	} else if (asoc->str_reset_seq_in - 1 == seq) {
3820163953Srrs		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[0],
3821235170Stuexen		    asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
3822163953Srrs	} else if (asoc->str_reset_seq_in - 2 == seq) {
3823163953Srrs		sctp_add_stream_reset_result_tsn(chk, seq, asoc->last_reset_action[1],
3824235170Stuexen		    asoc->last_sending_seq[1], asoc->last_base_tsnsent[1]);
3825163953Srrs	} else {
3826235170Stuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
3827163953Srrs	}
3828163953Srrs	return (0);
3829163953Srrs}
3830163953Srrs
3831163953Srrsstatic void
3832163953Srrssctp_handle_str_reset_request_out(struct sctp_tcb *stcb,
3833163953Srrs    struct sctp_tmit_chunk *chk,
3834170992Srrs    struct sctp_stream_reset_out_request *req, int trunc)
3835163953Srrs{
3836163953Srrs	uint32_t seq, tsn;
3837163953Srrs	int number_entries, len;
3838163953Srrs	struct sctp_association *asoc = &stcb->asoc;
3839163953Srrs
3840163953Srrs	seq = ntohl(req->request_seq);
3841163953Srrs
3842163953Srrs	/* now if its not a duplicate we process it */
3843163953Srrs	if (asoc->str_reset_seq_in == seq) {
3844163953Srrs		len = ntohs(req->ph.param_length);
3845163953Srrs		number_entries = ((len - sizeof(struct sctp_stream_reset_out_request)) / sizeof(uint16_t));
3846163953Srrs		/*
3847163953Srrs		 * the sender is resetting, handle the list issue.. we must
3848163953Srrs		 * a) verify if we can do the reset, if so no problem b) If
3849163953Srrs		 * we can't do the reset we must copy the request. c) queue
3850163953Srrs		 * it, and setup the data in processor to trigger it off
3851163953Srrs		 * when needed and dequeue all the queued data.
3852163953Srrs		 */
3853163953Srrs		tsn = ntohl(req->send_reset_at_tsn);
3854163953Srrs
3855163953Srrs		/* move the reset action back one */
3856163953Srrs		asoc->last_reset_action[1] = asoc->last_reset_action[0];
3857235170Stuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_RESET_STREAM_REQ)) {
3858235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3859235170Stuexen		} else if (trunc) {
3860235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3861216825Stuexen		} else if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) {
3862163953Srrs			/* we can do it now */
3863163953Srrs			sctp_reset_in_stream(stcb, number_entries, req->list_of_streams);
3864235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
3865163953Srrs		} else {
3866163953Srrs			/*
3867163953Srrs			 * we must queue it up and thus wait for the TSN's
3868163953Srrs			 * to arrive that are at or before tsn
3869163953Srrs			 */
3870163953Srrs			struct sctp_stream_reset_list *liste;
3871163953Srrs			int siz;
3872163953Srrs
3873163953Srrs			siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
3874163953Srrs			SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
3875170091Srrs			    siz, SCTP_M_STRESET);
3876163953Srrs			if (liste == NULL) {
3877163953Srrs				/* gak out of memory */
3878235170Stuexen				asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3879235170Stuexen				sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3880163953Srrs				return;
3881163953Srrs			}
3882163953Srrs			liste->tsn = tsn;
3883163953Srrs			liste->number_entries = number_entries;
3884252929Stuexen			memcpy(&liste->list_of_streams, req->list_of_streams, number_entries * sizeof(uint16_t));
3885163953Srrs			TAILQ_INSERT_TAIL(&asoc->resetHead, liste, next_resp);
3886235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
3887163953Srrs		}
3888234790Stuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3889163953Srrs		asoc->str_reset_seq_in++;
3890163953Srrs	} else if ((asoc->str_reset_seq_in - 1) == seq) {
3891163953Srrs		/*
3892163953Srrs		 * one seq back, just echo back last action since my
3893163953Srrs		 * response was lost.
3894163953Srrs		 */
3895163953Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3896163953Srrs	} else if ((asoc->str_reset_seq_in - 2) == seq) {
3897163953Srrs		/*
3898163953Srrs		 * two seq back, just echo back last action since my
3899163953Srrs		 * response was lost.
3900163953Srrs		 */
3901163953Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3902163953Srrs	} else {
3903235170Stuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
3904163953Srrs	}
3905163953Srrs}
3906163953Srrs
3907188854Srrsstatic void
3908188854Srrssctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
3909188854Srrs    struct sctp_stream_reset_add_strm *str_add)
3910188854Srrs{
3911188854Srrs	/*
3912188854Srrs	 * Peer is requesting to add more streams. If its within our
3913188854Srrs	 * max-streams we will allow it.
3914188854Srrs	 */
3915234790Stuexen	uint32_t num_stream, i;
3916188854Srrs	uint32_t seq;
3917189121Srrs	struct sctp_association *asoc = &stcb->asoc;
3918216822Stuexen	struct sctp_queued_to_read *ctl, *nctl;
3919188854Srrs
3920188854Srrs	/* Get the number. */
3921188854Srrs	seq = ntohl(str_add->request_seq);
3922188854Srrs	num_stream = ntohs(str_add->number_of_streams);
3923188854Srrs	/* Now what would be the new total? */
3924189121Srrs	if (asoc->str_reset_seq_in == seq) {
3925189121Srrs		num_stream += stcb->asoc.streamincnt;
3926235170Stuexen		stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
3927235170Stuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
3928235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3929235170Stuexen		} else if ((num_stream > stcb->asoc.max_inbound_streams) ||
3930234790Stuexen		    (num_stream > 0xffff)) {
3931189121Srrs			/* We must reject it they ask for to many */
3932189121Srrs	denied:
3933235170Stuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
3934189121Srrs		} else {
3935189121Srrs			/* Ok, we can do that :-) */
3936189121Srrs			struct sctp_stream_in *oldstrm;
3937189121Srrs
3938189121Srrs			/* save off the old */
3939189121Srrs			oldstrm = stcb->asoc.strmin;
3940189121Srrs			SCTP_MALLOC(stcb->asoc.strmin, struct sctp_stream_in *,
3941189121Srrs			    (num_stream * sizeof(struct sctp_stream_in)),
3942189121Srrs			    SCTP_M_STRMI);
3943189121Srrs			if (stcb->asoc.strmin == NULL) {
3944189121Srrs				stcb->asoc.strmin = oldstrm;
3945189121Srrs				goto denied;
3946189121Srrs			}
3947189121Srrs			/* copy off the old data */
3948189121Srrs			for (i = 0; i < stcb->asoc.streamincnt; i++) {
3949189121Srrs				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
3950189121Srrs				stcb->asoc.strmin[i].stream_no = i;
3951189121Srrs				stcb->asoc.strmin[i].last_sequence_delivered = oldstrm[i].last_sequence_delivered;
3952189121Srrs				stcb->asoc.strmin[i].delivery_started = oldstrm[i].delivery_started;
3953189121Srrs				/* now anything on those queues? */
3954216822Stuexen				TAILQ_FOREACH_SAFE(ctl, &oldstrm[i].inqueue, next, nctl) {
3955189121Srrs					TAILQ_REMOVE(&oldstrm[i].inqueue, ctl, next);
3956189121Srrs					TAILQ_INSERT_TAIL(&stcb->asoc.strmin[i].inqueue, ctl, next);
3957189121Srrs				}
3958189121Srrs			}
3959189121Srrs			/* Init the new streams */
3960189121Srrs			for (i = stcb->asoc.streamincnt; i < num_stream; i++) {
3961189121Srrs				TAILQ_INIT(&stcb->asoc.strmin[i].inqueue);
3962189121Srrs				stcb->asoc.strmin[i].stream_no = i;
3963189121Srrs				stcb->asoc.strmin[i].last_sequence_delivered = 0xffff;
3964189121Srrs				stcb->asoc.strmin[i].delivery_started = 0;
3965189121Srrs			}
3966189121Srrs			SCTP_FREE(oldstrm, SCTP_M_STRMI);
3967189121Srrs			/* update the size */
3968189121Srrs			stcb->asoc.streamincnt = num_stream;
3969235170Stuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
3970234790Stuexen			sctp_notify_stream_reset_add(stcb, stcb->asoc.streamincnt, stcb->asoc.streamoutcnt, 0);
3971189121Srrs		}
3972234790Stuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3973234790Stuexen		asoc->str_reset_seq_in++;
3974189121Srrs	} else if ((asoc->str_reset_seq_in - 1) == seq) {
3975189121Srrs		/*
3976189121Srrs		 * one seq back, just echo back last action since my
3977189121Srrs		 * response was lost.
3978189121Srrs		 */
3979189121Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
3980189121Srrs	} else if ((asoc->str_reset_seq_in - 2) == seq) {
3981189121Srrs		/*
3982189121Srrs		 * two seq back, just echo back last action since my
3983189121Srrs		 * response was lost.
3984189121Srrs		 */
3985189121Srrs		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
3986188854Srrs	} else {
3987235170Stuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
3988188854Srrs
3989188854Srrs	}
3990188854Srrs}
3991188854Srrs
3992234790Stuexenstatic void
3993234790Stuexensctp_handle_str_reset_add_out_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk,
3994234790Stuexen    struct sctp_stream_reset_add_strm *str_add)
3995234790Stuexen{
3996234790Stuexen	/*
3997234790Stuexen	 * Peer is requesting to add more streams. If its within our
3998234790Stuexen	 * max-streams we will allow it.
3999234790Stuexen	 */
4000234790Stuexen	uint16_t num_stream;
4001234790Stuexen	uint32_t seq;
4002234790Stuexen	struct sctp_association *asoc = &stcb->asoc;
4003234790Stuexen
4004234790Stuexen	/* Get the number. */
4005234790Stuexen	seq = ntohl(str_add->request_seq);
4006234790Stuexen	num_stream = ntohs(str_add->number_of_streams);
4007234790Stuexen	/* Now what would be the new total? */
4008234790Stuexen	if (asoc->str_reset_seq_in == seq) {
4009235170Stuexen		stcb->asoc.last_reset_action[1] = stcb->asoc.last_reset_action[0];
4010235170Stuexen		if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
4011235170Stuexen			asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
4012235170Stuexen		} else if (stcb->asoc.stream_reset_outstanding) {
4013234790Stuexen			/* We must reject it we have something pending */
4014235170Stuexen			stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_ERR_IN_PROGRESS;
4015234790Stuexen		} else {
4016234790Stuexen			/* Ok, we can do that :-) */
4017234790Stuexen			int mychk;
4018234790Stuexen
4019234790Stuexen			mychk = stcb->asoc.streamoutcnt;
4020234790Stuexen			mychk += num_stream;
4021234790Stuexen			if (mychk < 0x10000) {
4022235170Stuexen				stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
4023234790Stuexen				if (sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, 1, num_stream, 0, 1)) {
4024235170Stuexen					stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
4025234790Stuexen				}
4026234790Stuexen			} else {
4027235170Stuexen				stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
4028234790Stuexen			}
4029234790Stuexen		}
4030234790Stuexen		sctp_add_stream_reset_result(chk, seq, stcb->asoc.last_reset_action[0]);
4031234790Stuexen		asoc->str_reset_seq_in++;
4032234790Stuexen	} else if ((asoc->str_reset_seq_in - 1) == seq) {
4033234790Stuexen		/*
4034234790Stuexen		 * one seq back, just echo back last action since my
4035234790Stuexen		 * response was lost.
4036234790Stuexen		 */
4037234790Stuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[0]);
4038234790Stuexen	} else if ((asoc->str_reset_seq_in - 2) == seq) {
4039234790Stuexen		/*
4040234790Stuexen		 * two seq back, just echo back last action since my
4041234790Stuexen		 * response was lost.
4042234790Stuexen		 */
4043234790Stuexen		sctp_add_stream_reset_result(chk, seq, asoc->last_reset_action[1]);
4044234790Stuexen	} else {
4045235170Stuexen		sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_RESULT_ERR_BAD_SEQNO);
4046234790Stuexen	}
4047234790Stuexen}
4048234790Stuexen
4049170992Srrs#ifdef __GNUC__
4050170992Srrs__attribute__((noinline))
4051170992Srrs#endif
4052170992Srrs	static int
4053170992Srrs	    sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
4054252929Stuexen        struct sctp_chunkhdr *ch_req)
4055163953Srrs{
4056277808Sdelphij	uint16_t remaining_length, param_len, ptype;
4057170992Srrs	struct sctp_paramhdr pstore;
4058170992Srrs	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
4059234790Stuexen	uint32_t seq = 0;
4060163953Srrs	int num_req = 0;
4061170992Srrs	int trunc = 0;
4062163953Srrs	struct sctp_tmit_chunk *chk;
4063163953Srrs	struct sctp_chunkhdr *ch;
4064163953Srrs	struct sctp_paramhdr *ph;
4065166675Srrs	int ret_code = 0;
4066166675Srrs	int num_param = 0;
4067163953Srrs
4068163953Srrs	/* now it may be a reset or a reset-response */
4069277808Sdelphij	remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
4070163953Srrs
4071163953Srrs	/* setup for adding the response */
4072163953Srrs	sctp_alloc_a_chunk(stcb, chk);
4073163953Srrs	if (chk == NULL) {
4074163953Srrs		return (ret_code);
4075163953Srrs	}
4076163953Srrs	chk->rec.chunk_id.id = SCTP_STREAM_RESET;
4077169208Srrs	chk->rec.chunk_id.can_take_data = 0;
4078163953Srrs	chk->asoc = &stcb->asoc;
4079163953Srrs	chk->no_fr_allowed = 0;
4080163953Srrs	chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
4081166023Srrs	chk->book_size_scale = 0;
4082165647Srrs	chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
4083163953Srrs	if (chk->data == NULL) {
4084163953Srrsstrres_nochunk:
4085163953Srrs		if (chk->data) {
4086163953Srrs			sctp_m_freem(chk->data);
4087163953Srrs			chk->data = NULL;
4088163953Srrs		}
4089221627Stuexen		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
4090163953Srrs		return (ret_code);
4091163953Srrs	}
4092165647Srrs	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
4093163953Srrs
4094163953Srrs	/* setup chunk parameters */
4095163953Srrs	chk->sent = SCTP_DATAGRAM_UNSENT;
4096163953Srrs	chk->snd_count = 0;
4097224641Stuexen	chk->whoTo = NULL;
4098163953Srrs
4099163953Srrs	ch = mtod(chk->data, struct sctp_chunkhdr *);
4100163953Srrs	ch->chunk_type = SCTP_STREAM_RESET;
4101163953Srrs	ch->chunk_flags = 0;
4102163953Srrs	ch->chunk_length = htons(chk->send_size);
4103165647Srrs	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
4104170992Srrs	offset += sizeof(struct sctp_chunkhdr);
4105277808Sdelphij	while (remaining_length >= sizeof(struct sctp_paramhdr)) {
4106170992Srrs		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore);
4107277808Sdelphij		if (ph == NULL) {
4108277808Sdelphij			/* TSNH */
4109170992Srrs			break;
4110277808Sdelphij		}
4111163953Srrs		param_len = ntohs(ph->param_length);
4112277808Sdelphij		if ((param_len > remaining_length) ||
4113277808Sdelphij		    (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
4114277808Sdelphij			/* bad parameter length */
4115163953Srrs			break;
4116163953Srrs		}
4117277808Sdelphij		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
4118170992Srrs		    (uint8_t *) & cstore);
4119277808Sdelphij		if (ph == NULL) {
4120277808Sdelphij			/* TSNH */
4121277808Sdelphij			break;
4122277808Sdelphij		}
4123163953Srrs		ptype = ntohs(ph->param_type);
4124163953Srrs		num_param++;
4125277808Sdelphij		if (param_len > sizeof(cstore)) {
4126170992Srrs			trunc = 1;
4127170992Srrs		} else {
4128170992Srrs			trunc = 0;
4129170992Srrs		}
4130163953Srrs		if (num_param > SCTP_MAX_RESET_PARAMS) {
4131163953Srrs			/* hit the max of parameters already sorry.. */
4132163953Srrs			break;
4133163953Srrs		}
4134163953Srrs		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
4135163953Srrs			struct sctp_stream_reset_out_request *req_out;
4136163953Srrs
4137277808Sdelphij			if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
4138277808Sdelphij				break;
4139277808Sdelphij			}
4140163953Srrs			req_out = (struct sctp_stream_reset_out_request *)ph;
4141163953Srrs			num_req++;
4142163953Srrs			if (stcb->asoc.stream_reset_outstanding) {
4143163953Srrs				seq = ntohl(req_out->response_seq);
4144163953Srrs				if (seq == stcb->asoc.str_reset_seq_out) {
4145163953Srrs					/* implicit ack */
4146235170Stuexen					(void)sctp_handle_stream_reset_response(stcb, seq, SCTP_STREAM_RESET_RESULT_PERFORMED, NULL);
4147163953Srrs				}
4148163953Srrs			}
4149170992Srrs			sctp_handle_str_reset_request_out(stcb, chk, req_out, trunc);
4150234790Stuexen		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
4151188854Srrs			struct sctp_stream_reset_add_strm *str_add;
4152188854Srrs
4153277808Sdelphij			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
4154277808Sdelphij				break;
4155277808Sdelphij			}
4156188854Srrs			str_add = (struct sctp_stream_reset_add_strm *)ph;
4157188854Srrs			num_req++;
4158188854Srrs			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
4159234790Stuexen		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
4160234790Stuexen			struct sctp_stream_reset_add_strm *str_add;
4161234790Stuexen
4162277808Sdelphij			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
4163277808Sdelphij				break;
4164277808Sdelphij			}
4165234790Stuexen			str_add = (struct sctp_stream_reset_add_strm *)ph;
4166234790Stuexen			num_req++;
4167234790Stuexen			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
4168163953Srrs		} else if (ptype == SCTP_STR_RESET_IN_REQUEST) {
4169163953Srrs			struct sctp_stream_reset_in_request *req_in;
4170163953Srrs
4171163953Srrs			num_req++;
4172163953Srrs			req_in = (struct sctp_stream_reset_in_request *)ph;
4173170992Srrs			sctp_handle_str_reset_request_in(stcb, chk, req_in, trunc);
4174163953Srrs		} else if (ptype == SCTP_STR_RESET_TSN_REQUEST) {
4175163953Srrs			struct sctp_stream_reset_tsn_request *req_tsn;
4176163953Srrs
4177163953Srrs			num_req++;
4178163953Srrs			req_tsn = (struct sctp_stream_reset_tsn_request *)ph;
4179163953Srrs			if (sctp_handle_str_reset_request_tsn(stcb, chk, req_tsn)) {
4180163953Srrs				ret_code = 1;
4181163953Srrs				goto strres_nochunk;
4182163953Srrs			}
4183163953Srrs			/* no more */
4184163953Srrs			break;
4185163953Srrs		} else if (ptype == SCTP_STR_RESET_RESPONSE) {
4186163953Srrs			struct sctp_stream_reset_response *resp;
4187163953Srrs			uint32_t result;
4188163953Srrs
4189277808Sdelphij			if (param_len < sizeof(struct sctp_stream_reset_response)) {
4190277808Sdelphij				break;
4191277808Sdelphij			}
4192163953Srrs			resp = (struct sctp_stream_reset_response *)ph;
4193163953Srrs			seq = ntohl(resp->response_seq);
4194163953Srrs			result = ntohl(resp->result);
4195163953Srrs			if (sctp_handle_stream_reset_response(stcb, seq, result, resp)) {
4196163953Srrs				ret_code = 1;
4197163953Srrs				goto strres_nochunk;
4198163953Srrs			}
4199163953Srrs		} else {
4200163953Srrs			break;
4201163953Srrs		}
4202170992Srrs		offset += SCTP_SIZE32(param_len);
4203277808Sdelphij		if (remaining_length >= SCTP_SIZE32(param_len)) {
4204277808Sdelphij			remaining_length -= SCTP_SIZE32(param_len);
4205277808Sdelphij		} else {
4206277808Sdelphij			remaining_length = 0;
4207277808Sdelphij		}
4208163953Srrs	}
4209163953Srrs	if (num_req == 0) {
4210163953Srrs		/* we have no response free the stuff */
4211163953Srrs		goto strres_nochunk;
4212163953Srrs	}
4213163953Srrs	/* ok we have a chunk to link in */
4214163953Srrs	TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue,
4215163953Srrs	    chk,
4216163953Srrs	    sctp_next);
4217163953Srrs	stcb->asoc.ctrl_queue_cnt++;
4218163953Srrs	return (ret_code);
4219163953Srrs}
4220163953Srrs
4221163953Srrs/*
4222163953Srrs * Handle a router or endpoints report of a packet loss, there are two ways
4223163953Srrs * to handle this, either we get the whole packet and must disect it
4224163953Srrs * ourselves (possibly with truncation and or corruption) or it is a summary
4225163953Srrs * from a middle box that did the disectting for us.
4226163953Srrs */
4227163953Srrsstatic void
4228163953Srrssctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
4229170781Srrs    struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t limit)
4230163953Srrs{
4231163953Srrs	uint32_t bottle_bw, on_queue;
4232163953Srrs	uint16_t trunc_len;
4233163953Srrs	unsigned int chlen;
4234163953Srrs	unsigned int at;
4235163953Srrs	struct sctp_chunk_desc desc;
4236163953Srrs	struct sctp_chunkhdr *ch;
4237163953Srrs
4238163953Srrs	chlen = ntohs(cp->ch.chunk_length);
4239163953Srrs	chlen -= sizeof(struct sctp_pktdrop_chunk);
4240163953Srrs	/* XXX possible chlen underflow */
4241163953Srrs	if (chlen == 0) {
4242163953Srrs		ch = NULL;
4243163953Srrs		if (cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX)
4244163953Srrs			SCTP_STAT_INCR(sctps_pdrpbwrpt);
4245163953Srrs	} else {
4246163953Srrs		ch = (struct sctp_chunkhdr *)(cp->data + sizeof(struct sctphdr));
4247163953Srrs		chlen -= sizeof(struct sctphdr);
4248163953Srrs		/* XXX possible chlen underflow */
4249163953Srrs		memset(&desc, 0, sizeof(desc));
4250163953Srrs	}
4251163953Srrs	trunc_len = (uint16_t) ntohs(cp->trunc_len);
4252170781Srrs	if (trunc_len > limit) {
4253170781Srrs		trunc_len = limit;
4254170781Srrs	}
4255163953Srrs	/* now the chunks themselves */
4256163953Srrs	while ((ch != NULL) && (chlen >= sizeof(struct sctp_chunkhdr))) {
4257163953Srrs		desc.chunk_type = ch->chunk_type;
4258163953Srrs		/* get amount we need to move */
4259163953Srrs		at = ntohs(ch->chunk_length);
4260163953Srrs		if (at < sizeof(struct sctp_chunkhdr)) {
4261163953Srrs			/* corrupt chunk, maybe at the end? */
4262163953Srrs			SCTP_STAT_INCR(sctps_pdrpcrupt);
4263163953Srrs			break;
4264163953Srrs		}
4265163953Srrs		if (trunc_len == 0) {
4266163953Srrs			/* we are supposed to have all of it */
4267163953Srrs			if (at > chlen) {
4268163953Srrs				/* corrupt skip it */
4269163953Srrs				SCTP_STAT_INCR(sctps_pdrpcrupt);
4270163953Srrs				break;
4271163953Srrs			}
4272163953Srrs		} else {
4273163953Srrs			/* is there enough of it left ? */
4274163953Srrs			if (desc.chunk_type == SCTP_DATA) {
4275163953Srrs				if (chlen < (sizeof(struct sctp_data_chunk) +
4276163953Srrs				    sizeof(desc.data_bytes))) {
4277163953Srrs					break;
4278163953Srrs				}
4279163953Srrs			} else {
4280163953Srrs				if (chlen < sizeof(struct sctp_chunkhdr)) {
4281163953Srrs					break;
4282163953Srrs				}
4283163953Srrs			}
4284163953Srrs		}
4285163953Srrs		if (desc.chunk_type == SCTP_DATA) {
4286163953Srrs			/* can we get out the tsn? */
4287163953Srrs			if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
4288163953Srrs				SCTP_STAT_INCR(sctps_pdrpmbda);
4289163953Srrs
4290163953Srrs			if (chlen >= (sizeof(struct sctp_data_chunk) + sizeof(uint32_t))) {
4291163953Srrs				/* yep */
4292163953Srrs				struct sctp_data_chunk *dcp;
4293163953Srrs				uint8_t *ddp;
4294163953Srrs				unsigned int iii;
4295163953Srrs
4296163953Srrs				dcp = (struct sctp_data_chunk *)ch;
4297163953Srrs				ddp = (uint8_t *) (dcp + 1);
4298163953Srrs				for (iii = 0; iii < sizeof(desc.data_bytes); iii++) {
4299163953Srrs					desc.data_bytes[iii] = ddp[iii];
4300163953Srrs				}
4301163953Srrs				desc.tsn_ifany = dcp->dp.tsn;
4302163953Srrs			} else {
4303163953Srrs				/* nope we are done. */
4304163953Srrs				SCTP_STAT_INCR(sctps_pdrpnedat);
4305163953Srrs				break;
4306163953Srrs			}
4307163953Srrs		} else {
4308163953Srrs			if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX))
4309163953Srrs				SCTP_STAT_INCR(sctps_pdrpmbct);
4310163953Srrs		}
4311163953Srrs
4312163953Srrs		if (process_chunk_drop(stcb, &desc, net, cp->ch.chunk_flags)) {
4313163953Srrs			SCTP_STAT_INCR(sctps_pdrppdbrk);
4314163953Srrs			break;
4315163953Srrs		}
4316163953Srrs		if (SCTP_SIZE32(at) > chlen) {
4317163953Srrs			break;
4318163953Srrs		}
4319163953Srrs		chlen -= SCTP_SIZE32(at);
4320163953Srrs		if (chlen < sizeof(struct sctp_chunkhdr)) {
4321163953Srrs			/* done, none left */
4322163953Srrs			break;
4323163953Srrs		}
4324163953Srrs		ch = (struct sctp_chunkhdr *)((caddr_t)ch + SCTP_SIZE32(at));
4325163953Srrs	}
4326163953Srrs	/* Now update any rwnd --- possibly */
4327163953Srrs	if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) == 0) {
4328163953Srrs		/* From a peer, we get a rwnd report */
4329163953Srrs		uint32_t a_rwnd;
4330163953Srrs
4331163953Srrs		SCTP_STAT_INCR(sctps_pdrpfehos);
4332163953Srrs
4333163953Srrs		bottle_bw = ntohl(cp->bottle_bw);
4334163953Srrs		on_queue = ntohl(cp->current_onq);
4335163953Srrs		if (bottle_bw && on_queue) {
4336163953Srrs			/* a rwnd report is in here */
4337163953Srrs			if (bottle_bw > on_queue)
4338163953Srrs				a_rwnd = bottle_bw - on_queue;
4339163953Srrs			else
4340163953Srrs				a_rwnd = 0;
4341163953Srrs
4342163953Srrs			if (a_rwnd == 0)
4343163953Srrs				stcb->asoc.peers_rwnd = 0;
4344163953Srrs			else {
4345163953Srrs				if (a_rwnd > stcb->asoc.total_flight) {
4346163953Srrs					stcb->asoc.peers_rwnd =
4347163953Srrs					    a_rwnd - stcb->asoc.total_flight;
4348163953Srrs				} else {
4349163953Srrs					stcb->asoc.peers_rwnd = 0;
4350163953Srrs				}
4351163953Srrs				if (stcb->asoc.peers_rwnd <
4352163953Srrs				    stcb->sctp_ep->sctp_ep.sctp_sws_sender) {
4353163953Srrs					/* SWS sender side engages */
4354163953Srrs					stcb->asoc.peers_rwnd = 0;
4355163953Srrs				}
4356163953Srrs			}
4357163953Srrs		}
4358163953Srrs	} else {
4359163953Srrs		SCTP_STAT_INCR(sctps_pdrpfmbox);
4360163953Srrs	}
4361163953Srrs
4362163953Srrs	/* now middle boxes in sat networks get a cwnd bump */
4363163953Srrs	if ((cp->ch.chunk_flags & SCTP_FROM_MIDDLE_BOX) &&
4364163953Srrs	    (stcb->asoc.sat_t3_loss_recovery == 0) &&
4365163953Srrs	    (stcb->asoc.sat_network)) {
4366163953Srrs		/*
4367163953Srrs		 * This is debateable but for sat networks it makes sense
4368163953Srrs		 * Note if a T3 timer has went off, we will prohibit any
4369163953Srrs		 * changes to cwnd until we exit the t3 loss recovery.
4370163953Srrs		 */
4371171440Srrs		stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped(stcb,
4372171440Srrs		    net, cp, &bottle_bw, &on_queue);
4373163953Srrs	}
4374163953Srrs}
4375163953Srrs
4376163953Srrs/*
4377163953Srrs * handles all control chunks in a packet inputs: - m: mbuf chain, assumed to
4378163953Srrs * still contain IP/SCTP header - stcb: is the tcb found for this packet -
4379163953Srrs * offset: offset into the mbuf chain to first chunkhdr - length: is the
4380163953Srrs * length of the complete packet outputs: - length: modified to remaining
4381163953Srrs * length after control processing - netp: modified to new sctp_nets after
4382163953Srrs * cookie-echo processing - return NULL to discard the packet (ie. no asoc,
4383163953Srrs * bad packet,...) otherwise return the tcb for this packet
4384163953Srrs */
4385170099Srrs#ifdef __GNUC__
4386170099Srrs__attribute__((noinline))
4387170099Srrs#endif
4388170099Srrs	static struct sctp_tcb *
4389170099Srrs	         sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
4390252889Stuexen             struct sockaddr *src, struct sockaddr *dst,
4391170099Srrs             struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp,
4392170099Srrs             struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen,
4393238253Stuexen             uint8_t use_mflowid, uint32_t mflowid,
4394179157Srrs             uint32_t vrf_id, uint16_t port)
4395163953Srrs{
4396163953Srrs	struct sctp_association *asoc;
4397266181Stuexen	struct mbuf *op_err;
4398266181Stuexen	char msg[SCTP_DIAG_INFO_LEN];
4399163953Srrs	uint32_t vtag_in;
4400163953Srrs	int num_chunks = 0;	/* number of control chunks processed */
4401170140Srrs	uint32_t chk_length;
4402163953Srrs	int ret;
4403168299Srrs	int abort_no_unlock = 0;
4404218186Srrs	int ecne_seen = 0;
4405163953Srrs
4406163953Srrs	/*
4407163953Srrs	 * How big should this be, and should it be alloc'd? Lets try the
4408163953Srrs	 * d-mtu-ceiling for now (2k) and that should hopefully work ...
4409163953Srrs	 * until we get into jumbo grams and such..
4410163953Srrs	 */
4411166675Srrs	uint8_t chunk_buf[SCTP_CHUNK_BUFFER_SIZE];
4412163953Srrs	struct sctp_tcb *locked_tcb = stcb;
4413163953Srrs	int got_auth = 0;
4414163953Srrs	uint32_t auth_offset = 0, auth_len = 0;
4415163953Srrs	int auth_skipped = 0;
4416171990Srrs	int asconf_cnt = 0;
4417163953Srrs
4418252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4419172090Srrs	struct socket *so;
4420172090Srrs
4421172090Srrs#endif
4422172090Srrs
4423169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT1, "sctp_process_control: iphlen=%u, offset=%u, length=%u stcb:%p\n",
4424252927Stuexen	    iphlen, *offset, length, (void *)stcb);
4425163953Srrs
4426163953Srrs	/* validate chunk header length... */
4427163953Srrs	if (ntohs(ch->chunk_length) < sizeof(*ch)) {
4428170056Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "Invalid header length %d\n",
4429170056Srrs		    ntohs(ch->chunk_length));
4430170091Srrs		if (locked_tcb) {
4431170091Srrs			SCTP_TCB_UNLOCK(locked_tcb);
4432170091Srrs		}
4433163953Srrs		return (NULL);
4434163953Srrs	}
4435163953Srrs	/*
4436163953Srrs	 * validate the verification tag
4437163953Srrs	 */
4438163953Srrs	vtag_in = ntohl(sh->v_tag);
4439163953Srrs
4440165220Srrs	if (locked_tcb) {
4441165220Srrs		SCTP_TCB_LOCK_ASSERT(locked_tcb);
4442165220Srrs	}
4443163953Srrs	if (ch->chunk_type == SCTP_INITIATION) {
4444170056Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "Its an INIT of len:%d vtag:%x\n",
4445170056Srrs		    ntohs(ch->chunk_length), vtag_in);
4446163953Srrs		if (vtag_in != 0) {
4447163953Srrs			/* protocol error- silently discard... */
4448163953Srrs			SCTP_STAT_INCR(sctps_badvtag);
4449169378Srrs			if (locked_tcb) {
4450163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4451169378Srrs			}
4452163953Srrs			return (NULL);
4453163953Srrs		}
4454163953Srrs	} else if (ch->chunk_type != SCTP_COOKIE_ECHO) {
4455163953Srrs		/*
4456163953Srrs		 * If there is no stcb, skip the AUTH chunk and process
4457163953Srrs		 * later after a stcb is found (to validate the lookup was
4458163953Srrs		 * valid.
4459163953Srrs		 */
4460163953Srrs		if ((ch->chunk_type == SCTP_AUTHENTICATION) &&
4461179783Srrs		    (stcb == NULL) &&
4462179783Srrs		    !SCTP_BASE_SYSCTL(sctp_auth_disable)) {
4463163953Srrs			/* save this chunk for later processing */
4464163953Srrs			auth_skipped = 1;
4465163953Srrs			auth_offset = *offset;
4466163953Srrs			auth_len = ntohs(ch->chunk_length);
4467163953Srrs
4468163953Srrs			/* (temporarily) move past this chunk */
4469163953Srrs			*offset += SCTP_SIZE32(auth_len);
4470163953Srrs			if (*offset >= length) {
4471163953Srrs				/* no more data left in the mbuf chain */
4472163953Srrs				*offset = length;
4473170091Srrs				if (locked_tcb) {
4474170091Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4475170091Srrs				}
4476163953Srrs				return (NULL);
4477163953Srrs			}
4478163953Srrs			ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
4479163953Srrs			    sizeof(struct sctp_chunkhdr), chunk_buf);
4480163953Srrs		}
4481169420Srrs		if (ch == NULL) {
4482169420Srrs			/* Help */
4483169420Srrs			*offset = length;
4484170091Srrs			if (locked_tcb) {
4485170091Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4486170091Srrs			}
4487169420Srrs			return (NULL);
4488169420Srrs		}
4489163953Srrs		if (ch->chunk_type == SCTP_COOKIE_ECHO) {
4490163953Srrs			goto process_control_chunks;
4491163953Srrs		}
4492163953Srrs		/*
4493163953Srrs		 * first check if it's an ASCONF with an unknown src addr we
4494163953Srrs		 * need to look inside to find the association
4495163953Srrs		 */
4496163953Srrs		if (ch->chunk_type == SCTP_ASCONF && stcb == NULL) {
4497171990Srrs			struct sctp_chunkhdr *asconf_ch = ch;
4498171990Srrs			uint32_t asconf_offset = 0, asconf_len = 0;
4499171990Srrs
4500163953Srrs			/* inp's refcount may be reduced */
4501163953Srrs			SCTP_INP_INCR_REF(inp);
4502163953Srrs
4503171990Srrs			asconf_offset = *offset;
4504171990Srrs			do {
4505171990Srrs				asconf_len = ntohs(asconf_ch->chunk_length);
4506171990Srrs				if (asconf_len < sizeof(struct sctp_asconf_paramhdr))
4507171990Srrs					break;
4508231038Stuexen				stcb = sctp_findassociation_ep_asconf(m,
4509252889Stuexen				    *offset,
4510252889Stuexen				    dst,
4511252889Stuexen				    sh, &inp, netp, vrf_id);
4512171990Srrs				if (stcb != NULL)
4513171990Srrs					break;
4514171990Srrs				asconf_offset += SCTP_SIZE32(asconf_len);
4515171990Srrs				asconf_ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, asconf_offset,
4516171990Srrs				    sizeof(struct sctp_chunkhdr), chunk_buf);
4517171990Srrs			} while (asconf_ch != NULL && asconf_ch->chunk_type == SCTP_ASCONF);
4518163953Srrs			if (stcb == NULL) {
4519163953Srrs				/*
4520163953Srrs				 * reduce inp's refcount if not reduced in
4521163953Srrs				 * sctp_findassociation_ep_asconf().
4522163953Srrs				 */
4523163953Srrs				SCTP_INP_DECR_REF(inp);
4524171990Srrs			} else {
4525171990Srrs				locked_tcb = stcb;
4526163953Srrs			}
4527171990Srrs
4528163953Srrs			/* now go back and verify any auth chunk to be sure */
4529163953Srrs			if (auth_skipped && (stcb != NULL)) {
4530163953Srrs				struct sctp_auth_chunk *auth;
4531163953Srrs
4532163953Srrs				auth = (struct sctp_auth_chunk *)
4533163953Srrs				    sctp_m_getptr(m, auth_offset,
4534163953Srrs				    auth_len, chunk_buf);
4535163953Srrs				got_auth = 1;
4536163953Srrs				auth_skipped = 0;
4537169420Srrs				if ((auth == NULL) || sctp_handle_auth(stcb, auth, m,
4538163953Srrs				    auth_offset)) {
4539163953Srrs					/* auth HMAC failed so dump it */
4540163953Srrs					*offset = length;
4541170091Srrs					if (locked_tcb) {
4542170091Srrs						SCTP_TCB_UNLOCK(locked_tcb);
4543170091Srrs					}
4544163953Srrs					return (NULL);
4545163953Srrs				} else {
4546163953Srrs					/* remaining chunks are HMAC checked */
4547163953Srrs					stcb->asoc.authenticated = 1;
4548163953Srrs				}
4549163953Srrs			}
4550163953Srrs		}
4551163953Srrs		if (stcb == NULL) {
4552266181Stuexen			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
4553266181Stuexen			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
4554266181Stuexen			    msg);
4555163953Srrs			/* no association, so it's out of the blue... */
4556266181Stuexen			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
4557238253Stuexen			    use_mflowid, mflowid,
4558179157Srrs			    vrf_id, port);
4559163953Srrs			*offset = length;
4560169378Srrs			if (locked_tcb) {
4561163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4562169378Srrs			}
4563163953Srrs			return (NULL);
4564163953Srrs		}
4565163953Srrs		asoc = &stcb->asoc;
4566163953Srrs		/* ABORT and SHUTDOWN can use either v_tag... */
4567163953Srrs		if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) ||
4568163953Srrs		    (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) ||
4569163953Srrs		    (ch->chunk_type == SCTP_PACKET_DROPPED)) {
4570252977Stuexen			/* Take the T-bit always into account. */
4571252977Stuexen			if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) &&
4572252977Stuexen			    (vtag_in == asoc->my_vtag)) ||
4573252977Stuexen			    (((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) &&
4574163953Srrs			    (vtag_in == asoc->peer_vtag))) {
4575163953Srrs				/* this is valid */
4576163953Srrs			} else {
4577163953Srrs				/* drop this packet... */
4578163953Srrs				SCTP_STAT_INCR(sctps_badvtag);
4579169378Srrs				if (locked_tcb) {
4580163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4581169378Srrs				}
4582163953Srrs				return (NULL);
4583163953Srrs			}
4584163953Srrs		} else if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
4585163953Srrs			if (vtag_in != asoc->my_vtag) {
4586163953Srrs				/*
4587163953Srrs				 * this could be a stale SHUTDOWN-ACK or the
4588163953Srrs				 * peer never got the SHUTDOWN-COMPLETE and
4589163953Srrs				 * is still hung; we have started a new asoc
4590163953Srrs				 * but it won't complete until the shutdown
4591163953Srrs				 * is completed
4592163953Srrs				 */
4593169378Srrs				if (locked_tcb) {
4594163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4595169378Srrs				}
4596266181Stuexen				snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
4597266181Stuexen				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
4598266181Stuexen				    msg);
4599252889Stuexen				sctp_handle_ootb(m, iphlen, *offset, src, dst,
4600266181Stuexen				    sh, inp, op_err,
4601238253Stuexen				    use_mflowid, mflowid,
4602237900Stuexen				    vrf_id, port);
4603163953Srrs				return (NULL);
4604163953Srrs			}
4605163953Srrs		} else {
4606163953Srrs			/* for all other chunks, vtag must match */
4607163953Srrs			if (vtag_in != asoc->my_vtag) {
4608163953Srrs				/* invalid vtag... */
4609169420Srrs				SCTPDBG(SCTP_DEBUG_INPUT3,
4610169420Srrs				    "invalid vtag: %xh, expect %xh\n",
4611169420Srrs				    vtag_in, asoc->my_vtag);
4612163953Srrs				SCTP_STAT_INCR(sctps_badvtag);
4613169378Srrs				if (locked_tcb) {
4614163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4615169378Srrs				}
4616163953Srrs				*offset = length;
4617163953Srrs				return (NULL);
4618163953Srrs			}
4619163953Srrs		}
4620163953Srrs	}			/* end if !SCTP_COOKIE_ECHO */
4621163953Srrs	/*
4622163953Srrs	 * process all control chunks...
4623163953Srrs	 */
4624163953Srrs	if (((ch->chunk_type == SCTP_SELECTIVE_ACK) ||
4625185694Srrs	    (ch->chunk_type == SCTP_NR_SELECTIVE_ACK) ||
4626163953Srrs	    (ch->chunk_type == SCTP_HEARTBEAT_REQUEST)) &&
4627163953Srrs	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
4628163953Srrs		/* implied cookie-ack.. we must have lost the ack */
4629179783Srrs		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
4630171943Srrs			sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
4631171943Srrs			    stcb->asoc.overall_error_count,
4632171943Srrs			    0,
4633171943Srrs			    SCTP_FROM_SCTP_INPUT,
4634171943Srrs			    __LINE__);
4635171943Srrs		}
4636163953Srrs		stcb->asoc.overall_error_count = 0;
4637163953Srrs		sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb,
4638163953Srrs		    *netp);
4639163953Srrs	}
4640163953Srrsprocess_control_chunks:
4641163953Srrs	while (IS_SCTP_CONTROL(ch)) {
4642163953Srrs		/* validate chunk length */
4643163953Srrs		chk_length = ntohs(ch->chunk_length);
4644169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_process_control: processing a chunk type=%u, len=%u\n",
4645169420Srrs		    ch->chunk_type, chk_length);
4646170744Srrs		SCTP_LTRACE_CHK(inp, stcb, ch->chunk_type, chk_length);
4647170140Srrs		if (chk_length < sizeof(*ch) ||
4648170140Srrs		    (*offset + (int)chk_length) > length) {
4649163953Srrs			*offset = length;
4650169378Srrs			if (locked_tcb) {
4651163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4652169378Srrs			}
4653163953Srrs			return (NULL);
4654163953Srrs		}
4655163953Srrs		SCTP_STAT_INCR_COUNTER64(sctps_incontrolchunks);
4656163953Srrs		/*
4657163953Srrs		 * INIT-ACK only gets the init ack "header" portion only
4658163953Srrs		 * because we don't have to process the peer's COOKIE. All
4659163953Srrs		 * others get a complete chunk.
4660163953Srrs		 */
4661169208Srrs		if ((ch->chunk_type == SCTP_INITIATION_ACK) ||
4662169208Srrs		    (ch->chunk_type == SCTP_INITIATION)) {
4663163953Srrs			/* get an init-ack chunk */
4664163953Srrs			ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
4665163953Srrs			    sizeof(struct sctp_init_ack_chunk), chunk_buf);
4666163953Srrs			if (ch == NULL) {
4667163953Srrs				*offset = length;
4668169378Srrs				if (locked_tcb) {
4669163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4670169378Srrs				}
4671163953Srrs				return (NULL);
4672163953Srrs			}
4673170642Srrs		} else {
4674170786Srrs			/* For cookies and all other chunks. */
4675169208Srrs			if (chk_length > sizeof(chunk_buf)) {
4676169208Srrs				/*
4677169208Srrs				 * use just the size of the chunk buffer so
4678170642Srrs				 * the front part of our chunks fit in
4679170642Srrs				 * contiguous space up to the chunk buffer
4680170642Srrs				 * size (508 bytes). For chunks that need to
4681170786Srrs				 * get more than that they must use the
4682170642Srrs				 * sctp_m_getptr() function or other means
4683170786Srrs				 * (e.g. know how to parse mbuf chains).
4684170786Srrs				 * Cookies do this already.
4685169208Srrs				 */
4686169208Srrs				ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
4687169208Srrs				    (sizeof(chunk_buf) - 4),
4688169208Srrs				    chunk_buf);
4689169208Srrs				if (ch == NULL) {
4690169208Srrs					*offset = length;
4691169378Srrs					if (locked_tcb) {
4692169208Srrs						SCTP_TCB_UNLOCK(locked_tcb);
4693169378Srrs					}
4694169208Srrs					return (NULL);
4695169208Srrs				}
4696169208Srrs			} else {
4697169208Srrs				/* We can fit it all */
4698170642Srrs				ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
4699170642Srrs				    chk_length, chunk_buf);
4700170642Srrs				if (ch == NULL) {
4701170642Srrs					SCTP_PRINTF("sctp_process_control: Can't get the all data....\n");
4702170642Srrs					*offset = length;
4703170642Srrs					if (locked_tcb) {
4704170642Srrs						SCTP_TCB_UNLOCK(locked_tcb);
4705169208Srrs					}
4706170642Srrs					return (NULL);
4707163953Srrs				}
4708163953Srrs			}
4709163953Srrs		}
4710163953Srrs		num_chunks++;
4711163953Srrs		/* Save off the last place we got a control from */
4712163953Srrs		if (stcb != NULL) {
4713169420Srrs			if (((netp != NULL) && (*netp != NULL)) || (ch->chunk_type == SCTP_ASCONF)) {
4714163953Srrs				/*
4715163953Srrs				 * allow last_control to be NULL if
4716163953Srrs				 * ASCONF... ASCONF processing will find the
4717163953Srrs				 * right net later
4718163953Srrs				 */
4719169420Srrs				if ((netp != NULL) && (*netp != NULL))
4720169420Srrs					stcb->asoc.last_control_chunk_from = *netp;
4721163953Srrs			}
4722163953Srrs		}
4723163953Srrs#ifdef SCTP_AUDITING_ENABLED
4724163953Srrs		sctp_audit_log(0xB0, ch->chunk_type);
4725163953Srrs#endif
4726163953Srrs
4727163953Srrs		/* check to see if this chunk required auth, but isn't */
4728179783Srrs		if ((stcb != NULL) &&
4729179783Srrs		    !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
4730179783Srrs		    sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) &&
4731163953Srrs		    !stcb->asoc.authenticated) {
4732163953Srrs			/* "silently" ignore */
4733163953Srrs			SCTP_STAT_INCR(sctps_recvauthmissing);
4734163953Srrs			goto next_chunk;
4735163953Srrs		}
4736163953Srrs		switch (ch->chunk_type) {
4737163953Srrs		case SCTP_INITIATION:
4738169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT\n");
4739231041Stuexen			/* The INIT chunk must be the only chunk. */
4740231041Stuexen			if ((num_chunks > 1) ||
4741231043Stuexen			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
4742266181Stuexen				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
4743266181Stuexen				    "INIT not the only chunk");
4744252889Stuexen				sctp_abort_association(inp, stcb, m, iphlen,
4745266181Stuexen				    src, dst, sh, op_err,
4746238253Stuexen				    use_mflowid, mflowid,
4747238253Stuexen				    vrf_id, port);
4748163953Srrs				*offset = length;
4749163953Srrs				return (NULL);
4750163953Srrs			}
4751231041Stuexen			/* Honor our resource limit. */
4752231041Stuexen			if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
4753266181Stuexen				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
4754252889Stuexen				sctp_abort_association(inp, stcb, m, iphlen,
4755252889Stuexen				    src, dst, sh, op_err,
4756238253Stuexen				    use_mflowid, mflowid,
4757238253Stuexen				    vrf_id, port);
4758163953Srrs				*offset = length;
4759163953Srrs				return (NULL);
4760163953Srrs			}
4761252889Stuexen			sctp_handle_init(m, iphlen, *offset, src, dst, sh,
4762231041Stuexen			    (struct sctp_init_chunk *)ch, inp,
4763238253Stuexen			    stcb, &abort_no_unlock,
4764238253Stuexen			    use_mflowid, mflowid,
4765238253Stuexen			    vrf_id, port);
4766163953Srrs			*offset = length;
4767231041Stuexen			if ((!abort_no_unlock) && (locked_tcb)) {
4768163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4769169378Srrs			}
4770163953Srrs			return (NULL);
4771163953Srrs			break;
4772170642Srrs		case SCTP_PAD_CHUNK:
4773170642Srrs			break;
4774163953Srrs		case SCTP_INITIATION_ACK:
4775169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n");
4776163953Srrs			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
4777163953Srrs				/* We are not interested anymore */
4778163953Srrs				if ((stcb) && (stcb->asoc.total_output_queue_size)) {
4779163953Srrs					;
4780163953Srrs				} else {
4781208876Srrs					if (locked_tcb != stcb) {
4782208876Srrs						/* Very unlikely */
4783163953Srrs						SCTP_TCB_UNLOCK(locked_tcb);
4784169378Srrs					}
4785163953Srrs					*offset = length;
4786163953Srrs					if (stcb) {
4787252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4788172090Srrs						so = SCTP_INP_SO(inp);
4789172090Srrs						atomic_add_int(&stcb->asoc.refcnt, 1);
4790172090Srrs						SCTP_TCB_UNLOCK(stcb);
4791172090Srrs						SCTP_SOCKET_LOCK(so, 1);
4792172090Srrs						SCTP_TCB_LOCK(stcb);
4793172090Srrs						atomic_subtract_int(&stcb->asoc.refcnt, 1);
4794172090Srrs#endif
4795171943Srrs						(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_27);
4796252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4797172090Srrs						SCTP_SOCKET_UNLOCK(so, 1);
4798172090Srrs#endif
4799163953Srrs					}
4800163953Srrs					return (NULL);
4801163953Srrs				}
4802163953Srrs			}
4803231043Stuexen			/* The INIT-ACK chunk must be the only chunk. */
4804163953Srrs			if ((num_chunks > 1) ||
4805231043Stuexen			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
4806163953Srrs				*offset = length;
4807169378Srrs				if (locked_tcb) {
4808163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
4809169378Srrs				}
4810163953Srrs				return (NULL);
4811163953Srrs			}
4812169420Srrs			if ((netp) && (*netp)) {
4813252889Stuexen				ret = sctp_handle_init_ack(m, iphlen, *offset,
4814252889Stuexen				    src, dst, sh,
4815238253Stuexen				    (struct sctp_init_ack_chunk *)ch,
4816238253Stuexen				    stcb, *netp,
4817238253Stuexen				    &abort_no_unlock,
4818238253Stuexen				    use_mflowid, mflowid,
4819238253Stuexen				    vrf_id);
4820169420Srrs			} else {
4821169420Srrs				ret = -1;
4822169420Srrs			}
4823231041Stuexen			*offset = length;
4824231041Stuexen			if (abort_no_unlock) {
4825231041Stuexen				return (NULL);
4826231041Stuexen			}
4827163953Srrs			/*
4828163953Srrs			 * Special case, I must call the output routine to
4829163953Srrs			 * get the cookie echoed
4830163953Srrs			 */
4831231041Stuexen			if ((stcb != NULL) && (ret == 0)) {
4832172090Srrs				sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
4833231041Stuexen			}
4834169378Srrs			if (locked_tcb) {
4835163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
4836169378Srrs			}
4837163953Srrs			return (NULL);
4838163953Srrs			break;
4839163953Srrs		case SCTP_SELECTIVE_ACK:
4840163953Srrs			{
4841163953Srrs				struct sctp_sack_chunk *sack;
4842163953Srrs				int abort_now = 0;
4843163953Srrs				uint32_t a_rwnd, cum_ack;
4844202526Stuexen				uint16_t num_seg, num_dup;
4845202526Stuexen				uint8_t flags;
4846202526Stuexen				int offset_seg, offset_dup;
4847163953Srrs
4848211944Stuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
4849211944Stuexen				SCTP_STAT_INCR(sctps_recvsacks);
4850202526Stuexen				if (stcb == NULL) {
4851202526Stuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
4852202526Stuexen					break;
4853169208Srrs				}
4854202526Stuexen				if (chk_length < sizeof(struct sctp_sack_chunk)) {
4855202526Stuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on SACK chunk, too small\n");
4856202526Stuexen					break;
4857202526Stuexen				}
4858171990Srrs				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
4859171990Srrs					/*-
4860171990Srrs					 * If we have sent a shutdown-ack, we will pay no
4861171990Srrs					 * attention to a sack sent in to us since
4862171990Srrs					 * we don't care anymore.
4863171990Srrs					 */
4864184883Srrs					break;
4865171990Srrs				}
4866163953Srrs				sack = (struct sctp_sack_chunk *)ch;
4867202526Stuexen				flags = ch->chunk_flags;
4868163953Srrs				cum_ack = ntohl(sack->sack.cum_tsn_ack);
4869163953Srrs				num_seg = ntohs(sack->sack.num_gap_ack_blks);
4870202526Stuexen				num_dup = ntohs(sack->sack.num_dup_tsns);
4871163953Srrs				a_rwnd = (uint32_t) ntohl(sack->sack.a_rwnd);
4872202526Stuexen				if (sizeof(struct sctp_sack_chunk) +
4873202526Stuexen				    num_seg * sizeof(struct sctp_gap_ack_block) +
4874202526Stuexen				    num_dup * sizeof(uint32_t) != chk_length) {
4875202526Stuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of SACK chunk\n");
4876202526Stuexen					break;
4877202526Stuexen				}
4878202526Stuexen				offset_seg = *offset + sizeof(struct sctp_sack_chunk);
4879202526Stuexen				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
4880170606Srrs				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
4881202526Stuexen				    cum_ack, num_seg, a_rwnd);
4882163953Srrs				stcb->asoc.seen_a_sack_this_pkt = 1;
4883163953Srrs				if ((stcb->asoc.pr_sctp_cnt == 0) &&
4884163953Srrs				    (num_seg == 0) &&
4885216825Stuexen				    SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
4886163953Srrs				    (stcb->asoc.saw_sack_with_frags == 0) &&
4887216188Stuexen				    (stcb->asoc.saw_sack_with_nr_frags == 0) &&
4888163953Srrs				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))
4889163953Srrs				    ) {
4890163953Srrs					/*
4891163953Srrs					 * We have a SIMPLE sack having no
4892163953Srrs					 * prior segments and data on sent
4893163953Srrs					 * queue to be acked.. Use the
4894163953Srrs					 * faster path sack processing. We
4895163953Srrs					 * also allow window update sacks
4896163953Srrs					 * with no missing segments to go
4897163953Srrs					 * this way too.
4898163953Srrs					 */
4899218186Srrs					sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now, ecne_seen);
4900163953Srrs				} else {
4901169420Srrs					if (netp && *netp)
4902231038Stuexen						sctp_handle_sack(m, offset_seg, offset_dup, stcb,
4903202526Stuexen						    num_seg, 0, num_dup, &abort_now, flags,
4904218186Srrs						    cum_ack, a_rwnd, ecne_seen);
4905163953Srrs				}
4906202526Stuexen				if (abort_now) {
4907202526Stuexen					/* ABORT signal from sack processing */
4908202526Stuexen					*offset = length;
4909202526Stuexen					return (NULL);
4910202526Stuexen				}
4911185694Srrs				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
4912185694Srrs				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
4913185694Srrs				    (stcb->asoc.stream_queue_cnt == 0)) {
4914185694Srrs					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
4915185694Srrs				}
4916163953Srrs			}
4917163953Srrs			break;
4918185694Srrs			/*
4919185694Srrs			 * EY - nr_sack:  If the received chunk is an
4920185694Srrs			 * nr_sack chunk
4921185694Srrs			 */
4922185694Srrs		case SCTP_NR_SELECTIVE_ACK:
4923185694Srrs			{
4924185694Srrs				struct sctp_nr_sack_chunk *nr_sack;
4925185694Srrs				int abort_now = 0;
4926185694Srrs				uint32_t a_rwnd, cum_ack;
4927202526Stuexen				uint16_t num_seg, num_nr_seg, num_dup;
4928202526Stuexen				uint8_t flags;
4929202526Stuexen				int offset_seg, offset_dup;
4930185694Srrs
4931211944Stuexen				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
4932211944Stuexen				SCTP_STAT_INCR(sctps_recvsacks);
4933212225Srrs				if (stcb == NULL) {
4934212225Srrs					SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
4935212225Srrs					break;
4936212225Srrs				}
4937211944Stuexen				if ((stcb->asoc.sctp_nr_sack_on_off == 0) ||
4938211944Stuexen				    (stcb->asoc.peer_supports_nr_sack == 0)) {
4939185694Srrs					goto unknown_chunk;
4940185694Srrs				}
4941202526Stuexen				if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
4942202526Stuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size on NR-SACK chunk, too small\n");
4943202526Stuexen					break;
4944202526Stuexen				}
4945185694Srrs				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
4946185694Srrs					/*-
4947185694Srrs					 * If we have sent a shutdown-ack, we will pay no
4948185694Srrs					 * attention to a sack sent in to us since
4949185694Srrs					 * we don't care anymore.
4950185694Srrs					 */
4951202526Stuexen					break;
4952185694Srrs				}
4953185694Srrs				nr_sack = (struct sctp_nr_sack_chunk *)ch;
4954202526Stuexen				flags = ch->chunk_flags;
4955185694Srrs				cum_ack = ntohl(nr_sack->nr_sack.cum_tsn_ack);
4956185694Srrs				num_seg = ntohs(nr_sack->nr_sack.num_gap_ack_blks);
4957185694Srrs				num_nr_seg = ntohs(nr_sack->nr_sack.num_nr_gap_ack_blks);
4958202526Stuexen				num_dup = ntohs(nr_sack->nr_sack.num_dup_tsns);
4959185694Srrs				a_rwnd = (uint32_t) ntohl(nr_sack->nr_sack.a_rwnd);
4960202526Stuexen				if (sizeof(struct sctp_nr_sack_chunk) +
4961202526Stuexen				    (num_seg + num_nr_seg) * sizeof(struct sctp_gap_ack_block) +
4962202526Stuexen				    num_dup * sizeof(uint32_t) != chk_length) {
4963202526Stuexen					SCTPDBG(SCTP_DEBUG_INDATA1, "Bad size of NR_SACK chunk\n");
4964202526Stuexen					break;
4965202526Stuexen				}
4966202526Stuexen				offset_seg = *offset + sizeof(struct sctp_nr_sack_chunk);
4967202526Stuexen				offset_dup = offset_seg + num_seg * sizeof(struct sctp_gap_ack_block);
4968185694Srrs				SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK process cum_ack:%x num_seg:%d a_rwnd:%d\n",
4969202526Stuexen				    cum_ack, num_seg, a_rwnd);
4970185694Srrs				stcb->asoc.seen_a_sack_this_pkt = 1;
4971185694Srrs				if ((stcb->asoc.pr_sctp_cnt == 0) &&
4972202526Stuexen				    (num_seg == 0) && (num_nr_seg == 0) &&
4973216825Stuexen				    SCTP_TSN_GE(cum_ack, stcb->asoc.last_acked_seq) &&
4974185694Srrs				    (stcb->asoc.saw_sack_with_frags == 0) &&
4975216188Stuexen				    (stcb->asoc.saw_sack_with_nr_frags == 0) &&
4976202526Stuexen				    (!TAILQ_EMPTY(&stcb->asoc.sent_queue))) {
4977185694Srrs					/*
4978185694Srrs					 * We have a SIMPLE sack having no
4979185694Srrs					 * prior segments and data on sent
4980202526Stuexen					 * queue to be acked. Use the faster
4981202526Stuexen					 * path sack processing. We also
4982202526Stuexen					 * allow window update sacks with no
4983202526Stuexen					 * missing segments to go this way
4984202526Stuexen					 * too.
4985185694Srrs					 */
4986218129Srrs					sctp_express_handle_sack(stcb, cum_ack, a_rwnd,
4987218186Srrs					    &abort_now, ecne_seen);
4988185694Srrs				} else {
4989185694Srrs					if (netp && *netp)
4990231038Stuexen						sctp_handle_sack(m, offset_seg, offset_dup, stcb,
4991202526Stuexen						    num_seg, num_nr_seg, num_dup, &abort_now, flags,
4992218186Srrs						    cum_ack, a_rwnd, ecne_seen);
4993185694Srrs				}
4994202526Stuexen				if (abort_now) {
4995202526Stuexen					/* ABORT signal from sack processing */
4996202526Stuexen					*offset = length;
4997202526Stuexen					return (NULL);
4998202526Stuexen				}
4999185694Srrs				if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
5000185694Srrs				    TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
5001185694Srrs				    (stcb->asoc.stream_queue_cnt == 0)) {
5002185694Srrs					sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
5003185694Srrs				}
5004185694Srrs			}
5005185694Srrs			break;
5006185694Srrs
5007163953Srrs		case SCTP_HEARTBEAT_REQUEST:
5008169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT\n");
5009169420Srrs			if ((stcb) && netp && *netp) {
5010169420Srrs				SCTP_STAT_INCR(sctps_recvheartbeat);
5011169420Srrs				sctp_send_heartbeat_ack(stcb, m, *offset,
5012169420Srrs				    chk_length, *netp);
5013169420Srrs
5014169420Srrs				/* He's alive so give him credit */
5015179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5016171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5017171943Srrs					    stcb->asoc.overall_error_count,
5018171943Srrs					    0,
5019171943Srrs					    SCTP_FROM_SCTP_INPUT,
5020171943Srrs					    __LINE__);
5021171943Srrs				}
5022169420Srrs				stcb->asoc.overall_error_count = 0;
5023163953Srrs			}
5024163953Srrs			break;
5025163953Srrs		case SCTP_HEARTBEAT_ACK:
5026169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_HEARTBEAT-ACK\n");
5027169420Srrs			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_heartbeat_chunk))) {
5028169208Srrs				/* Its not ours */
5029169352Srrs				*offset = length;
5030169378Srrs				if (locked_tcb) {
5031169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5032169378Srrs				}
5033169208Srrs				return (NULL);
5034169208Srrs			}
5035163953Srrs			/* He's alive so give him credit */
5036179783Srrs			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5037171943Srrs				sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5038171943Srrs				    stcb->asoc.overall_error_count,
5039171943Srrs				    0,
5040171943Srrs				    SCTP_FROM_SCTP_INPUT,
5041171943Srrs				    __LINE__);
5042171943Srrs			}
5043163953Srrs			stcb->asoc.overall_error_count = 0;
5044163953Srrs			SCTP_STAT_INCR(sctps_recvheartbeatack);
5045169420Srrs			if (netp && *netp)
5046169420Srrs				sctp_handle_heartbeat_ack((struct sctp_heartbeat_chunk *)ch,
5047169420Srrs				    stcb, *netp);
5048163953Srrs			break;
5049163953Srrs		case SCTP_ABORT_ASSOCIATION:
5050170091Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n",
5051252927Stuexen			    (void *)stcb);
5052169420Srrs			if ((stcb) && netp && *netp)
5053169420Srrs				sctp_handle_abort((struct sctp_abort_chunk *)ch,
5054169420Srrs				    stcb, *netp);
5055163953Srrs			*offset = length;
5056163953Srrs			return (NULL);
5057163953Srrs			break;
5058163953Srrs		case SCTP_SHUTDOWN:
5059170091Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN, stcb %p\n",
5060252927Stuexen			    (void *)stcb);
5061169420Srrs			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_shutdown_chunk))) {
5062169208Srrs				*offset = length;
5063169378Srrs				if (locked_tcb) {
5064169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5065169378Srrs				}
5066169208Srrs				return (NULL);
5067169420Srrs			}
5068169420Srrs			if (netp && *netp) {
5069163953Srrs				int abort_flag = 0;
5070163953Srrs
5071163953Srrs				sctp_handle_shutdown((struct sctp_shutdown_chunk *)ch,
5072163953Srrs				    stcb, *netp, &abort_flag);
5073163953Srrs				if (abort_flag) {
5074163953Srrs					*offset = length;
5075163953Srrs					return (NULL);
5076163953Srrs				}
5077163953Srrs			}
5078163953Srrs			break;
5079163953Srrs		case SCTP_SHUTDOWN_ACK:
5080252927Stuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK, stcb %p\n", (void *)stcb);
5081169420Srrs			if ((stcb) && (netp) && (*netp))
5082169420Srrs				sctp_handle_shutdown_ack((struct sctp_shutdown_ack_chunk *)ch, stcb, *netp);
5083163953Srrs			*offset = length;
5084163953Srrs			return (NULL);
5085163953Srrs			break;
5086169420Srrs
5087163953Srrs		case SCTP_OPERATION_ERROR:
5088169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_OP-ERR\n");
5089169420Srrs			if ((stcb) && netp && *netp && sctp_handle_error(ch, stcb, *netp) < 0) {
5090163953Srrs				*offset = length;
5091163953Srrs				return (NULL);
5092163953Srrs			}
5093163953Srrs			break;
5094163953Srrs		case SCTP_COOKIE_ECHO:
5095169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3,
5096252927Stuexen			    "SCTP_COOKIE-ECHO, stcb %p\n", (void *)stcb);
5097163953Srrs			if ((stcb) && (stcb->asoc.total_output_queue_size)) {
5098163953Srrs				;
5099163953Srrs			} else {
5100169420Srrs				if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5101163953Srrs					/* We are not interested anymore */
5102208878Srrs			abend:
5103208853Srrs					if (stcb) {
5104208853Srrs						SCTP_TCB_UNLOCK(stcb);
5105208853Srrs					}
5106163953Srrs					*offset = length;
5107163953Srrs					return (NULL);
5108163953Srrs				}
5109163953Srrs			}
5110163953Srrs			/*
5111163953Srrs			 * First are we accepting? We do this again here
5112207924Srrs			 * since it is possible that a previous endpoint WAS
5113207924Srrs			 * listening responded to a INIT-ACK and then
5114163953Srrs			 * closed. We opened and bound.. and are now no
5115163953Srrs			 * longer listening.
5116163953Srrs			 */
5117172703Srrs
5118172703Srrs			if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
5119172703Srrs				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
5120179783Srrs				    (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
5121266181Stuexen					op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
5122252889Stuexen					sctp_abort_association(inp, stcb, m, iphlen,
5123252889Stuexen					    src, dst, sh, op_err,
5124238253Stuexen					    use_mflowid, mflowid,
5125238253Stuexen					    vrf_id, port);
5126163953Srrs				}
5127172703Srrs				*offset = length;
5128172703Srrs				return (NULL);
5129172703Srrs			} else {
5130163953Srrs				struct mbuf *ret_buf;
5131165220Srrs				struct sctp_inpcb *linp;
5132163953Srrs
5133169420Srrs				if (stcb) {
5134165220Srrs					linp = NULL;
5135169420Srrs				} else {
5136165220Srrs					linp = inp;
5137169420Srrs				}
5138165220Srrs
5139169420Srrs				if (linp) {
5140165220Srrs					SCTP_ASOC_CREATE_LOCK(linp);
5141208878Srrs					if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
5142208878Srrs					    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
5143208878Srrs						SCTP_ASOC_CREATE_UNLOCK(linp);
5144208878Srrs						goto abend;
5145208878Srrs					}
5146169420Srrs				}
5147169420Srrs				if (netp) {
5148169420Srrs					ret_buf =
5149169420Srrs					    sctp_handle_cookie_echo(m, iphlen,
5150252889Stuexen					    *offset,
5151252889Stuexen					    src, dst,
5152252889Stuexen					    sh,
5153169420Srrs					    (struct sctp_cookie_echo_chunk *)ch,
5154169420Srrs					    &inp, &stcb, netp,
5155169420Srrs					    auth_skipped,
5156169420Srrs					    auth_offset,
5157169420Srrs					    auth_len,
5158169420Srrs					    &locked_tcb,
5159238253Stuexen					    use_mflowid,
5160238253Stuexen					    mflowid,
5161179157Srrs					    vrf_id,
5162179157Srrs					    port);
5163169420Srrs				} else {
5164169420Srrs					ret_buf = NULL;
5165169420Srrs				}
5166169420Srrs				if (linp) {
5167165220Srrs					SCTP_ASOC_CREATE_UNLOCK(linp);
5168169420Srrs				}
5169163953Srrs				if (ret_buf == NULL) {
5170163953Srrs					if (locked_tcb) {
5171163953Srrs						SCTP_TCB_UNLOCK(locked_tcb);
5172163953Srrs					}
5173169420Srrs					SCTPDBG(SCTP_DEBUG_INPUT3,
5174169420Srrs					    "GAK, null buffer\n");
5175163953Srrs					*offset = length;
5176163953Srrs					return (NULL);
5177163953Srrs				}
5178163953Srrs				/* if AUTH skipped, see if it verified... */
5179163953Srrs				if (auth_skipped) {
5180163953Srrs					got_auth = 1;
5181163953Srrs					auth_skipped = 0;
5182163953Srrs				}
5183163953Srrs				if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
5184163953Srrs					/*
5185163953Srrs					 * Restart the timer if we have
5186163953Srrs					 * pending data
5187163953Srrs					 */
5188163953Srrs					struct sctp_tmit_chunk *chk;
5189163953Srrs
5190163953Srrs					chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
5191216822Stuexen					sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
5192163953Srrs				}
5193163953Srrs			}
5194163953Srrs			break;
5195163953Srrs		case SCTP_COOKIE_ACK:
5196252927Stuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", (void *)stcb);
5197169420Srrs			if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) {
5198169378Srrs				if (locked_tcb) {
5199169352Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5200169378Srrs				}
5201169352Srrs				return (NULL);
5202169352Srrs			}
5203163953Srrs			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5204163953Srrs				/* We are not interested anymore */
5205163953Srrs				if ((stcb) && (stcb->asoc.total_output_queue_size)) {
5206163953Srrs					;
5207169420Srrs				} else if (stcb) {
5208252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5209172090Srrs					so = SCTP_INP_SO(inp);
5210172090Srrs					atomic_add_int(&stcb->asoc.refcnt, 1);
5211172090Srrs					SCTP_TCB_UNLOCK(stcb);
5212172090Srrs					SCTP_SOCKET_LOCK(so, 1);
5213172090Srrs					SCTP_TCB_LOCK(stcb);
5214172090Srrs					atomic_subtract_int(&stcb->asoc.refcnt, 1);
5215172090Srrs#endif
5216171943Srrs					(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_27);
5217252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5218172090Srrs					SCTP_SOCKET_UNLOCK(so, 1);
5219172090Srrs#endif
5220163953Srrs					*offset = length;
5221163953Srrs					return (NULL);
5222163953Srrs				}
5223163953Srrs			}
5224163953Srrs			/* He's alive so give him credit */
5225169420Srrs			if ((stcb) && netp && *netp) {
5226179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5227171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5228171943Srrs					    stcb->asoc.overall_error_count,
5229171943Srrs					    0,
5230171943Srrs					    SCTP_FROM_SCTP_INPUT,
5231171943Srrs					    __LINE__);
5232171943Srrs				}
5233169378Srrs				stcb->asoc.overall_error_count = 0;
5234169378Srrs				sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, *netp);
5235169378Srrs			}
5236163953Srrs			break;
5237163953Srrs		case SCTP_ECN_ECHO:
5238169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-ECHO\n");
5239163953Srrs			/* He's alive so give him credit */
5240169420Srrs			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_ecne_chunk))) {
5241169208Srrs				/* Its not ours */
5242169378Srrs				if (locked_tcb) {
5243169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5244169378Srrs				}
5245169208Srrs				*offset = length;
5246169208Srrs				return (NULL);
5247169208Srrs			}
5248169378Srrs			if (stcb) {
5249179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5250171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5251171943Srrs					    stcb->asoc.overall_error_count,
5252171943Srrs					    0,
5253171943Srrs					    SCTP_FROM_SCTP_INPUT,
5254171943Srrs					    __LINE__);
5255171943Srrs				}
5256169378Srrs				stcb->asoc.overall_error_count = 0;
5257169378Srrs				sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch,
5258169378Srrs				    stcb);
5259218186Srrs				ecne_seen = 1;
5260169378Srrs			}
5261163953Srrs			break;
5262163953Srrs		case SCTP_ECN_CWR:
5263169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ECN-CWR\n");
5264163953Srrs			/* He's alive so give him credit */
5265169420Srrs			if ((stcb == NULL) || (chk_length != sizeof(struct sctp_cwr_chunk))) {
5266169208Srrs				/* Its not ours */
5267169378Srrs				if (locked_tcb) {
5268169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5269169378Srrs				}
5270169208Srrs				*offset = length;
5271169208Srrs				return (NULL);
5272169208Srrs			}
5273169378Srrs			if (stcb) {
5274179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5275171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5276171943Srrs					    stcb->asoc.overall_error_count,
5277171943Srrs					    0,
5278171943Srrs					    SCTP_FROM_SCTP_INPUT,
5279171943Srrs					    __LINE__);
5280171943Srrs				}
5281169378Srrs				stcb->asoc.overall_error_count = 0;
5282218072Srrs				sctp_handle_ecn_cwr((struct sctp_cwr_chunk *)ch, stcb, *netp);
5283169378Srrs			}
5284163953Srrs			break;
5285163953Srrs		case SCTP_SHUTDOWN_COMPLETE:
5286252927Stuexen			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE, stcb %p\n", (void *)stcb);
5287163953Srrs			/* must be first and only chunk */
5288163953Srrs			if ((num_chunks > 1) ||
5289170140Srrs			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
5290163953Srrs				*offset = length;
5291169378Srrs				if (locked_tcb) {
5292163953Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5293169378Srrs				}
5294163953Srrs				return (NULL);
5295163953Srrs			}
5296169420Srrs			if ((stcb) && netp && *netp) {
5297169378Srrs				sctp_handle_shutdown_complete((struct sctp_shutdown_complete_chunk *)ch,
5298169378Srrs				    stcb, *netp);
5299169378Srrs			}
5300163953Srrs			*offset = length;
5301163953Srrs			return (NULL);
5302163953Srrs			break;
5303163953Srrs		case SCTP_ASCONF:
5304169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF\n");
5305163953Srrs			/* He's alive so give him credit */
5306169378Srrs			if (stcb) {
5307179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5308171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5309171943Srrs					    stcb->asoc.overall_error_count,
5310171943Srrs					    0,
5311171943Srrs					    SCTP_FROM_SCTP_INPUT,
5312171943Srrs					    __LINE__);
5313171943Srrs				}
5314169378Srrs				stcb->asoc.overall_error_count = 0;
5315252889Stuexen				sctp_handle_asconf(m, *offset, src,
5316171990Srrs				    (struct sctp_asconf_chunk *)ch, stcb, asconf_cnt == 0);
5317171990Srrs				asconf_cnt++;
5318169378Srrs			}
5319163953Srrs			break;
5320163953Srrs		case SCTP_ASCONF_ACK:
5321169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF-ACK\n");
5322169208Srrs			if (chk_length < sizeof(struct sctp_asconf_ack_chunk)) {
5323169208Srrs				/* Its not ours */
5324169378Srrs				if (locked_tcb) {
5325169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5326169378Srrs				}
5327169208Srrs				*offset = length;
5328169208Srrs				return (NULL);
5329169208Srrs			}
5330169420Srrs			if ((stcb) && netp && *netp) {
5331169378Srrs				/* He's alive so give him credit */
5332179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5333171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5334171943Srrs					    stcb->asoc.overall_error_count,
5335171943Srrs					    0,
5336171943Srrs					    SCTP_FROM_SCTP_INPUT,
5337171943Srrs					    __LINE__);
5338171943Srrs				}
5339169378Srrs				stcb->asoc.overall_error_count = 0;
5340169378Srrs				sctp_handle_asconf_ack(m, *offset,
5341172190Srrs				    (struct sctp_asconf_ack_chunk *)ch, stcb, *netp, &abort_no_unlock);
5342172190Srrs				if (abort_no_unlock)
5343172190Srrs					return (NULL);
5344169378Srrs			}
5345163953Srrs			break;
5346163953Srrs		case SCTP_FORWARD_CUM_TSN:
5347169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_FWD-TSN\n");
5348169208Srrs			if (chk_length < sizeof(struct sctp_forward_tsn_chunk)) {
5349169208Srrs				/* Its not ours */
5350169378Srrs				if (locked_tcb) {
5351169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5352169378Srrs				}
5353169208Srrs				*offset = length;
5354169208Srrs				return (NULL);
5355169208Srrs			}
5356163953Srrs			/* He's alive so give him credit */
5357169378Srrs			if (stcb) {
5358163953Srrs				int abort_flag = 0;
5359163953Srrs
5360163953Srrs				stcb->asoc.overall_error_count = 0;
5361179783Srrs				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5362171943Srrs					sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5363171943Srrs					    stcb->asoc.overall_error_count,
5364171943Srrs					    0,
5365171943Srrs					    SCTP_FROM_SCTP_INPUT,
5366171943Srrs					    __LINE__);
5367171943Srrs				}
5368163953Srrs				*fwd_tsn_seen = 1;
5369163953Srrs				if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5370163953Srrs					/* We are not interested anymore */
5371252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5372172090Srrs					so = SCTP_INP_SO(inp);
5373172090Srrs					atomic_add_int(&stcb->asoc.refcnt, 1);
5374172090Srrs					SCTP_TCB_UNLOCK(stcb);
5375172090Srrs					SCTP_SOCKET_LOCK(so, 1);
5376172090Srrs					SCTP_TCB_LOCK(stcb);
5377172090Srrs					atomic_subtract_int(&stcb->asoc.refcnt, 1);
5378172090Srrs#endif
5379171943Srrs					(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_29);
5380252882Stuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5381172090Srrs					SCTP_SOCKET_UNLOCK(so, 1);
5382172090Srrs#endif
5383163953Srrs					*offset = length;
5384163953Srrs					return (NULL);
5385163953Srrs				}
5386163953Srrs				sctp_handle_forward_tsn(stcb,
5387170992Srrs				    (struct sctp_forward_tsn_chunk *)ch, &abort_flag, m, *offset);
5388163953Srrs				if (abort_flag) {
5389163953Srrs					*offset = length;
5390163953Srrs					return (NULL);
5391163953Srrs				} else {
5392179783Srrs					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5393171943Srrs						sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5394171943Srrs						    stcb->asoc.overall_error_count,
5395171943Srrs						    0,
5396171943Srrs						    SCTP_FROM_SCTP_INPUT,
5397171943Srrs						    __LINE__);
5398171943Srrs					}
5399163953Srrs					stcb->asoc.overall_error_count = 0;
5400163953Srrs				}
5401163953Srrs
5402163953Srrs			}
5403163953Srrs			break;
5404163953Srrs		case SCTP_STREAM_RESET:
5405169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_STREAM_RESET\n");
5406169420Srrs			if (((stcb == NULL) || (ch == NULL) || (chk_length < sizeof(struct sctp_stream_reset_tsn_req)))) {
5407169208Srrs				/* Its not ours */
5408169378Srrs				if (locked_tcb) {
5409169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5410169378Srrs				}
5411169208Srrs				*offset = length;
5412169208Srrs				return (NULL);
5413169208Srrs			}
5414169420Srrs			if (stcb->asoc.peer_supports_strreset == 0) {
5415169420Srrs				/*
5416169420Srrs				 * hmm, peer should have announced this, but
5417169420Srrs				 * we will turn it on since he is sending us
5418169420Srrs				 * a stream reset.
5419169420Srrs				 */
5420169420Srrs				stcb->asoc.peer_supports_strreset = 1;
5421163953Srrs			}
5422252929Stuexen			if (sctp_handle_stream_reset(stcb, m, *offset, ch)) {
5423169420Srrs				/* stop processing */
5424169420Srrs				*offset = length;
5425169420Srrs				return (NULL);
5426169420Srrs			}
5427163953Srrs			break;
5428163953Srrs		case SCTP_PACKET_DROPPED:
5429169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_PACKET_DROPPED\n");
5430163953Srrs			/* re-get it all please */
5431169208Srrs			if (chk_length < sizeof(struct sctp_pktdrop_chunk)) {
5432169208Srrs				/* Its not ours */
5433169378Srrs				if (locked_tcb) {
5434169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5435169378Srrs				}
5436169208Srrs				*offset = length;
5437169208Srrs				return (NULL);
5438169208Srrs			}
5439169420Srrs			if (ch && (stcb) && netp && (*netp)) {
5440169378Srrs				sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch,
5441170781Srrs				    stcb, *netp,
5442170781Srrs				    min(chk_length, (sizeof(chunk_buf) - 4)));
5443170781Srrs
5444169378Srrs			}
5445163953Srrs			break;
5446163953Srrs
5447163953Srrs		case SCTP_AUTHENTICATION:
5448169420Srrs			SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_AUTHENTICATION\n");
5449179783Srrs			if (SCTP_BASE_SYSCTL(sctp_auth_disable))
5450163953Srrs				goto unknown_chunk;
5451163953Srrs
5452163953Srrs			if (stcb == NULL) {
5453163953Srrs				/* save the first AUTH for later processing */
5454163953Srrs				if (auth_skipped == 0) {
5455163953Srrs					auth_offset = *offset;
5456163953Srrs					auth_len = chk_length;
5457163953Srrs					auth_skipped = 1;
5458163953Srrs				}
5459163953Srrs				/* skip this chunk (temporarily) */
5460163953Srrs				goto next_chunk;
5461163953Srrs			}
5462169208Srrs			if ((chk_length < (sizeof(struct sctp_auth_chunk))) ||
5463169420Srrs			    (chk_length > (sizeof(struct sctp_auth_chunk) +
5464169420Srrs			    SCTP_AUTH_DIGEST_LEN_MAX))) {
5465169208Srrs				/* Its not ours */
5466169378Srrs				if (locked_tcb) {
5467169295Srrs					SCTP_TCB_UNLOCK(locked_tcb);
5468169378Srrs				}
5469169208Srrs				*offset = length;
5470169208Srrs				return (NULL);
5471169208Srrs			}
5472163953Srrs			if (got_auth == 1) {
5473163953Srrs				/* skip this chunk... it's already auth'd */
5474163953Srrs				goto next_chunk;
5475163953Srrs			}
5476163953Srrs			got_auth = 1;
5477169420Srrs			if ((ch == NULL) || sctp_handle_auth(stcb, (struct sctp_auth_chunk *)ch,
5478163953Srrs			    m, *offset)) {
5479163953Srrs				/* auth HMAC failed so dump the packet */
5480163953Srrs				*offset = length;
5481163953Srrs				return (stcb);
5482163953Srrs			} else {
5483163953Srrs				/* remaining chunks are HMAC checked */
5484163953Srrs				stcb->asoc.authenticated = 1;
5485163953Srrs			}
5486163953Srrs			break;
5487163953Srrs
5488163953Srrs		default:
5489163953Srrs	unknown_chunk:
5490163953Srrs			/* it's an unknown chunk! */
5491163953Srrs			if ((ch->chunk_type & 0x40) && (stcb != NULL)) {
5492163953Srrs				struct mbuf *mm;
5493163953Srrs				struct sctp_paramhdr *phd;
5494163953Srrs
5495163953Srrs				mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
5496165647Srrs				    0, M_DONTWAIT, 1, MT_DATA);
5497163953Srrs				if (mm) {
5498163953Srrs					phd = mtod(mm, struct sctp_paramhdr *);
5499163953Srrs					/*
5500163953Srrs					 * We cheat and use param type since
5501163953Srrs					 * we did not bother to define a
5502163953Srrs					 * error cause struct. They are the
5503163953Srrs					 * same basic format with different
5504163953Srrs					 * names.
5505163953Srrs					 */
5506163953Srrs					phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK);
5507163953Srrs					phd->param_length = htons(chk_length + sizeof(*phd));
5508165647Srrs					SCTP_BUF_LEN(mm) = sizeof(*phd);
5509234794Stuexen					SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, chk_length, M_DONTWAIT);
5510165647Srrs					if (SCTP_BUF_NEXT(mm)) {
5511234794Stuexen						if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL)) {
5512234794Stuexen							sctp_m_freem(mm);
5513234794Stuexen						} else {
5514178202Srrs#ifdef SCTP_MBUF_LOGGING
5515234794Stuexen							if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
5516234794Stuexen								struct mbuf *mat;
5517178202Srrs
5518234797Stuexen								for (mat = SCTP_BUF_NEXT(mm); mat; mat = SCTP_BUF_NEXT(mat)) {
5519234794Stuexen									if (SCTP_BUF_IS_EXTENDED(mat)) {
5520234794Stuexen										sctp_log_mb(mat, SCTP_MBUF_ICOPY);
5521234794Stuexen									}
5522178202Srrs								}
5523178202Srrs							}
5524234794Stuexen#endif
5525234794Stuexen							sctp_queue_op_err(stcb, mm);
5526178202Srrs						}
5527163953Srrs					} else {
5528163953Srrs						sctp_m_freem(mm);
5529163953Srrs					}
5530163953Srrs				}
5531163953Srrs			}
5532163953Srrs			if ((ch->chunk_type & 0x80) == 0) {
5533163953Srrs				/* discard this packet */
5534163953Srrs				*offset = length;
5535163953Srrs				return (stcb);
5536163953Srrs			}	/* else skip this bad chunk and continue... */
5537163953Srrs			break;
5538163953Srrs		}		/* switch (ch->chunk_type) */
5539163953Srrs
5540163953Srrs
5541163953Srrsnext_chunk:
5542163953Srrs		/* get the next chunk */
5543163953Srrs		*offset += SCTP_SIZE32(chk_length);
5544163953Srrs		if (*offset >= length) {
5545163953Srrs			/* no more data left in the mbuf chain */
5546163953Srrs			break;
5547163953Srrs		}
5548163953Srrs		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
5549163953Srrs		    sizeof(struct sctp_chunkhdr), chunk_buf);
5550163953Srrs		if (ch == NULL) {
5551169378Srrs			if (locked_tcb) {
5552163953Srrs				SCTP_TCB_UNLOCK(locked_tcb);
5553169378Srrs			}
5554163953Srrs			*offset = length;
5555163953Srrs			return (NULL);
5556163953Srrs		}
5557163953Srrs	}			/* while */
5558171990Srrs
5559171990Srrs	if (asconf_cnt > 0 && stcb != NULL) {
5560171990Srrs		sctp_send_asconf_ack(stcb);
5561171990Srrs	}
5562163953Srrs	return (stcb);
5563163953Srrs}
5564163953Srrs
5565163953Srrs
5566171440Srrs#ifdef INVARIANTS
5567208853Srrs#ifdef __GNUC__
5568208853Srrs__attribute__((noinline))
5569208853Srrs#endif
5570208853Srrs	void
5571208853Srrs	     sctp_validate_no_locks(struct sctp_inpcb *inp)
5572171440Srrs{
5573208853Srrs	struct sctp_tcb *lstcb;
5574171440Srrs
5575208853Srrs	LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
5576208853Srrs		if (mtx_owned(&lstcb->tcb_mtx)) {
5577171440Srrs			panic("Own lock on stcb at return from input");
5578171440Srrs		}
5579171440Srrs	}
5580208876Srrs	if (mtx_owned(&inp->inp_create_mtx)) {
5581208876Srrs		panic("Own create lock on inp");
5582208876Srrs	}
5583208876Srrs	if (mtx_owned(&inp->inp_mtx)) {
5584208876Srrs		panic("Own inp lock on inp");
5585208876Srrs	}
5586171440Srrs}
5587171440Srrs
5588171440Srrs#endif
5589171440Srrs
5590163953Srrs/*
5591163953Srrs * common input chunk processing (v4 and v6)
5592163953Srrs */
5593169378Srrsvoid
5594252889Stuexensctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length,
5595252889Stuexen    struct sockaddr *src, struct sockaddr *dst,
5596252889Stuexen    struct sctphdr *sh, struct sctp_chunkhdr *ch,
5597252896Stuexen#if !defined(SCTP_WITH_NO_CSUM)
5598252896Stuexen    uint8_t compute_crc,
5599252896Stuexen#endif
5600252896Stuexen    uint8_t ecn_bits,
5601238253Stuexen    uint8_t use_mflowid, uint32_t mflowid,
5602238253Stuexen    uint32_t vrf_id, uint16_t port)
5603163953Srrs{
5604163953Srrs	uint32_t high_tsn;
5605163953Srrs	int fwd_tsn_seen = 0, data_processed = 0;
5606266181Stuexen	struct mbuf *m = *mm, *op_err;
5607266181Stuexen	char msg[SCTP_DIAG_INFO_LEN];
5608163953Srrs	int un_sent;
5609218129Srrs	int cnt_ctrl_ready = 0;
5610252896Stuexen	struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
5611252896Stuexen	struct sctp_tcb *stcb = NULL;
5612252897Stuexen	struct sctp_nets *net = NULL;
5613163953Srrs
5614163953Srrs	SCTP_STAT_INCR(sctps_recvdatagrams);
5615163953Srrs#ifdef SCTP_AUDITING_ENABLED
5616163953Srrs	sctp_audit_log(0xE0, 1);
5617163953Srrs	sctp_auditing(0, inp, stcb, net);
5618163953Srrs#endif
5619252896Stuexen#if !defined(SCTP_WITH_NO_CSUM)
5620252896Stuexen	if (compute_crc != 0) {
5621252896Stuexen		uint32_t check, calc_check;
5622163953Srrs
5623252896Stuexen		check = sh->checksum;
5624252896Stuexen		sh->checksum = 0;
5625252896Stuexen		calc_check = sctp_calculate_cksum(m, iphlen);
5626252896Stuexen		sh->checksum = check;
5627252896Stuexen		if (calc_check != check) {
5628252896Stuexen			SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x  m:%p mlen:%d iphlen:%d\n",
5629252927Stuexen			    calc_check, check, (void *)m, length, iphlen);
5630252896Stuexen			stcb = sctp_findassociation_addr(m, offset, src, dst,
5631252896Stuexen			    sh, ch, &inp, &net, vrf_id);
5632252896Stuexen			if ((net != NULL) && (port != 0)) {
5633252896Stuexen				if (net->port == 0) {
5634252896Stuexen					sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
5635252896Stuexen				}
5636252896Stuexen				net->port = port;
5637252896Stuexen			}
5638252896Stuexen			if ((net != NULL) && (use_mflowid != 0)) {
5639252896Stuexen				net->flowid = mflowid;
5640252896Stuexen#ifdef INVARIANTS
5641252896Stuexen				net->flowidset = 1;
5642252896Stuexen#endif
5643252896Stuexen			}
5644252896Stuexen			if ((inp != NULL) && (stcb != NULL)) {
5645252896Stuexen				sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
5646252896Stuexen				sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
5647252896Stuexen			} else if ((inp != NULL) && (stcb == NULL)) {
5648252896Stuexen				inp_decr = inp;
5649252896Stuexen			}
5650252896Stuexen			SCTP_STAT_INCR(sctps_badsum);
5651252896Stuexen			SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
5652252896Stuexen			goto out;
5653252896Stuexen		}
5654252896Stuexen	}
5655252896Stuexen#endif
5656252896Stuexen	/* Destination port of 0 is illegal, based on RFC4960. */
5657252896Stuexen	if (sh->dest_port == 0) {
5658252896Stuexen		SCTP_STAT_INCR(sctps_hdrops);
5659252896Stuexen		goto out;
5660252896Stuexen	}
5661252896Stuexen	stcb = sctp_findassociation_addr(m, offset, src, dst,
5662252896Stuexen	    sh, ch, &inp, &net, vrf_id);
5663252896Stuexen	if ((net != NULL) && (port != 0)) {
5664252896Stuexen		if (net->port == 0) {
5665252896Stuexen			sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
5666252896Stuexen		}
5667252896Stuexen		net->port = port;
5668252896Stuexen	}
5669252896Stuexen	if ((net != NULL) && (use_mflowid != 0)) {
5670252896Stuexen		net->flowid = mflowid;
5671252896Stuexen#ifdef INVARIANTS
5672252896Stuexen		net->flowidset = 1;
5673252896Stuexen#endif
5674252896Stuexen	}
5675252896Stuexen	if (inp == NULL) {
5676252896Stuexen		SCTP_STAT_INCR(sctps_noport);
5677252896Stuexen		if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) {
5678252896Stuexen			goto out;
5679252896Stuexen		}
5680252896Stuexen		if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
5681252896Stuexen			sctp_send_shutdown_complete2(src, dst, sh,
5682252896Stuexen			    use_mflowid, mflowid,
5683252896Stuexen			    vrf_id, port);
5684252896Stuexen			goto out;
5685252896Stuexen		}
5686252896Stuexen		if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
5687252896Stuexen			goto out;
5688252896Stuexen		}
5689252896Stuexen		if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
5690252896Stuexen			if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
5691252896Stuexen			    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
5692252896Stuexen			    (ch->chunk_type != SCTP_INIT))) {
5693266181Stuexen				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
5694266181Stuexen				    "Out of the blue");
5695252896Stuexen				sctp_send_abort(m, iphlen, src, dst,
5696266181Stuexen				    sh, 0, op_err,
5697252896Stuexen				    use_mflowid, mflowid,
5698252896Stuexen				    vrf_id, port);
5699252896Stuexen			}
5700252896Stuexen		}
5701252896Stuexen		goto out;
5702252896Stuexen	} else if (stcb == NULL) {
5703252896Stuexen		inp_decr = inp;
5704252896Stuexen	}
5705252896Stuexen#ifdef IPSEC
5706252896Stuexen	/*-
5707252896Stuexen	 * I very much doubt any of the IPSEC stuff will work but I have no
5708252896Stuexen	 * idea, so I will leave it in place.
5709252896Stuexen	 */
5710252896Stuexen	if (inp != NULL) {
5711252896Stuexen		switch (dst->sa_family) {
5712252896Stuexen#ifdef INET
5713252896Stuexen		case AF_INET:
5714252896Stuexen			if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
5715253263Stuexen				IPSECSTAT_INC(in_polvio);
5716252896Stuexen				SCTP_STAT_INCR(sctps_hdrops);
5717252896Stuexen				goto out;
5718252896Stuexen			}
5719252896Stuexen			break;
5720252896Stuexen#endif
5721252896Stuexen#ifdef INET6
5722252896Stuexen		case AF_INET6:
5723252896Stuexen			if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
5724253263Stuexen				IPSEC6STAT_INC(in_polvio);
5725252896Stuexen				SCTP_STAT_INCR(sctps_hdrops);
5726252896Stuexen				goto out;
5727252896Stuexen			}
5728252896Stuexen			break;
5729252896Stuexen#endif
5730252896Stuexen		default:
5731252896Stuexen			break;
5732252896Stuexen		}
5733252896Stuexen	}
5734252896Stuexen#endif
5735179783Srrs	SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n",
5736252927Stuexen	    (void *)m, iphlen, offset, length, (void *)stcb);
5737163953Srrs	if (stcb) {
5738163953Srrs		/* always clear this before beginning a packet */
5739163953Srrs		stcb->asoc.authenticated = 0;
5740163953Srrs		stcb->asoc.seen_a_sack_this_pkt = 0;
5741171990Srrs		SCTPDBG(SCTP_DEBUG_INPUT1, "stcb:%p state:%x\n",
5742252927Stuexen		    (void *)stcb, stcb->asoc.state);
5743171990Srrs
5744171943Srrs		if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) ||
5745171943Srrs		    (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
5746171745Srrs			/*-
5747171745Srrs			 * If we hit here, we had a ref count
5748171745Srrs			 * up when the assoc was aborted and the
5749171745Srrs			 * timer is clearing out the assoc, we should
5750171745Srrs			 * NOT respond to any packet.. its OOTB.
5751171745Srrs			 */
5752171745Srrs			SCTP_TCB_UNLOCK(stcb);
5753252896Stuexen			stcb = NULL;
5754266181Stuexen			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
5755266181Stuexen			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
5756266181Stuexen			    msg);
5757266181Stuexen			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
5758238253Stuexen			    use_mflowid, mflowid,
5759179157Srrs			    vrf_id, port);
5760252896Stuexen			goto out;
5761171745Srrs		}
5762163953Srrs	}
5763163953Srrs	if (IS_SCTP_CONTROL(ch)) {
5764163953Srrs		/* process the control portion of the SCTP packet */
5765169655Srrs		/* sa_ignore NO_NULL_CHK */
5766252889Stuexen		stcb = sctp_process_control(m, iphlen, &offset, length,
5767252889Stuexen		    src, dst, sh, ch,
5768238253Stuexen		    inp, stcb, &net, &fwd_tsn_seen,
5769238253Stuexen		    use_mflowid, mflowid,
5770238253Stuexen		    vrf_id, port);
5771163953Srrs		if (stcb) {
5772163953Srrs			/*
5773163953Srrs			 * This covers us if the cookie-echo was there and
5774163953Srrs			 * it changes our INP.
5775163953Srrs			 */
5776163953Srrs			inp = stcb->sctp_ep;
5777179783Srrs			if ((net) && (port)) {
5778179783Srrs				if (net->port == 0) {
5779231038Stuexen					sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
5780179783Srrs				}
5781179783Srrs				net->port = port;
5782179783Srrs			}
5783163953Srrs		}
5784163953Srrs	} else {
5785163953Srrs		/*
5786163953Srrs		 * no control chunks, so pre-process DATA chunks (these
5787163953Srrs		 * checks are taken care of by control processing)
5788163953Srrs		 */
5789163953Srrs
5790163953Srrs		/*
5791163953Srrs		 * if DATA only packet, and auth is required, then punt...
5792163953Srrs		 * can't have authenticated without any AUTH (control)
5793163953Srrs		 * chunks
5794163953Srrs		 */
5795179783Srrs		if ((stcb != NULL) &&
5796179783Srrs		    !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
5797179783Srrs		    sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
5798163953Srrs			/* "silently" ignore */
5799163953Srrs			SCTP_STAT_INCR(sctps_recvauthmissing);
5800252896Stuexen			goto out;
5801163953Srrs		}
5802163953Srrs		if (stcb == NULL) {
5803163953Srrs			/* out of the blue DATA chunk */
5804266181Stuexen			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
5805266181Stuexen			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
5806266181Stuexen			    msg);
5807266181Stuexen			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
5808238253Stuexen			    use_mflowid, mflowid,
5809179157Srrs			    vrf_id, port);
5810252896Stuexen			goto out;
5811163953Srrs		}
5812163953Srrs		if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) {
5813163953Srrs			/* v_tag mismatch! */
5814163953Srrs			SCTP_STAT_INCR(sctps_badvtag);
5815252896Stuexen			goto out;
5816163953Srrs		}
5817163953Srrs	}
5818163953Srrs
5819163953Srrs	if (stcb == NULL) {
5820163953Srrs		/*
5821163953Srrs		 * no valid TCB for this packet, or we found it's a bad
5822163953Srrs		 * packet while processing control, or we're done with this
5823163953Srrs		 * packet (done or skip rest of data), so we drop it...
5824163953Srrs		 */
5825252896Stuexen		goto out;
5826163953Srrs	}
5827163953Srrs	/*
5828163953Srrs	 * DATA chunk processing
5829163953Srrs	 */
5830163953Srrs	/* plow through the data chunks while length > offset */
5831163953Srrs
5832163953Srrs	/*
5833163953Srrs	 * Rest should be DATA only.  Check authentication state if AUTH for
5834163953Srrs	 * DATA is required.
5835163953Srrs	 */
5836179783Srrs	if ((length > offset) &&
5837179783Srrs	    (stcb != NULL) &&
5838179783Srrs	    !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
5839179783Srrs	    sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) &&
5840163953Srrs	    !stcb->asoc.authenticated) {
5841163953Srrs		/* "silently" ignore */
5842163953Srrs		SCTP_STAT_INCR(sctps_recvauthmissing);
5843169420Srrs		SCTPDBG(SCTP_DEBUG_AUTH1,
5844169420Srrs		    "Data chunk requires AUTH, skipped\n");
5845165220Srrs		goto trigger_send;
5846163953Srrs	}
5847163953Srrs	if (length > offset) {
5848163953Srrs		int retval;
5849163953Srrs
5850163953Srrs		/*
5851163953Srrs		 * First check to make sure our state is correct. We would
5852163953Srrs		 * not get here unless we really did have a tag, so we don't
5853163953Srrs		 * abort if this happens, just dump the chunk silently.
5854163953Srrs		 */
5855163953Srrs		switch (SCTP_GET_STATE(&stcb->asoc)) {
5856163953Srrs		case SCTP_STATE_COOKIE_ECHOED:
5857163953Srrs			/*
5858163953Srrs			 * we consider data with valid tags in this state
5859163953Srrs			 * shows us the cookie-ack was lost. Imply it was
5860163953Srrs			 * there.
5861163953Srrs			 */
5862179783Srrs			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
5863171943Srrs				sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
5864171943Srrs				    stcb->asoc.overall_error_count,
5865171943Srrs				    0,
5866171943Srrs				    SCTP_FROM_SCTP_INPUT,
5867171943Srrs				    __LINE__);
5868171943Srrs			}
5869163953Srrs			stcb->asoc.overall_error_count = 0;
5870163953Srrs			sctp_handle_cookie_ack((struct sctp_cookie_ack_chunk *)ch, stcb, net);
5871163953Srrs			break;
5872163953Srrs		case SCTP_STATE_COOKIE_WAIT:
5873163953Srrs			/*
5874163953Srrs			 * We consider OOTB any data sent during asoc setup.
5875163953Srrs			 */
5876266181Stuexen			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
5877266181Stuexen			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
5878266181Stuexen			    msg);
5879266181Stuexen			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
5880238253Stuexen			    use_mflowid, mflowid,
5881179157Srrs			    vrf_id, port);
5882252896Stuexen			goto out;
5883171531Srrs			/* sa_ignore NOTREACHED */
5884163953Srrs			break;
5885163953Srrs		case SCTP_STATE_EMPTY:	/* should not happen */
5886163953Srrs		case SCTP_STATE_INUSE:	/* should not happen */
5887163953Srrs		case SCTP_STATE_SHUTDOWN_RECEIVED:	/* This is a peer error */
5888163953Srrs		case SCTP_STATE_SHUTDOWN_ACK_SENT:
5889163953Srrs		default:
5890252896Stuexen			goto out;
5891171531Srrs			/* sa_ignore NOTREACHED */
5892163953Srrs			break;
5893163953Srrs		case SCTP_STATE_OPEN:
5894163953Srrs		case SCTP_STATE_SHUTDOWN_SENT:
5895163953Srrs			break;
5896163953Srrs		}
5897163953Srrs		/* plow through the data chunks while length > offset */
5898252889Stuexen		retval = sctp_process_data(mm, iphlen, &offset, length,
5899252889Stuexen		    src, dst, sh,
5900238253Stuexen		    inp, stcb, net, &high_tsn,
5901238253Stuexen		    use_mflowid, mflowid,
5902238253Stuexen		    vrf_id, port);
5903163953Srrs		if (retval == 2) {
5904163953Srrs			/*
5905163953Srrs			 * The association aborted, NO UNLOCK needed since
5906163953Srrs			 * the association is destroyed.
5907163953Srrs			 */
5908252896Stuexen			stcb = NULL;
5909252896Stuexen			goto out;
5910163953Srrs		}
5911163953Srrs		data_processed = 1;
5912163953Srrs		/*
5913163953Srrs		 * Anything important needs to have been m_copy'ed in
5914163953Srrs		 * process_data
5915163953Srrs		 */
5916163953Srrs	}
5917218129Srrs	/* take care of ecn */
5918231039Stuexen	if ((data_processed == 1) &&
5919231039Stuexen	    (stcb->asoc.ecn_allowed == 1) &&
5920218235Stuexen	    ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) {
5921218129Srrs		/* Yep, we need to add a ECNE */
5922218129Srrs		sctp_send_ecn_echo(stcb, net, high_tsn);
5923218129Srrs	}
5924163953Srrs	if ((data_processed == 0) && (fwd_tsn_seen)) {
5925216495Stuexen		int was_a_gap;
5926216495Stuexen		uint32_t highest_tsn;
5927163953Srrs
5928216825Stuexen		if (SCTP_TSN_GT(stcb->asoc.highest_tsn_inside_nr_map, stcb->asoc.highest_tsn_inside_map)) {
5929216495Stuexen			highest_tsn = stcb->asoc.highest_tsn_inside_nr_map;
5930216495Stuexen		} else {
5931216495Stuexen			highest_tsn = stcb->asoc.highest_tsn_inside_map;
5932163953Srrs		}
5933216825Stuexen		was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn);
5934190689Srrs		stcb->asoc.send_sack = 1;
5935231038Stuexen		sctp_sack_check(stcb, was_a_gap);
5936190689Srrs	} else if (fwd_tsn_seen) {
5937190689Srrs		stcb->asoc.send_sack = 1;
5938163953Srrs	}
5939163953Srrs	/* trigger send of any chunks in queue... */
5940165220Srrstrigger_send:
5941163953Srrs#ifdef SCTP_AUDITING_ENABLED
5942163953Srrs	sctp_audit_log(0xE0, 2);
5943163953Srrs	sctp_auditing(1, inp, stcb, net);
5944163953Srrs#endif
5945169420Srrs	SCTPDBG(SCTP_DEBUG_INPUT1,
5946169420Srrs	    "Check for chunk output prw:%d tqe:%d tf=%d\n",
5947169420Srrs	    stcb->asoc.peers_rwnd,
5948169420Srrs	    TAILQ_EMPTY(&stcb->asoc.control_send_queue),
5949169420Srrs	    stcb->asoc.total_flight);
5950163953Srrs	un_sent = (stcb->asoc.total_output_queue_size - stcb->asoc.total_flight);
5951218129Srrs	if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
5952218129Srrs		cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq;
5953218129Srrs	}
5954218129Srrs	if (cnt_ctrl_ready ||
5955163953Srrs	    ((un_sent) &&
5956163953Srrs	    (stcb->asoc.peers_rwnd > 0 ||
5957163953Srrs	    (stcb->asoc.peers_rwnd <= 0 && stcb->asoc.total_flight == 0)))) {
5958169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT3, "Calling chunk OUTPUT\n");
5959172090Srrs		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
5960169420Srrs		SCTPDBG(SCTP_DEBUG_INPUT3, "chunk OUTPUT returns\n");
5961163953Srrs	}
5962163953Srrs#ifdef SCTP_AUDITING_ENABLED
5963163953Srrs	sctp_audit_log(0xE0, 3);
5964163953Srrs	sctp_auditing(2, inp, stcb, net);
5965163953Srrs#endif
5966252896Stuexenout:
5967252896Stuexen	if (stcb != NULL) {
5968252896Stuexen		SCTP_TCB_UNLOCK(stcb);
5969252896Stuexen	}
5970252896Stuexen	if (inp_decr != NULL) {
5971252896Stuexen		/* reduce ref-count */
5972252896Stuexen		SCTP_INP_WLOCK(inp_decr);
5973252896Stuexen		SCTP_INP_DECR_REF(inp_decr);
5974252896Stuexen		SCTP_INP_WUNLOCK(inp_decr);
5975252896Stuexen	}
5976171440Srrs#ifdef INVARIANTS
5977252896Stuexen	if (inp != NULL) {
5978252896Stuexen		sctp_validate_no_locks(inp);
5979252896Stuexen	}
5980171440Srrs#endif
5981169378Srrs	return;
5982163953Srrs}
5983163953Srrs
5984185694Srrs#if 0
5985185694Srrsstatic void
5986185694Srrssctp_print_mbuf_chain(struct mbuf *m)
5987185694Srrs{
5988185694Srrs	for (; m; m = SCTP_BUF_NEXT(m)) {
5989252927Stuexen		SCTP_PRINTF("%p: m_len = %ld\n", (void *)m, SCTP_BUF_LEN(m));
5990185694Srrs		if (SCTP_BUF_IS_EXTENDED(m))
5991252927Stuexen			SCTP_PRINTF("%p: extend_size = %d\n", (void *)m, SCTP_BUF_EXTEND_SIZE(m));
5992185694Srrs	}
5993185694Srrs}
5994163953Srrs
5995185694Srrs#endif
5996185694Srrs
5997221249Stuexen#ifdef INET
5998163953Srrsvoid
5999189004Srdivackysctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
6000163953Srrs{
6001165647Srrs	struct mbuf *m;
6002163953Srrs	int iphlen;
6003170181Srrs	uint32_t vrf_id = 0;
6004163953Srrs	uint8_t ecn_bits;
6005252889Stuexen	struct sockaddr_in src, dst;
6006163953Srrs	struct ip *ip;
6007163953Srrs	struct sctphdr *sh;
6008252883Stuexen	struct sctp_chunkhdr *ch;
6009252883Stuexen	int length, offset;
6010163953Srrs
6011211969Stuexen#if !defined(SCTP_WITH_NO_CSUM)
6012252896Stuexen	uint8_t compute_crc;
6013211969Stuexen
6014211969Stuexen#endif
6015252896Stuexen	uint32_t mflowid;
6016252896Stuexen	uint8_t use_mflowid;
6017211969Stuexen
6018252883Stuexen	iphlen = off;
6019169352Srrs	if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
6020169352Srrs		SCTP_RELEASE_PKT(i_pak);
6021169352Srrs		return;
6022169352Srrs	}
6023165647Srrs	m = SCTP_HEADER_TO_CHAIN(i_pak);
6024163953Srrs#ifdef SCTP_MBUF_LOGGING
6025163953Srrs	/* Log in any input mbufs */
6026179783Srrs	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
6027234797Stuexen		struct mbuf *mat;
6028234797Stuexen
6029231039Stuexen		for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
6030170744Srrs			if (SCTP_BUF_IS_EXTENDED(mat)) {
6031170744Srrs				sctp_log_mb(mat, SCTP_MBUF_INPUT);
6032170744Srrs			}
6033163953Srrs		}
6034163953Srrs	}
6035163953Srrs#endif
6036252879Stuexen#ifdef SCTP_PACKET_LOGGING
6037252883Stuexen	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
6038252879Stuexen		sctp_packet_log(m);
6039252883Stuexen	}
6040170091Srrs#endif
6041252896Stuexen	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
6042252896Stuexen	    "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
6043252896Stuexen	    m->m_pkthdr.len,
6044252896Stuexen	    if_name(m->m_pkthdr.rcvif),
6045252896Stuexen	    m->m_pkthdr.csum_flags);
6046238253Stuexen	if (m->m_flags & M_FLOWID) {
6047238253Stuexen		mflowid = m->m_pkthdr.flowid;
6048238253Stuexen		use_mflowid = 1;
6049238253Stuexen	} else {
6050238253Stuexen		mflowid = 0;
6051238253Stuexen		use_mflowid = 0;
6052238253Stuexen	}
6053252883Stuexen	SCTP_STAT_INCR(sctps_recvpackets);
6054252883Stuexen	SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
6055252883Stuexen	/* Get IP, SCTP, and first chunk header together in the first mbuf. */
6056252883Stuexen	offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
6057165647Srrs	if (SCTP_BUF_LEN(m) < offset) {
6058252889Stuexen		if ((m = m_pullup(m, offset)) == NULL) {
6059163953Srrs			SCTP_STAT_INCR(sctps_hdrops);
6060163953Srrs			return;
6061163953Srrs		}
6062163953Srrs	}
6063252889Stuexen	ip = mtod(m, struct ip *);
6064252883Stuexen	sh = (struct sctphdr *)((caddr_t)ip + iphlen);
6065252883Stuexen	ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
6066252883Stuexen	offset -= sizeof(struct sctp_chunkhdr);
6067252889Stuexen	memset(&src, 0, sizeof(struct sockaddr_in));
6068252889Stuexen	src.sin_family = AF_INET;
6069252889Stuexen	src.sin_len = sizeof(struct sockaddr_in);
6070252889Stuexen	src.sin_port = sh->src_port;
6071252889Stuexen	src.sin_addr = ip->ip_src;
6072252889Stuexen	memset(&dst, 0, sizeof(struct sockaddr_in));
6073252889Stuexen	dst.sin_family = AF_INET;
6074252889Stuexen	dst.sin_len = sizeof(struct sockaddr_in);
6075252889Stuexen	dst.sin_port = sh->dest_port;
6076252889Stuexen	dst.sin_addr = ip->ip_dst;
6077252883Stuexen	length = ip->ip_len + iphlen;
6078252883Stuexen	/* Validate mbuf chain length with IP payload length. */
6079252896Stuexen	if (SCTP_HEADER_LEN(m) != length) {
6080252883Stuexen		SCTPDBG(SCTP_DEBUG_INPUT1,
6081252896Stuexen		    "sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m));
6082188067Srrs		SCTP_STAT_INCR(sctps_hdrops);
6083252896Stuexen		goto out;
6084188067Srrs	}
6085163953Srrs	/* SCTP does not allow broadcasts or multicasts */
6086252889Stuexen	if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
6087252896Stuexen		goto out;
6088163953Srrs	}
6089252889Stuexen	if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) {
6090252896Stuexen		goto out;
6091163953Srrs	}
6092252896Stuexen	ecn_bits = ip->ip_tos;
6093211969Stuexen#if defined(SCTP_WITH_NO_CSUM)
6094211969Stuexen	SCTP_STAT_INCR(sctps_recvnocrc);
6095211969Stuexen#else
6096188067Srrs	if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
6097188067Srrs		SCTP_STAT_INCR(sctps_recvhwcrc);
6098252896Stuexen		compute_crc = 0;
6099252896Stuexen	} else {
6100252896Stuexen		SCTP_STAT_INCR(sctps_recvswcrc);
6101252896Stuexen		compute_crc = 1;
6102188067Srrs	}
6103218400Stuexen#endif
6104252896Stuexen	sctp_common_input_processing(&m, iphlen, offset, length,
6105252889Stuexen	    (struct sockaddr *)&src,
6106252889Stuexen	    (struct sockaddr *)&dst,
6107252896Stuexen	    sh, ch,
6108252896Stuexen#if !defined(SCTP_WITH_NO_CSUM)
6109252896Stuexen	    compute_crc,
6110218400Stuexen#endif
6111252896Stuexen	    ecn_bits,
6112238253Stuexen	    use_mflowid, mflowid,
6113238253Stuexen	    vrf_id, port);
6114252896Stuexenout:
6115163953Srrs	if (m) {
6116163953Srrs		sctp_m_freem(m);
6117163953Srrs	}
6118163953Srrs	return;
6119163953Srrs}
6120218211Srrs
6121218269Srrs#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
6122218269Srrsextern int *sctp_cpuarry;
6123218211Srrs
6124218269Srrs#endif
6125218269Srrs
6126179157Srrsvoid
6127218211Srrssctp_input(struct mbuf *m, int off)
6128179157Srrs{
6129218211Srrs#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
6130218211Srrs	struct ip *ip;
6131218211Srrs	struct sctphdr *sh;
6132218211Srrs	int offset;
6133218211Srrs	int cpu_to_use;
6134218371Srrs	uint32_t flowid, tag;
6135218211Srrs
6136218269Srrs	if (mp_ncpus > 1) {
6137218371Srrs		if (m->m_flags & M_FLOWID) {
6138218371Srrs			flowid = m->m_pkthdr.flowid;
6139218269Srrs		} else {
6140218269Srrs			/*
6141218371Srrs			 * No flow id built by lower layers fix it so we
6142218371Srrs			 * create one.
6143218269Srrs			 */
6144252889Stuexen			offset = off + sizeof(struct sctphdr);
6145218371Srrs			if (SCTP_BUF_LEN(m) < offset) {
6146252889Stuexen				if ((m = m_pullup(m, offset)) == NULL) {
6147218371Srrs					SCTP_STAT_INCR(sctps_hdrops);
6148218371Srrs					return;
6149218371Srrs				}
6150218371Srrs			}
6151252889Stuexen			ip = mtod(m, struct ip *);
6152218371Srrs			sh = (struct sctphdr *)((caddr_t)ip + off);
6153218371Srrs			tag = htonl(sh->v_tag);
6154218371Srrs			flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);
6155218371Srrs			m->m_pkthdr.flowid = flowid;
6156218371Srrs			m->m_flags |= M_FLOWID;
6157218269Srrs		}
6158218371Srrs		cpu_to_use = sctp_cpuarry[flowid % mp_ncpus];
6159218211Srrs		sctp_queue_to_mcore(m, off, cpu_to_use);
6160218211Srrs		return;
6161218211Srrs	}
6162218211Srrs#endif
6163218211Srrs	sctp_input_with_port(m, off, 0);
6164179157Srrs}
6165221249Stuexen
6166221249Stuexen#endif
6167