• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
5  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * a) Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  *
14  * b) Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the distribution.
17  *
18  * c) Neither the name of Cisco Systems, Inc. nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifdef __FreeBSD__
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 361225 2020-05-18 19:23:01Z tuexen $");
38 #endif
39 
40 #include <netinet/sctp_os.h>
41 #include <netinet/sctp_pcb.h>
42 #include <netinet/sctputil.h>
43 #include <netinet/sctp_var.h>
44 #include <netinet/sctp_sysctl.h>
45 #ifdef INET6
46 #if defined(__Userspace__) || defined(__FreeBSD__)
47 #include <netinet6/sctp6_var.h>
48 #endif
49 #endif
50 #include <netinet/sctp_header.h>
51 #include <netinet/sctp_output.h>
52 #include <netinet/sctp_uio.h>
53 #include <netinet/sctp_timer.h>
54 #include <netinet/sctp_indata.h>
55 #include <netinet/sctp_auth.h>
56 #include <netinet/sctp_asconf.h>
57 #include <netinet/sctp_bsd_addr.h>
58 #if defined(__Userspace__)
59 #include <netinet/sctp_constants.h>
60 #endif
61 #if defined(__FreeBSD__)
62 #include <netinet/sctp_kdtrace.h>
63 #if defined(INET6) || defined(INET)
64 #include <netinet/tcp_var.h>
65 #endif
66 #include <netinet/udp.h>
67 #include <netinet/udp_var.h>
68 #include <sys/proc.h>
69 #ifdef INET6
70 #include <netinet/icmp6.h>
71 #endif
72 #endif
73 
74 #if defined(__APPLE__)
75 #define APPLE_FILE_NO 8
76 #endif
77 
78 #if defined(__Windows__)
79 #if !defined(SCTP_LOCAL_TRACE_BUF)
80 #include "eventrace_netinet.h"
81 #include "sctputil.tmh" /* this is the file that will be auto generated */
82 #endif
83 #else
84 #ifndef KTR_SCTP
85 #define KTR_SCTP KTR_SUBSYS
86 #endif
87 #endif
88 
89 extern const struct sctp_cc_functions sctp_cc_functions[];
90 extern const struct sctp_ss_functions sctp_ss_functions[];
91 
92 void
sctp_sblog(struct sockbuf * sb,struct sctp_tcb * stcb,int from,int incr)93 sctp_sblog(struct sockbuf *sb, struct sctp_tcb *stcb, int from, int incr)
94 {
95 #if defined(SCTP_LOCAL_TRACE_BUF)
96 	struct sctp_cwnd_log sctp_clog;
97 
98 	sctp_clog.x.sb.stcb = stcb;
99 	sctp_clog.x.sb.so_sbcc = sb->sb_cc;
100 	if (stcb)
101 		sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc;
102 	else
103 		sctp_clog.x.sb.stcb_sbcc = 0;
104 	sctp_clog.x.sb.incr = incr;
105 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
106 	     SCTP_LOG_EVENT_SB,
107 	     from,
108 	     sctp_clog.x.misc.log1,
109 	     sctp_clog.x.misc.log2,
110 	     sctp_clog.x.misc.log3,
111 	     sctp_clog.x.misc.log4);
112 #endif
113 }
114 
115 void
sctp_log_closing(struct sctp_inpcb * inp,struct sctp_tcb * stcb,int16_t loc)116 sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc)
117 {
118 #if defined(SCTP_LOCAL_TRACE_BUF)
119 	struct sctp_cwnd_log sctp_clog;
120 
121 	sctp_clog.x.close.inp = (void *)inp;
122 	sctp_clog.x.close.sctp_flags = inp->sctp_flags;
123 	if (stcb) {
124 		sctp_clog.x.close.stcb = (void *)stcb;
125 		sctp_clog.x.close.state = (uint16_t)stcb->asoc.state;
126 	} else {
127 		sctp_clog.x.close.stcb = 0;
128 		sctp_clog.x.close.state = 0;
129 	}
130 	sctp_clog.x.close.loc = loc;
131 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
132 	     SCTP_LOG_EVENT_CLOSE,
133 	     0,
134 	     sctp_clog.x.misc.log1,
135 	     sctp_clog.x.misc.log2,
136 	     sctp_clog.x.misc.log3,
137 	     sctp_clog.x.misc.log4);
138 #endif
139 }
140 
141 void
rto_logging(struct sctp_nets * net,int from)142 rto_logging(struct sctp_nets *net, int from)
143 {
144 #if defined(SCTP_LOCAL_TRACE_BUF)
145 	struct sctp_cwnd_log sctp_clog;
146 
147 	memset(&sctp_clog, 0, sizeof(sctp_clog));
148 	sctp_clog.x.rto.net = (void *) net;
149 	sctp_clog.x.rto.rtt = net->rtt / 1000;
150 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
151 	     SCTP_LOG_EVENT_RTT,
152 	     from,
153 	     sctp_clog.x.misc.log1,
154 	     sctp_clog.x.misc.log2,
155 	     sctp_clog.x.misc.log3,
156 	     sctp_clog.x.misc.log4);
157 #endif
158 }
159 
160 void
sctp_log_strm_del_alt(struct sctp_tcb * stcb,uint32_t tsn,uint16_t sseq,uint16_t stream,int from)161 sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16_t stream, int from)
162 {
163 #if defined(SCTP_LOCAL_TRACE_BUF)
164 	struct sctp_cwnd_log sctp_clog;
165 
166 	sctp_clog.x.strlog.stcb = stcb;
167 	sctp_clog.x.strlog.n_tsn = tsn;
168 	sctp_clog.x.strlog.n_sseq = sseq;
169 	sctp_clog.x.strlog.e_tsn = 0;
170 	sctp_clog.x.strlog.e_sseq = 0;
171 	sctp_clog.x.strlog.strm = stream;
172 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
173 	     SCTP_LOG_EVENT_STRM,
174 	     from,
175 	     sctp_clog.x.misc.log1,
176 	     sctp_clog.x.misc.log2,
177 	     sctp_clog.x.misc.log3,
178 	     sctp_clog.x.misc.log4);
179 #endif
180 }
181 
182 void
sctp_log_nagle_event(struct sctp_tcb * stcb,int action)183 sctp_log_nagle_event(struct sctp_tcb *stcb, int action)
184 {
185 #if defined(SCTP_LOCAL_TRACE_BUF)
186 	struct sctp_cwnd_log sctp_clog;
187 
188 	sctp_clog.x.nagle.stcb = (void *)stcb;
189 	sctp_clog.x.nagle.total_flight = stcb->asoc.total_flight;
190 	sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size;
191 	sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue;
192 	sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count;
193 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
194 	     SCTP_LOG_EVENT_NAGLE,
195 	     action,
196 	     sctp_clog.x.misc.log1,
197 	     sctp_clog.x.misc.log2,
198 	     sctp_clog.x.misc.log3,
199 	     sctp_clog.x.misc.log4);
200 #endif
201 }
202 
203 void
sctp_log_sack(uint32_t old_cumack,uint32_t cumack,uint32_t tsn,uint16_t gaps,uint16_t dups,int from)204 sctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps, uint16_t dups, int from)
205 {
206 #if defined(SCTP_LOCAL_TRACE_BUF)
207 	struct sctp_cwnd_log sctp_clog;
208 
209 	sctp_clog.x.sack.cumack = cumack;
210 	sctp_clog.x.sack.oldcumack = old_cumack;
211 	sctp_clog.x.sack.tsn = tsn;
212 	sctp_clog.x.sack.numGaps = gaps;
213 	sctp_clog.x.sack.numDups = dups;
214 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
215 	     SCTP_LOG_EVENT_SACK,
216 	     from,
217 	     sctp_clog.x.misc.log1,
218 	     sctp_clog.x.misc.log2,
219 	     sctp_clog.x.misc.log3,
220 	     sctp_clog.x.misc.log4);
221 #endif
222 }
223 
224 void
sctp_log_map(uint32_t map,uint32_t cum,uint32_t high,int from)225 sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
226 {
227 #if defined(SCTP_LOCAL_TRACE_BUF)
228 	struct sctp_cwnd_log sctp_clog;
229 
230 	memset(&sctp_clog, 0, sizeof(sctp_clog));
231 	sctp_clog.x.map.base = map;
232 	sctp_clog.x.map.cum = cum;
233 	sctp_clog.x.map.high = high;
234 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
235 	     SCTP_LOG_EVENT_MAP,
236 	     from,
237 	     sctp_clog.x.misc.log1,
238 	     sctp_clog.x.misc.log2,
239 	     sctp_clog.x.misc.log3,
240 	     sctp_clog.x.misc.log4);
241 #endif
242 }
243 
244 void
sctp_log_fr(uint32_t biggest_tsn,uint32_t biggest_new_tsn,uint32_t tsn,int from)245 sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int from)
246 {
247 #if defined(SCTP_LOCAL_TRACE_BUF)
248 	struct sctp_cwnd_log sctp_clog;
249 
250 	memset(&sctp_clog, 0, sizeof(sctp_clog));
251 	sctp_clog.x.fr.largest_tsn = biggest_tsn;
252 	sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn;
253 	sctp_clog.x.fr.tsn = tsn;
254 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
255 	     SCTP_LOG_EVENT_FR,
256 	     from,
257 	     sctp_clog.x.misc.log1,
258 	     sctp_clog.x.misc.log2,
259 	     sctp_clog.x.misc.log3,
260 	     sctp_clog.x.misc.log4);
261 #endif
262 }
263 
264 #ifdef SCTP_MBUF_LOGGING
265 void
sctp_log_mb(struct mbuf * m,int from)266 sctp_log_mb(struct mbuf *m, int from)
267 {
268 #if defined(SCTP_LOCAL_TRACE_BUF)
269 	struct sctp_cwnd_log sctp_clog;
270 
271 	sctp_clog.x.mb.mp = m;
272 	sctp_clog.x.mb.mbuf_flags = (uint8_t)(SCTP_BUF_GET_FLAGS(m));
273 	sctp_clog.x.mb.size = (uint16_t)(SCTP_BUF_LEN(m));
274 	sctp_clog.x.mb.data = SCTP_BUF_AT(m, 0);
275 	if (SCTP_BUF_IS_EXTENDED(m)) {
276 		sctp_clog.x.mb.ext = SCTP_BUF_EXTEND_BASE(m);
277 #if defined(__APPLE__)
278 		/* APPLE does not use a ref_cnt, but a forward/backward ref queue */
279 #else
280 		sctp_clog.x.mb.refcnt = (uint8_t)(SCTP_BUF_EXTEND_REFCNT(m));
281 #endif
282 	} else {
283 		sctp_clog.x.mb.ext = 0;
284 		sctp_clog.x.mb.refcnt = 0;
285 	}
286 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
287 	     SCTP_LOG_EVENT_MBUF,
288 	     from,
289 	     sctp_clog.x.misc.log1,
290 	     sctp_clog.x.misc.log2,
291 	     sctp_clog.x.misc.log3,
292 	     sctp_clog.x.misc.log4);
293 #endif
294 }
295 
296 void
sctp_log_mbc(struct mbuf * m,int from)297 sctp_log_mbc(struct mbuf *m, int from)
298 {
299 	struct mbuf *mat;
300 
301 	for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
302 		sctp_log_mb(mat, from);
303 	}
304 }
305 #endif
306 
307 void
sctp_log_strm_del(struct sctp_queued_to_read * control,struct sctp_queued_to_read * poschk,int from)308 sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk, int from)
309 {
310 #if defined(SCTP_LOCAL_TRACE_BUF)
311 	struct sctp_cwnd_log sctp_clog;
312 
313 	if (control == NULL) {
314 		SCTP_PRINTF("Gak log of NULL?\n");
315 		return;
316 	}
317 	sctp_clog.x.strlog.stcb = control->stcb;
318 	sctp_clog.x.strlog.n_tsn = control->sinfo_tsn;
319 	sctp_clog.x.strlog.n_sseq = (uint16_t)control->mid;
320 	sctp_clog.x.strlog.strm = control->sinfo_stream;
321 	if (poschk != NULL) {
322 		sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn;
323 		sctp_clog.x.strlog.e_sseq = (uint16_t)poschk->mid;
324 	} else {
325 		sctp_clog.x.strlog.e_tsn = 0;
326 		sctp_clog.x.strlog.e_sseq = 0;
327 	}
328 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
329 	     SCTP_LOG_EVENT_STRM,
330 	     from,
331 	     sctp_clog.x.misc.log1,
332 	     sctp_clog.x.misc.log2,
333 	     sctp_clog.x.misc.log3,
334 	     sctp_clog.x.misc.log4);
335 #endif
336 }
337 
338 void
sctp_log_cwnd(struct sctp_tcb * stcb,struct sctp_nets * net,int augment,uint8_t from)339 sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
340 {
341 #if defined(SCTP_LOCAL_TRACE_BUF)
342 	struct sctp_cwnd_log sctp_clog;
343 
344 	sctp_clog.x.cwnd.net = net;
345 	if (stcb->asoc.send_queue_cnt > 255)
346 		sctp_clog.x.cwnd.cnt_in_send = 255;
347 	else
348 		sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
349 	if (stcb->asoc.stream_queue_cnt > 255)
350 		sctp_clog.x.cwnd.cnt_in_str = 255;
351 	else
352 		sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
353 
354 	if (net) {
355 		sctp_clog.x.cwnd.cwnd_new_value = net->cwnd;
356 		sctp_clog.x.cwnd.inflight = net->flight_size;
357 		sctp_clog.x.cwnd.pseudo_cumack = net->pseudo_cumack;
358 		sctp_clog.x.cwnd.meets_pseudo_cumack = net->new_pseudo_cumack;
359 		sctp_clog.x.cwnd.need_new_pseudo_cumack = net->find_pseudo_cumack;
360 	}
361 	if (SCTP_CWNDLOG_PRESEND == from) {
362 		sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd;
363 	}
364 	sctp_clog.x.cwnd.cwnd_augment = augment;
365 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
366 	     SCTP_LOG_EVENT_CWND,
367 	     from,
368 	     sctp_clog.x.misc.log1,
369 	     sctp_clog.x.misc.log2,
370 	     sctp_clog.x.misc.log3,
371 	     sctp_clog.x.misc.log4);
372 #endif
373 }
374 
375 #ifndef __APPLE__
376 void
sctp_log_lock(struct sctp_inpcb * inp,struct sctp_tcb * stcb,uint8_t from)377 sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from)
378 {
379 #if defined(SCTP_LOCAL_TRACE_BUF)
380 	struct sctp_cwnd_log sctp_clog;
381 
382 	memset(&sctp_clog, 0, sizeof(sctp_clog));
383 	if (inp) {
384 		sctp_clog.x.lock.sock = (void *) inp->sctp_socket;
385 
386 	} else {
387 		sctp_clog.x.lock.sock = (void *) NULL;
388 	}
389 	sctp_clog.x.lock.inp = (void *) inp;
390 #if (defined(__FreeBSD__) && __FreeBSD_version >= 503000) || (defined(__APPLE__))
391 	if (stcb) {
392 		sctp_clog.x.lock.tcb_lock = mtx_owned(&stcb->tcb_mtx);
393 	} else {
394 		sctp_clog.x.lock.tcb_lock = SCTP_LOCK_UNKNOWN;
395 	}
396 	if (inp) {
397 		sctp_clog.x.lock.inp_lock = mtx_owned(&inp->inp_mtx);
398 		sctp_clog.x.lock.create_lock = mtx_owned(&inp->inp_create_mtx);
399 	} else {
400 		sctp_clog.x.lock.inp_lock = SCTP_LOCK_UNKNOWN;
401 		sctp_clog.x.lock.create_lock = SCTP_LOCK_UNKNOWN;
402 	}
403 #if (defined(__FreeBSD__) && __FreeBSD_version <= 602000)
404 	sctp_clog.x.lock.info_lock = mtx_owned(&SCTP_BASE_INFO(ipi_ep_mtx));
405 #else
406 	sctp_clog.x.lock.info_lock = rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx));
407 #endif
408 	if (inp && (inp->sctp_socket)) {
409 		sctp_clog.x.lock.sock_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
410 		sctp_clog.x.lock.sockrcvbuf_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
411 		sctp_clog.x.lock.socksndbuf_lock = mtx_owned(&(inp->sctp_socket->so_snd.sb_mtx));
412 	} else {
413 		sctp_clog.x.lock.sock_lock = SCTP_LOCK_UNKNOWN;
414 		sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN;
415 		sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN;
416 	}
417 #endif
418 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
419 	     SCTP_LOG_LOCK_EVENT,
420 	     from,
421 	     sctp_clog.x.misc.log1,
422 	     sctp_clog.x.misc.log2,
423 	     sctp_clog.x.misc.log3,
424 	     sctp_clog.x.misc.log4);
425 #endif
426 }
427 #endif
428 
429 void
sctp_log_maxburst(struct sctp_tcb * stcb,struct sctp_nets * net,int error,int burst,uint8_t from)430 sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from)
431 {
432 #if defined(SCTP_LOCAL_TRACE_BUF)
433 	struct sctp_cwnd_log sctp_clog;
434 
435 	memset(&sctp_clog, 0, sizeof(sctp_clog));
436 	sctp_clog.x.cwnd.net = net;
437 	sctp_clog.x.cwnd.cwnd_new_value = error;
438 	sctp_clog.x.cwnd.inflight = net->flight_size;
439 	sctp_clog.x.cwnd.cwnd_augment = burst;
440 	if (stcb->asoc.send_queue_cnt > 255)
441 		sctp_clog.x.cwnd.cnt_in_send = 255;
442 	else
443 		sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
444 	if (stcb->asoc.stream_queue_cnt > 255)
445 		sctp_clog.x.cwnd.cnt_in_str = 255;
446 	else
447 		sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
448 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
449 	     SCTP_LOG_EVENT_MAXBURST,
450 	     from,
451 	     sctp_clog.x.misc.log1,
452 	     sctp_clog.x.misc.log2,
453 	     sctp_clog.x.misc.log3,
454 	     sctp_clog.x.misc.log4);
455 #endif
456 }
457 
458 void
sctp_log_rwnd(uint8_t from,uint32_t peers_rwnd,uint32_t snd_size,uint32_t overhead)459 sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead)
460 {
461 #if defined(SCTP_LOCAL_TRACE_BUF)
462 	struct sctp_cwnd_log sctp_clog;
463 
464 	sctp_clog.x.rwnd.rwnd = peers_rwnd;
465 	sctp_clog.x.rwnd.send_size = snd_size;
466 	sctp_clog.x.rwnd.overhead = overhead;
467 	sctp_clog.x.rwnd.new_rwnd = 0;
468 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
469 	     SCTP_LOG_EVENT_RWND,
470 	     from,
471 	     sctp_clog.x.misc.log1,
472 	     sctp_clog.x.misc.log2,
473 	     sctp_clog.x.misc.log3,
474 	     sctp_clog.x.misc.log4);
475 #endif
476 }
477 
478 void
sctp_log_rwnd_set(uint8_t from,uint32_t peers_rwnd,uint32_t flight_size,uint32_t overhead,uint32_t a_rwndval)479 sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint32_t overhead, uint32_t a_rwndval)
480 {
481 #if defined(SCTP_LOCAL_TRACE_BUF)
482 	struct sctp_cwnd_log sctp_clog;
483 
484 	sctp_clog.x.rwnd.rwnd = peers_rwnd;
485 	sctp_clog.x.rwnd.send_size = flight_size;
486 	sctp_clog.x.rwnd.overhead = overhead;
487 	sctp_clog.x.rwnd.new_rwnd = a_rwndval;
488 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
489 	     SCTP_LOG_EVENT_RWND,
490 	     from,
491 	     sctp_clog.x.misc.log1,
492 	     sctp_clog.x.misc.log2,
493 	     sctp_clog.x.misc.log3,
494 	     sctp_clog.x.misc.log4);
495 #endif
496 }
497 
498 #ifdef SCTP_MBCNT_LOGGING
499 static void
sctp_log_mbcnt(uint8_t from,uint32_t total_oq,uint32_t book,uint32_t total_mbcnt_q,uint32_t mbcnt)500 sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt)
501 {
502 #if defined(SCTP_LOCAL_TRACE_BUF)
503 	struct sctp_cwnd_log sctp_clog;
504 
505 	sctp_clog.x.mbcnt.total_queue_size = total_oq;
506 	sctp_clog.x.mbcnt.size_change = book;
507 	sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q;
508 	sctp_clog.x.mbcnt.mbcnt_change = mbcnt;
509 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
510 	     SCTP_LOG_EVENT_MBCNT,
511 	     from,
512 	     sctp_clog.x.misc.log1,
513 	     sctp_clog.x.misc.log2,
514 	     sctp_clog.x.misc.log3,
515 	     sctp_clog.x.misc.log4);
516 #endif
517 }
518 #endif
519 
520 void
sctp_misc_ints(uint8_t from,uint32_t a,uint32_t b,uint32_t c,uint32_t d)521 sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
522 {
523 #if defined(SCTP_LOCAL_TRACE_BUF)
524 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
525 	     SCTP_LOG_MISC_EVENT,
526 	     from,
527 	     a, b, c, d);
528 #endif
529 }
530 
531 void
sctp_wakeup_log(struct sctp_tcb * stcb,uint32_t wake_cnt,int from)532 sctp_wakeup_log(struct sctp_tcb *stcb, uint32_t wake_cnt, int from)
533 {
534 #if defined(SCTP_LOCAL_TRACE_BUF)
535 	struct sctp_cwnd_log sctp_clog;
536 
537 	sctp_clog.x.wake.stcb = (void *)stcb;
538 	sctp_clog.x.wake.wake_cnt = wake_cnt;
539 	sctp_clog.x.wake.flight = stcb->asoc.total_flight_count;
540 	sctp_clog.x.wake.send_q = stcb->asoc.send_queue_cnt;
541 	sctp_clog.x.wake.sent_q = stcb->asoc.sent_queue_cnt;
542 
543 	if (stcb->asoc.stream_queue_cnt < 0xff)
544 		sctp_clog.x.wake.stream_qcnt = (uint8_t) stcb->asoc.stream_queue_cnt;
545 	else
546 		sctp_clog.x.wake.stream_qcnt = 0xff;
547 
548 	if (stcb->asoc.chunks_on_out_queue < 0xff)
549 		sctp_clog.x.wake.chunks_on_oque = (uint8_t) stcb->asoc.chunks_on_out_queue;
550 	else
551 		sctp_clog.x.wake.chunks_on_oque = 0xff;
552 
553 	sctp_clog.x.wake.sctpflags = 0;
554 	/* set in the defered mode stuff */
555 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE)
556 		sctp_clog.x.wake.sctpflags |= 1;
557 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT)
558 		sctp_clog.x.wake.sctpflags |= 2;
559 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT)
560 		sctp_clog.x.wake.sctpflags |= 4;
561 	/* what about the sb */
562 	if (stcb->sctp_socket) {
563 		struct socket *so = stcb->sctp_socket;
564 
565 		sctp_clog.x.wake.sbflags = (uint8_t)((so->so_snd.sb_flags & 0x00ff));
566 	} else {
567 		sctp_clog.x.wake.sbflags = 0xff;
568 	}
569 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
570 	     SCTP_LOG_EVENT_WAKE,
571 	     from,
572 	     sctp_clog.x.misc.log1,
573 	     sctp_clog.x.misc.log2,
574 	     sctp_clog.x.misc.log3,
575 	     sctp_clog.x.misc.log4);
576 #endif
577 }
578 
579 void
sctp_log_block(uint8_t from,struct sctp_association * asoc,ssize_t sendlen)580 sctp_log_block(uint8_t from, struct sctp_association *asoc, ssize_t sendlen)
581 {
582 #if defined(SCTP_LOCAL_TRACE_BUF)
583 	struct sctp_cwnd_log sctp_clog;
584 
585 	sctp_clog.x.blk.onsb = asoc->total_output_queue_size;
586 	sctp_clog.x.blk.send_sent_qcnt = (uint16_t) (asoc->send_queue_cnt + asoc->sent_queue_cnt);
587 	sctp_clog.x.blk.peer_rwnd = asoc->peers_rwnd;
588 	sctp_clog.x.blk.stream_qcnt = (uint16_t) asoc->stream_queue_cnt;
589 	sctp_clog.x.blk.chunks_on_oque = (uint16_t) asoc->chunks_on_out_queue;
590 	sctp_clog.x.blk.flight_size = (uint16_t) (asoc->total_flight/1024);
591 	sctp_clog.x.blk.sndlen = (uint32_t)sendlen;
592 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
593 	     SCTP_LOG_EVENT_BLOCK,
594 	     from,
595 	     sctp_clog.x.misc.log1,
596 	     sctp_clog.x.misc.log2,
597 	     sctp_clog.x.misc.log3,
598 	     sctp_clog.x.misc.log4);
599 #endif
600 }
601 
602 int
sctp_fill_stat_log(void * optval SCTP_UNUSED,size_t * optsize SCTP_UNUSED)603 sctp_fill_stat_log(void *optval SCTP_UNUSED, size_t *optsize SCTP_UNUSED)
604 {
605 	/* May need to fix this if ktrdump does not work */
606 	return (0);
607 }
608 
609 #ifdef SCTP_AUDITING_ENABLED
610 uint8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
611 static int sctp_audit_indx = 0;
612 
613 static
614 void
sctp_print_audit_report(void)615 sctp_print_audit_report(void)
616 {
617 	int i;
618 	int cnt;
619 
620 	cnt = 0;
621 	for (i = sctp_audit_indx; i < SCTP_AUDIT_SIZE; i++) {
622 		if ((sctp_audit_data[i][0] == 0xe0) &&
623 		    (sctp_audit_data[i][1] == 0x01)) {
624 			cnt = 0;
625 			SCTP_PRINTF("\n");
626 		} else if (sctp_audit_data[i][0] == 0xf0) {
627 			cnt = 0;
628 			SCTP_PRINTF("\n");
629 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
630 		    (sctp_audit_data[i][1] == 0x01)) {
631 			SCTP_PRINTF("\n");
632 			cnt = 0;
633 		}
634 		SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
635 			    (uint32_t) sctp_audit_data[i][1]);
636 		cnt++;
637 		if ((cnt % 14) == 0)
638 			SCTP_PRINTF("\n");
639 	}
640 	for (i = 0; i < sctp_audit_indx; i++) {
641 		if ((sctp_audit_data[i][0] == 0xe0) &&
642 		    (sctp_audit_data[i][1] == 0x01)) {
643 			cnt = 0;
644 			SCTP_PRINTF("\n");
645 		} else if (sctp_audit_data[i][0] == 0xf0) {
646 			cnt = 0;
647 			SCTP_PRINTF("\n");
648 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
649 		    (sctp_audit_data[i][1] == 0x01)) {
650 			SCTP_PRINTF("\n");
651 			cnt = 0;
652 		}
653 		SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
654 			    (uint32_t) sctp_audit_data[i][1]);
655 		cnt++;
656 		if ((cnt % 14) == 0)
657 			SCTP_PRINTF("\n");
658 	}
659 	SCTP_PRINTF("\n");
660 }
661 
662 void
sctp_auditing(int from,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net)663 sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
664     struct sctp_nets *net)
665 {
666 	int resend_cnt, tot_out, rep, tot_book_cnt;
667 	struct sctp_nets *lnet;
668 	struct sctp_tmit_chunk *chk;
669 
670 	sctp_audit_data[sctp_audit_indx][0] = 0xAA;
671 	sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
672 	sctp_audit_indx++;
673 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
674 		sctp_audit_indx = 0;
675 	}
676 	if (inp == NULL) {
677 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
678 		sctp_audit_data[sctp_audit_indx][1] = 0x01;
679 		sctp_audit_indx++;
680 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
681 			sctp_audit_indx = 0;
682 		}
683 		return;
684 	}
685 	if (stcb == NULL) {
686 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
687 		sctp_audit_data[sctp_audit_indx][1] = 0x02;
688 		sctp_audit_indx++;
689 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
690 			sctp_audit_indx = 0;
691 		}
692 		return;
693 	}
694 	sctp_audit_data[sctp_audit_indx][0] = 0xA1;
695 	sctp_audit_data[sctp_audit_indx][1] =
696 	    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
697 	sctp_audit_indx++;
698 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
699 		sctp_audit_indx = 0;
700 	}
701 	rep = 0;
702 	tot_book_cnt = 0;
703 	resend_cnt = tot_out = 0;
704 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
705 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
706 			resend_cnt++;
707 		} else if (chk->sent < SCTP_DATAGRAM_RESEND) {
708 			tot_out += chk->book_size;
709 			tot_book_cnt++;
710 		}
711 	}
712 	if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
713 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
714 		sctp_audit_data[sctp_audit_indx][1] = 0xA1;
715 		sctp_audit_indx++;
716 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
717 			sctp_audit_indx = 0;
718 		}
719 		SCTP_PRINTF("resend_cnt:%d asoc-tot:%d\n",
720 			    resend_cnt, stcb->asoc.sent_queue_retran_cnt);
721 		rep = 1;
722 		stcb->asoc.sent_queue_retran_cnt = resend_cnt;
723 		sctp_audit_data[sctp_audit_indx][0] = 0xA2;
724 		sctp_audit_data[sctp_audit_indx][1] =
725 		    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
726 		sctp_audit_indx++;
727 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
728 			sctp_audit_indx = 0;
729 		}
730 	}
731 	if (tot_out != stcb->asoc.total_flight) {
732 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
733 		sctp_audit_data[sctp_audit_indx][1] = 0xA2;
734 		sctp_audit_indx++;
735 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
736 			sctp_audit_indx = 0;
737 		}
738 		rep = 1;
739 		SCTP_PRINTF("tot_flt:%d asoc_tot:%d\n", tot_out,
740 			    (int)stcb->asoc.total_flight);
741 		stcb->asoc.total_flight = tot_out;
742 	}
743 	if (tot_book_cnt != stcb->asoc.total_flight_count) {
744 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
745 		sctp_audit_data[sctp_audit_indx][1] = 0xA5;
746 		sctp_audit_indx++;
747 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
748 			sctp_audit_indx = 0;
749 		}
750 		rep = 1;
751 		SCTP_PRINTF("tot_flt_book:%d\n", tot_book_cnt);
752 
753 		stcb->asoc.total_flight_count = tot_book_cnt;
754 	}
755 	tot_out = 0;
756 	TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
757 		tot_out += lnet->flight_size;
758 	}
759 	if (tot_out != stcb->asoc.total_flight) {
760 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
761 		sctp_audit_data[sctp_audit_indx][1] = 0xA3;
762 		sctp_audit_indx++;
763 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
764 			sctp_audit_indx = 0;
765 		}
766 		rep = 1;
767 		SCTP_PRINTF("real flight:%d net total was %d\n",
768 			    stcb->asoc.total_flight, tot_out);
769 		/* now corrective action */
770 		TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
771 
772 			tot_out = 0;
773 			TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
774 				if ((chk->whoTo == lnet) &&
775 				    (chk->sent < SCTP_DATAGRAM_RESEND)) {
776 					tot_out += chk->book_size;
777 				}
778 			}
779 			if (lnet->flight_size != tot_out) {
780 				SCTP_PRINTF("net:%p flight was %d corrected to %d\n",
781 					    (void *)lnet, lnet->flight_size,
782 					    tot_out);
783 				lnet->flight_size = tot_out;
784 			}
785 		}
786 	}
787 	if (rep) {
788 		sctp_print_audit_report();
789 	}
790 }
791 
792 void
sctp_audit_log(uint8_t ev,uint8_t fd)793 sctp_audit_log(uint8_t ev, uint8_t fd)
794 {
795 
796 	sctp_audit_data[sctp_audit_indx][0] = ev;
797 	sctp_audit_data[sctp_audit_indx][1] = fd;
798 	sctp_audit_indx++;
799 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
800 		sctp_audit_indx = 0;
801 	}
802 }
803 
804 #endif
805 
806 /*
807  * The conversion from time to ticks and vice versa is done by rounding
808  * upwards. This way we can test in the code the time to be positive and
809  * know that this corresponds to a positive number of ticks.
810  */
811 
812 uint32_t
sctp_msecs_to_ticks(uint32_t msecs)813 sctp_msecs_to_ticks(uint32_t msecs)
814 {
815 	uint64_t temp;
816 	uint32_t ticks;
817 
818 	if (hz == 1000) {
819 		ticks = msecs;
820 	} else {
821 		temp = (((uint64_t)msecs * hz) + 999) / 1000;
822 		if (temp > UINT32_MAX) {
823 			ticks = UINT32_MAX;
824 		} else {
825 			ticks = (uint32_t)temp;
826 		}
827 	}
828 	return (ticks);
829 }
830 
831 uint32_t
sctp_ticks_to_msecs(uint32_t ticks)832 sctp_ticks_to_msecs(uint32_t ticks)
833 {
834 	uint64_t temp;
835 	uint32_t msecs;
836 
837 	if (hz == 1000) {
838 		msecs = ticks;
839 	} else {
840 		temp = (((uint64_t)ticks * 1000) + (hz - 1)) / hz;
841 		if (temp > UINT32_MAX) {
842 			msecs = UINT32_MAX;
843 		} else {
844 			msecs = (uint32_t)temp;
845 		}
846 	}
847 	return (msecs);
848 }
849 
850 uint32_t
sctp_secs_to_ticks(uint32_t secs)851 sctp_secs_to_ticks(uint32_t secs)
852 {
853 	uint64_t temp;
854 	uint32_t ticks;
855 
856 	temp = (uint64_t)secs * hz;
857 	if (temp > UINT32_MAX) {
858 		ticks = UINT32_MAX;
859 	} else {
860 		ticks = (uint32_t)temp;
861 	}
862 	return (ticks);
863 }
864 
865 uint32_t
sctp_ticks_to_secs(uint32_t ticks)866 sctp_ticks_to_secs(uint32_t ticks)
867 {
868 	uint64_t temp;
869 	uint32_t secs;
870 
871 	temp = ((uint64_t)ticks + (hz - 1)) / hz;
872 	if (temp > UINT32_MAX) {
873 		secs = UINT32_MAX;
874 	} else {
875 		secs = (uint32_t)temp;
876 	}
877 	return (secs);
878 }
879 
880 /*
881  * sctp_stop_timers_for_shutdown() should be called
882  * when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT
883  * state to make sure that all timers are stopped.
884  */
885 void
sctp_stop_timers_for_shutdown(struct sctp_tcb * stcb)886 sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
887 {
888 	struct sctp_inpcb *inp;
889 	struct sctp_nets *net;
890 
891 	inp = stcb->sctp_ep;
892 
893 	sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
894 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_12);
895 	sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
896 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_13);
897 	sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
898 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_14);
899 	sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
900 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_15);
901 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
902 		sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
903 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_16);
904 		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
905 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_17);
906 	}
907 }
908 
909 void
sctp_stop_association_timers(struct sctp_tcb * stcb,bool stop_assoc_kill_timer)910 sctp_stop_association_timers(struct sctp_tcb *stcb, bool stop_assoc_kill_timer)
911 {
912 	struct sctp_inpcb *inp;
913 	struct sctp_nets *net;
914 
915 	inp = stcb->sctp_ep;
916 	sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
917 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_18);
918 	sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
919 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_19);
920 	if (stop_assoc_kill_timer) {
921 		sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
922 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_20);
923 	}
924 	sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
925 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_21);
926 	sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
927 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_22);
928 	sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNGUARD, inp, stcb, NULL,
929 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_23);
930 	/* Mobility adaptation */
931 	sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, inp, stcb, NULL,
932 	                SCTP_FROM_SCTPUTIL + SCTP_LOC_24);
933 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
934 		sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
935 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_25);
936 		sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
937 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_26);
938 		sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, net,
939 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_27);
940 		sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net,
941 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_28);
942 		sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, net,
943 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_29);
944 		sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
945 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_30);
946 		sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
947 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_31);
948 	}
949 }
950 
951 /*
952  * A list of sizes based on typical mtu's, used only if next hop size not
953  * returned. These values MUST be multiples of 4 and MUST be ordered.
954  */
955 static uint32_t sctp_mtu_sizes[] = {
956 	68,
957 	296,
958 	508,
959 	512,
960 	544,
961 	576,
962 	1004,
963 	1492,
964 	1500,
965 	1536,
966 	2000,
967 	2048,
968 	4352,
969 	4464,
970 	8168,
971 	17912,
972 	32000,
973 	65532
974 };
975 
976 /*
977  * Return the largest MTU in sctp_mtu_sizes smaller than val.
978  * If val is smaller than the minimum, just return the largest
979  * multiple of 4 smaller or equal to val.
980  * Ensure that the result is a multiple of 4.
981  */
982 uint32_t
sctp_get_prev_mtu(uint32_t val)983 sctp_get_prev_mtu(uint32_t val)
984 {
985 	uint32_t i;
986 
987 	val &= 0xfffffffc;
988 	if (val <= sctp_mtu_sizes[0]) {
989 		return (val);
990 	}
991 	for (i = 1; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) {
992 		if (val <= sctp_mtu_sizes[i]) {
993 			break;
994 		}
995 	}
996 	KASSERT((sctp_mtu_sizes[i - 1] & 0x00000003) == 0,
997 	        ("sctp_mtu_sizes[%u] not a multiple of 4", i - 1));
998 	return (sctp_mtu_sizes[i - 1]);
999 }
1000 
1001 /*
1002  * Return the smallest MTU in sctp_mtu_sizes larger than val.
1003  * If val is larger than the maximum, just return the largest multiple of 4 smaller
1004  * or equal to val.
1005  * Ensure that the result is a multiple of 4.
1006  */
1007 uint32_t
sctp_get_next_mtu(uint32_t val)1008 sctp_get_next_mtu(uint32_t val)
1009 {
1010 	/* select another MTU that is just bigger than this one */
1011 	uint32_t i;
1012 
1013 	val &= 0xfffffffc;
1014 	for (i = 0; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) {
1015 		if (val < sctp_mtu_sizes[i]) {
1016 			KASSERT((sctp_mtu_sizes[i] & 0x00000003) == 0,
1017 				("sctp_mtu_sizes[%u] not a multiple of 4", i));
1018 			return (sctp_mtu_sizes[i]);
1019 		}
1020 	}
1021 	return (val);
1022 }
1023 
1024 void
sctp_fill_random_store(struct sctp_pcb * m)1025 sctp_fill_random_store(struct sctp_pcb *m)
1026 {
1027 	/*
1028 	 * Here we use the MD5/SHA-1 to hash with our good randomNumbers and
1029 	 * our counter. The result becomes our good random numbers and we
1030 	 * then setup to give these out. Note that we do no locking to
1031 	 * protect this. This is ok, since if competing folks call this we
1032 	 * will get more gobbled gook in the random store which is what we
1033 	 * want. There is a danger that two guys will use the same random
1034 	 * numbers, but thats ok too since that is random as well :->
1035 	 */
1036 	m->store_at = 0;
1037 #if defined(__Userspace__) && defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
1038 	for (int i = 0; i < (int) (sizeof(m->random_store) / sizeof(m->random_store[0])); i++) {
1039 		m->random_store[i] = (uint8_t) rand();
1040 	}
1041 #else
1042 	(void)sctp_hmac(SCTP_HMAC, (uint8_t *)m->random_numbers,
1043 	    sizeof(m->random_numbers), (uint8_t *)&m->random_counter,
1044 	    sizeof(m->random_counter), (uint8_t *)m->random_store);
1045 #endif
1046 	m->random_counter++;
1047 }
1048 
1049 uint32_t
sctp_select_initial_TSN(struct sctp_pcb * inp)1050 sctp_select_initial_TSN(struct sctp_pcb *inp)
1051 {
1052 	/*
1053 	 * A true implementation should use random selection process to get
1054 	 * the initial stream sequence number, using RFC1750 as a good
1055 	 * guideline
1056 	 */
1057 	uint32_t x, *xp;
1058 	uint8_t *p;
1059 	int store_at, new_store;
1060 
1061 	if (inp->initial_sequence_debug != 0) {
1062 		uint32_t ret;
1063 
1064 		ret = inp->initial_sequence_debug;
1065 		inp->initial_sequence_debug++;
1066 		return (ret);
1067 	}
1068  retry:
1069 	store_at = inp->store_at;
1070 	new_store = store_at + sizeof(uint32_t);
1071 	if (new_store >= (SCTP_SIGNATURE_SIZE-3)) {
1072 		new_store = 0;
1073 	}
1074 	if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) {
1075 		goto retry;
1076 	}
1077 	if (new_store == 0) {
1078 		/* Refill the random store */
1079 		sctp_fill_random_store(inp);
1080 	}
1081 	p = &inp->random_store[store_at];
1082 	xp = (uint32_t *)p;
1083 	x = *xp;
1084 	return (x);
1085 }
1086 
1087 uint32_t
sctp_select_a_tag(struct sctp_inpcb * inp,uint16_t lport,uint16_t rport,int check)1088 sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check)
1089 {
1090 	uint32_t x;
1091 	struct timeval now;
1092 
1093 	if (check) {
1094 		(void)SCTP_GETTIME_TIMEVAL(&now);
1095 	}
1096 	for (;;) {
1097 		x = sctp_select_initial_TSN(&inp->sctp_ep);
1098 		if (x == 0) {
1099 			/* we never use 0 */
1100 			continue;
1101 		}
1102 		if (!check || sctp_is_vtag_good(x, lport, rport, &now)) {
1103 			break;
1104 		}
1105 	}
1106 	return (x);
1107 }
1108 
1109 int32_t
sctp_map_assoc_state(int kernel_state)1110 sctp_map_assoc_state(int kernel_state)
1111 {
1112 	int32_t user_state;
1113 
1114 	if (kernel_state & SCTP_STATE_WAS_ABORTED) {
1115 		user_state = SCTP_CLOSED;
1116 	} else if (kernel_state & SCTP_STATE_SHUTDOWN_PENDING) {
1117 		user_state = SCTP_SHUTDOWN_PENDING;
1118 	} else {
1119 		switch (kernel_state & SCTP_STATE_MASK) {
1120 		case SCTP_STATE_EMPTY:
1121 			user_state = SCTP_CLOSED;
1122 			break;
1123 		case SCTP_STATE_INUSE:
1124 			user_state = SCTP_CLOSED;
1125 			break;
1126 		case SCTP_STATE_COOKIE_WAIT:
1127 			user_state = SCTP_COOKIE_WAIT;
1128 			break;
1129 		case SCTP_STATE_COOKIE_ECHOED:
1130 			user_state = SCTP_COOKIE_ECHOED;
1131 			break;
1132 		case SCTP_STATE_OPEN:
1133 			user_state = SCTP_ESTABLISHED;
1134 			break;
1135 		case SCTP_STATE_SHUTDOWN_SENT:
1136 			user_state = SCTP_SHUTDOWN_SENT;
1137 			break;
1138 		case SCTP_STATE_SHUTDOWN_RECEIVED:
1139 			user_state = SCTP_SHUTDOWN_RECEIVED;
1140 			break;
1141 		case SCTP_STATE_SHUTDOWN_ACK_SENT:
1142 			user_state = SCTP_SHUTDOWN_ACK_SENT;
1143 			break;
1144 		default:
1145 			user_state = SCTP_CLOSED;
1146 			break;
1147 		}
1148 	}
1149 	return (user_state);
1150 }
1151 
1152 int
sctp_init_asoc(struct sctp_inpcb * inp,struct sctp_tcb * stcb,uint32_t override_tag,uint32_t vrf_id,uint16_t o_strms)1153 sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1154                uint32_t override_tag, uint32_t vrf_id, uint16_t o_strms)
1155 {
1156 	struct sctp_association *asoc;
1157 	/*
1158 	 * Anything set to zero is taken care of by the allocation routine's
1159 	 * bzero
1160 	 */
1161 
1162 	/*
1163 	 * Up front select what scoping to apply on addresses I tell my peer
1164 	 * Not sure what to do with these right now, we will need to come up
1165 	 * with a way to set them. We may need to pass them through from the
1166 	 * caller in the sctp_aloc_assoc() function.
1167 	 */
1168 	int i;
1169 #if defined(SCTP_DETAILED_STR_STATS)
1170 	int j;
1171 #endif
1172 
1173 	asoc = &stcb->asoc;
1174 	/* init all variables to a known value. */
1175 	SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
1176 	asoc->max_burst = inp->sctp_ep.max_burst;
1177 	asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
1178 	asoc->heart_beat_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
1179 	asoc->cookie_life = inp->sctp_ep.def_cookie_life;
1180 	asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
1181 	asoc->ecn_supported = inp->ecn_supported;
1182 	asoc->prsctp_supported = inp->prsctp_supported;
1183 	asoc->auth_supported = inp->auth_supported;
1184 	asoc->asconf_supported = inp->asconf_supported;
1185 	asoc->reconfig_supported = inp->reconfig_supported;
1186 	asoc->nrsack_supported = inp->nrsack_supported;
1187 	asoc->pktdrop_supported = inp->pktdrop_supported;
1188 	asoc->idata_supported = inp->idata_supported;
1189 	asoc->sctp_cmt_pf = (uint8_t)0;
1190 	asoc->sctp_frag_point = inp->sctp_frag_point;
1191 	asoc->sctp_features = inp->sctp_features;
1192 	asoc->default_dscp = inp->sctp_ep.default_dscp;
1193 	asoc->max_cwnd = inp->max_cwnd;
1194 #ifdef INET6
1195 	if (inp->sctp_ep.default_flowlabel) {
1196 		asoc->default_flowlabel = inp->sctp_ep.default_flowlabel;
1197 	} else {
1198 		if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
1199 			asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep);
1200 			asoc->default_flowlabel &= 0x000fffff;
1201 			asoc->default_flowlabel |= 0x80000000;
1202 		} else {
1203 			asoc->default_flowlabel = 0;
1204 		}
1205 	}
1206 #endif
1207 	asoc->sb_send_resv = 0;
1208 	if (override_tag) {
1209 		asoc->my_vtag = override_tag;
1210 	} else {
1211 		asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport,  1);
1212 	}
1213 	/* Get the nonce tags */
1214 	asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1215 	asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1216 	asoc->vrf_id = vrf_id;
1217 
1218 #ifdef SCTP_ASOCLOG_OF_TSNS
1219 	asoc->tsn_in_at = 0;
1220 	asoc->tsn_out_at = 0;
1221 	asoc->tsn_in_wrapped = 0;
1222 	asoc->tsn_out_wrapped = 0;
1223 	asoc->cumack_log_at = 0;
1224 	asoc->cumack_log_atsnt = 0;
1225 #endif
1226 #ifdef SCTP_FS_SPEC_LOG
1227 	asoc->fs_index = 0;
1228 #endif
1229 	asoc->refcnt = 0;
1230 	asoc->assoc_up_sent = 0;
1231 	asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
1232 	    sctp_select_initial_TSN(&inp->sctp_ep);
1233 	asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
1234 	/* we are optimisitic here */
1235 	asoc->peer_supports_nat = 0;
1236 	asoc->sent_queue_retran_cnt = 0;
1237 
1238 	/* for CMT */
1239         asoc->last_net_cmt_send_started = NULL;
1240 
1241 	/* This will need to be adjusted */
1242 	asoc->last_acked_seq = asoc->init_seq_number - 1;
1243 	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
1244 	asoc->asconf_seq_in = asoc->last_acked_seq;
1245 
1246 	/* here we are different, we hold the next one we expect */
1247 	asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
1248 
1249 	asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max;
1250 	asoc->initial_rto = inp->sctp_ep.initial_rto;
1251 
1252 	asoc->default_mtu = inp->sctp_ep.default_mtu;
1253 	asoc->max_init_times = inp->sctp_ep.max_init_times;
1254 	asoc->max_send_times = inp->sctp_ep.max_send_times;
1255 	asoc->def_net_failure = inp->sctp_ep.def_net_failure;
1256 	asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold;
1257 	asoc->free_chunk_cnt = 0;
1258 
1259 	asoc->iam_blocking = 0;
1260 	asoc->context = inp->sctp_context;
1261 	asoc->local_strreset_support = inp->local_strreset_support;
1262 	asoc->def_send = inp->def_send;
1263 	asoc->delayed_ack = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1264 	asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
1265 	asoc->pr_sctp_cnt = 0;
1266 	asoc->total_output_queue_size = 0;
1267 
1268 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1269 		asoc->scope.ipv6_addr_legal = 1;
1270 		if (SCTP_IPV6_V6ONLY(inp) == 0) {
1271 			asoc->scope.ipv4_addr_legal = 1;
1272 		} else {
1273 			asoc->scope.ipv4_addr_legal = 0;
1274 		}
1275 #if defined(__Userspace__)
1276 			asoc->scope.conn_addr_legal = 0;
1277 #endif
1278 	} else {
1279 		asoc->scope.ipv6_addr_legal = 0;
1280 #if defined(__Userspace__)
1281 		if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
1282 			asoc->scope.conn_addr_legal = 1;
1283 			asoc->scope.ipv4_addr_legal = 0;
1284 		} else {
1285 			asoc->scope.conn_addr_legal = 0;
1286 			asoc->scope.ipv4_addr_legal = 1;
1287 		}
1288 #else
1289 		asoc->scope.ipv4_addr_legal = 1;
1290 #endif
1291 	}
1292 
1293 	asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND);
1294 	asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket);
1295 
1296 	asoc->smallest_mtu = inp->sctp_frag_point;
1297 	asoc->minrto = inp->sctp_ep.sctp_minrto;
1298 	asoc->maxrto = inp->sctp_ep.sctp_maxrto;
1299 
1300 	asoc->stream_locked_on = 0;
1301 	asoc->ecn_echo_cnt_onq = 0;
1302 	asoc->stream_locked = 0;
1303 
1304 	asoc->send_sack = 1;
1305 
1306 	LIST_INIT(&asoc->sctp_restricted_addrs);
1307 
1308 	TAILQ_INIT(&asoc->nets);
1309 	TAILQ_INIT(&asoc->pending_reply_queue);
1310 	TAILQ_INIT(&asoc->asconf_ack_sent);
1311 	/* Setup to fill the hb random cache at first HB */
1312 	asoc->hb_random_idx = 4;
1313 
1314 	asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time;
1315 
1316 	stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module;
1317 	stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module];
1318 
1319 	stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module;
1320 	stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module];
1321 
1322 	/*
1323 	 * Now the stream parameters, here we allocate space for all streams
1324 	 * that we request by default.
1325 	 */
1326 	asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
1327 	    o_strms;
1328 	SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
1329 		    asoc->streamoutcnt * sizeof(struct sctp_stream_out),
1330 		    SCTP_M_STRMO);
1331 	if (asoc->strmout == NULL) {
1332 		/* big trouble no memory */
1333 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1334 		return (ENOMEM);
1335 	}
1336 	for (i = 0; i < asoc->streamoutcnt; i++) {
1337 		/*
1338 		 * inbound side must be set to 0xffff, also NOTE when we get
1339 		 * the INIT-ACK back (for INIT sender) we MUST reduce the
1340 		 * count (streamoutcnt) but first check if we sent to any of
1341 		 * the upper streams that were dropped (if some were). Those
1342 		 * that were dropped must be notified to the upper layer as
1343 		 * failed to send.
1344 		 */
1345 		asoc->strmout[i].next_mid_ordered = 0;
1346 		asoc->strmout[i].next_mid_unordered = 0;
1347 		TAILQ_INIT(&asoc->strmout[i].outqueue);
1348 		asoc->strmout[i].chunks_on_queues = 0;
1349 #if defined(SCTP_DETAILED_STR_STATS)
1350 		for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
1351 			asoc->strmout[i].abandoned_sent[j] = 0;
1352 			asoc->strmout[i].abandoned_unsent[j] = 0;
1353 		}
1354 #else
1355 		asoc->strmout[i].abandoned_sent[0] = 0;
1356 		asoc->strmout[i].abandoned_unsent[0] = 0;
1357 #endif
1358 		asoc->strmout[i].sid = i;
1359 		asoc->strmout[i].last_msg_incomplete = 0;
1360 		asoc->strmout[i].state = SCTP_STREAM_OPENING;
1361 		asoc->ss_functions.sctp_ss_init_stream(stcb, &asoc->strmout[i], NULL);
1362 	}
1363 	asoc->ss_functions.sctp_ss_init(stcb, asoc, 0);
1364 
1365 	/* Now the mapping array */
1366 	asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
1367 	SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1368 		    SCTP_M_MAP);
1369 	if (asoc->mapping_array == NULL) {
1370 		SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1371 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1372 		return (ENOMEM);
1373 	}
1374 	memset(asoc->mapping_array, 0, asoc->mapping_array_size);
1375 	SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
1376 	    SCTP_M_MAP);
1377 	if (asoc->nr_mapping_array == NULL) {
1378 		SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1379 		SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1380 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1381 		return (ENOMEM);
1382 	}
1383 	memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
1384 
1385 	/* Now the init of the other outqueues */
1386 	TAILQ_INIT(&asoc->free_chunks);
1387 	TAILQ_INIT(&asoc->control_send_queue);
1388 	TAILQ_INIT(&asoc->asconf_send_queue);
1389 	TAILQ_INIT(&asoc->send_queue);
1390 	TAILQ_INIT(&asoc->sent_queue);
1391 	TAILQ_INIT(&asoc->resetHead);
1392 	asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome;
1393 	TAILQ_INIT(&asoc->asconf_queue);
1394 	/* authentication fields */
1395 	asoc->authinfo.random = NULL;
1396 	asoc->authinfo.active_keyid = 0;
1397 	asoc->authinfo.assoc_key = NULL;
1398 	asoc->authinfo.assoc_keyid = 0;
1399 	asoc->authinfo.recv_key = NULL;
1400 	asoc->authinfo.recv_keyid = 0;
1401 	LIST_INIT(&asoc->shared_keys);
1402 	asoc->marked_retrans = 0;
1403 	asoc->port = inp->sctp_ep.port;
1404 	asoc->timoinit = 0;
1405 	asoc->timodata = 0;
1406 	asoc->timosack = 0;
1407 	asoc->timoshutdown = 0;
1408 	asoc->timoheartbeat = 0;
1409 	asoc->timocookie = 0;
1410 	asoc->timoshutdownack = 0;
1411 	(void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
1412 	asoc->discontinuity_time = asoc->start_time;
1413 	for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
1414 		asoc->abandoned_unsent[i] = 0;
1415 		asoc->abandoned_sent[i] = 0;
1416 	}
1417 	/* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
1418 	 * the association is freed.
1419 	 */
1420 	return (0);
1421 }
1422 
1423 void
sctp_print_mapping_array(struct sctp_association * asoc)1424 sctp_print_mapping_array(struct sctp_association *asoc)
1425 {
1426 	unsigned int i, limit;
1427 
1428 	SCTP_PRINTF("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n",
1429 	            asoc->mapping_array_size,
1430 	            asoc->mapping_array_base_tsn,
1431 	            asoc->cumulative_tsn,
1432 	            asoc->highest_tsn_inside_map,
1433 	            asoc->highest_tsn_inside_nr_map);
1434 	for (limit = asoc->mapping_array_size; limit > 1; limit--) {
1435 		if (asoc->mapping_array[limit - 1] != 0) {
1436 			break;
1437 		}
1438 	}
1439 	SCTP_PRINTF("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
1440 	for (i = 0; i < limit; i++) {
1441 		SCTP_PRINTF("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
1442 	}
1443 	if (limit % 16)
1444 		SCTP_PRINTF("\n");
1445 	for (limit = asoc->mapping_array_size; limit > 1; limit--) {
1446 		if (asoc->nr_mapping_array[limit - 1]) {
1447 			break;
1448 		}
1449 	}
1450 	SCTP_PRINTF("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
1451 	for (i = 0; i < limit; i++) {
1452 		SCTP_PRINTF("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ': '\n');
1453 	}
1454 	if (limit % 16)
1455 		SCTP_PRINTF("\n");
1456 }
1457 
1458 int
sctp_expand_mapping_array(struct sctp_association * asoc,uint32_t needed)1459 sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
1460 {
1461 	/* mapping array needs to grow */
1462 	uint8_t *new_array1, *new_array2;
1463 	uint32_t new_size;
1464 
1465 	new_size = asoc->mapping_array_size + ((needed+7)/8 + SCTP_MAPPING_ARRAY_INCR);
1466 	SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
1467 	SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
1468 	if ((new_array1 == NULL) || (new_array2 == NULL)) {
1469 		/* can't get more, forget it */
1470 		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size);
1471 		if (new_array1) {
1472 			SCTP_FREE(new_array1, SCTP_M_MAP);
1473 		}
1474 		if (new_array2) {
1475 			SCTP_FREE(new_array2, SCTP_M_MAP);
1476 		}
1477 		return (-1);
1478 	}
1479 	memset(new_array1, 0, new_size);
1480 	memset(new_array2, 0, new_size);
1481 	memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
1482 	memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
1483 	SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1484 	SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
1485 	asoc->mapping_array = new_array1;
1486 	asoc->nr_mapping_array = new_array2;
1487 	asoc->mapping_array_size = new_size;
1488 	return (0);
1489 }
1490 
1491 
1492 static void
sctp_iterator_work(struct sctp_iterator * it)1493 sctp_iterator_work(struct sctp_iterator *it)
1494 {
1495 #if defined(__FreeBSD__)
1496 	struct epoch_tracker et;
1497 #endif
1498 	struct sctp_inpcb *tinp;
1499 	int iteration_count = 0;
1500 	int inp_skip = 0;
1501 	int first_in = 1;
1502 
1503 #if defined(__FreeBSD__)
1504 	NET_EPOCH_ENTER(et);
1505 #endif
1506 	SCTP_INP_INFO_RLOCK();
1507 	SCTP_ITERATOR_LOCK();
1508 	sctp_it_ctl.cur_it = it;
1509 	if (it->inp) {
1510 		SCTP_INP_RLOCK(it->inp);
1511 		SCTP_INP_DECR_REF(it->inp);
1512 	}
1513 	if (it->inp == NULL) {
1514 		/* iterator is complete */
1515 done_with_iterator:
1516 		sctp_it_ctl.cur_it = NULL;
1517 		SCTP_ITERATOR_UNLOCK();
1518 		SCTP_INP_INFO_RUNLOCK();
1519 		if (it->function_atend != NULL) {
1520 			(*it->function_atend) (it->pointer, it->val);
1521 		}
1522 		SCTP_FREE(it, SCTP_M_ITER);
1523 #if defined(__FreeBSD__)
1524 		NET_EPOCH_EXIT(et);
1525 #endif
1526 		return;
1527 	}
1528 select_a_new_ep:
1529 	if (first_in) {
1530 		first_in = 0;
1531 	} else {
1532 		SCTP_INP_RLOCK(it->inp);
1533 	}
1534 	while (((it->pcb_flags) &&
1535 	        ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) ||
1536 	       ((it->pcb_features) &&
1537 		((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) {
1538 		/* endpoint flags or features don't match, so keep looking */
1539 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1540 			SCTP_INP_RUNLOCK(it->inp);
1541 			goto done_with_iterator;
1542 		}
1543 		tinp = it->inp;
1544 		it->inp = LIST_NEXT(it->inp, sctp_list);
1545 		it->stcb = NULL;
1546 		SCTP_INP_RUNLOCK(tinp);
1547 		if (it->inp == NULL) {
1548 			goto done_with_iterator;
1549 		}
1550 		SCTP_INP_RLOCK(it->inp);
1551 	}
1552 	/* now go through each assoc which is in the desired state */
1553 	if (it->done_current_ep == 0) {
1554 		if (it->function_inp != NULL)
1555 			inp_skip = (*it->function_inp)(it->inp, it->pointer, it->val);
1556 		it->done_current_ep = 1;
1557 	}
1558 	if (it->stcb == NULL) {
1559 		/* run the per instance function */
1560 		it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
1561 	}
1562 	if ((inp_skip) || it->stcb == NULL) {
1563 		if (it->function_inp_end != NULL) {
1564 			inp_skip = (*it->function_inp_end)(it->inp,
1565 							   it->pointer,
1566 							   it->val);
1567 		}
1568 		SCTP_INP_RUNLOCK(it->inp);
1569 		goto no_stcb;
1570 	}
1571 	while (it->stcb) {
1572 		SCTP_TCB_LOCK(it->stcb);
1573 		if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
1574 			/* not in the right state... keep looking */
1575 			SCTP_TCB_UNLOCK(it->stcb);
1576 			goto next_assoc;
1577 		}
1578 		/* see if we have limited out the iterator loop */
1579 		iteration_count++;
1580 		if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) {
1581 			/* Pause to let others grab the lock */
1582 			atomic_add_int(&it->stcb->asoc.refcnt, 1);
1583 			SCTP_TCB_UNLOCK(it->stcb);
1584 			SCTP_INP_INCR_REF(it->inp);
1585 			SCTP_INP_RUNLOCK(it->inp);
1586 			SCTP_ITERATOR_UNLOCK();
1587 			SCTP_INP_INFO_RUNLOCK();
1588 			SCTP_INP_INFO_RLOCK();
1589 			SCTP_ITERATOR_LOCK();
1590 			if (sctp_it_ctl.iterator_flags) {
1591 				/* We won't be staying here */
1592 				SCTP_INP_DECR_REF(it->inp);
1593 				atomic_add_int(&it->stcb->asoc.refcnt, -1);
1594 #if !defined(__FreeBSD__)
1595 				if (sctp_it_ctl.iterator_flags &
1596 				   SCTP_ITERATOR_MUST_EXIT) {
1597 					goto done_with_iterator;
1598 				}
1599 #endif
1600 				if (sctp_it_ctl.iterator_flags &
1601 				   SCTP_ITERATOR_STOP_CUR_IT) {
1602 					sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_IT;
1603 					goto done_with_iterator;
1604 				}
1605 				if (sctp_it_ctl.iterator_flags &
1606 				   SCTP_ITERATOR_STOP_CUR_INP) {
1607 					sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_INP;
1608 					goto no_stcb;
1609 				}
1610 				/* If we reach here huh? */
1611 				SCTP_PRINTF("Unknown it ctl flag %x\n",
1612 					    sctp_it_ctl.iterator_flags);
1613 				sctp_it_ctl.iterator_flags = 0;
1614 			}
1615 			SCTP_INP_RLOCK(it->inp);
1616 			SCTP_INP_DECR_REF(it->inp);
1617 			SCTP_TCB_LOCK(it->stcb);
1618 			atomic_add_int(&it->stcb->asoc.refcnt, -1);
1619 			iteration_count = 0;
1620 		}
1621 		KASSERT(it->inp == it->stcb->sctp_ep,
1622 		        ("%s: stcb %p does not belong to inp %p, but inp %p",
1623 		         __func__, it->stcb, it->inp, it->stcb->sctp_ep));
1624 
1625 		/* run function on this one */
1626 		(*it->function_assoc)(it->inp, it->stcb, it->pointer, it->val);
1627 
1628 		/*
1629 		 * we lie here, it really needs to have its own type but
1630 		 * first I must verify that this won't effect things :-0
1631 		 */
1632 		if (it->no_chunk_output == 0)
1633 			sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1634 
1635 		SCTP_TCB_UNLOCK(it->stcb);
1636 	next_assoc:
1637 		it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1638 		if (it->stcb == NULL) {
1639 			/* Run last function */
1640 			if (it->function_inp_end != NULL) {
1641 				inp_skip = (*it->function_inp_end)(it->inp,
1642 								   it->pointer,
1643 								   it->val);
1644 			}
1645 		}
1646 	}
1647 	SCTP_INP_RUNLOCK(it->inp);
1648  no_stcb:
1649 	/* done with all assocs on this endpoint, move on to next endpoint */
1650 	it->done_current_ep = 0;
1651 	if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1652 		it->inp = NULL;
1653 	} else {
1654 		it->inp = LIST_NEXT(it->inp, sctp_list);
1655 	}
1656 	it->stcb = NULL;
1657 	if (it->inp == NULL) {
1658 		goto done_with_iterator;
1659 	}
1660 	goto select_a_new_ep;
1661 }
1662 
1663 void
sctp_iterator_worker(void)1664 sctp_iterator_worker(void)
1665 {
1666 	struct sctp_iterator *it;
1667 
1668 	/* This function is called with the WQ lock in place */
1669 	sctp_it_ctl.iterator_running = 1;
1670 	while ((it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead)) != NULL) {
1671 		/* now lets work on this one */
1672 		TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
1673 		SCTP_IPI_ITERATOR_WQ_UNLOCK();
1674 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1675 		CURVNET_SET(it->vn);
1676 #endif
1677 		sctp_iterator_work(it);
1678 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1679 		CURVNET_RESTORE();
1680 #endif
1681 		SCTP_IPI_ITERATOR_WQ_LOCK();
1682 #if !defined(__FreeBSD__)
1683 		if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
1684 			break;
1685 		}
1686 #endif
1687 		/*sa_ignore FREED_MEMORY*/
1688 	}
1689 	sctp_it_ctl.iterator_running = 0;
1690 	return;
1691 }
1692 
1693 
1694 static void
sctp_handle_addr_wq(void)1695 sctp_handle_addr_wq(void)
1696 {
1697 	/* deal with the ADDR wq from the rtsock calls */
1698 	struct sctp_laddr *wi, *nwi;
1699 	struct sctp_asconf_iterator *asc;
1700 
1701 	SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
1702 		    sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT);
1703 	if (asc == NULL) {
1704 		/* Try later, no memory */
1705 		sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
1706 				 (struct sctp_inpcb *)NULL,
1707 				 (struct sctp_tcb *)NULL,
1708 				 (struct sctp_nets *)NULL);
1709 		return;
1710 	}
1711 	LIST_INIT(&asc->list_of_work);
1712 	asc->cnt = 0;
1713 
1714 	LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
1715 		LIST_REMOVE(wi, sctp_nxt_addr);
1716 		LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
1717 		asc->cnt++;
1718 	}
1719 
1720 	if (asc->cnt == 0) {
1721 		SCTP_FREE(asc, SCTP_M_ASC_IT);
1722 	} else {
1723 		int ret;
1724 
1725 		ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
1726 		                             sctp_asconf_iterator_stcb,
1727 		                             NULL, /* No ep end for boundall */
1728 		                             SCTP_PCB_FLAGS_BOUNDALL,
1729 		                             SCTP_PCB_ANY_FEATURES,
1730 		                             SCTP_ASOC_ANY_STATE,
1731 		                             (void *)asc, 0,
1732 		                             sctp_asconf_iterator_end, NULL, 0);
1733 		if (ret) {
1734 			SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n");
1735 			/* Freeing if we are stopping or put back on the addr_wq. */
1736 			if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
1737 				sctp_asconf_iterator_end(asc, 0);
1738 			} else {
1739 				LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) {
1740 					LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
1741 				}
1742 				SCTP_FREE(asc, SCTP_M_ASC_IT);
1743 			}
1744 		}
1745 	}
1746 }
1747 
1748 /*-
1749  * The following table shows which pointers for the inp, stcb, or net are
1750  * stored for each timer after it was started.
1751  *
1752  *|Name                         |Timer                        |inp |stcb|net |
1753  *|-----------------------------|-----------------------------|----|----|----|
1754  *|SCTP_TIMER_TYPE_SEND         |net->rxt_timer               |Yes |Yes |Yes |
1755  *|SCTP_TIMER_TYPE_INIT         |net->rxt_timer               |Yes |Yes |Yes |
1756  *|SCTP_TIMER_TYPE_RECV         |stcb->asoc.dack_timer        |Yes |Yes |No  |
1757  *|SCTP_TIMER_TYPE_SHUTDOWN     |net->rxt_timer               |Yes |Yes |Yes |
1758  *|SCTP_TIMER_TYPE_HEARTBEAT    |net->hb_timer                |Yes |Yes |Yes |
1759  *|SCTP_TIMER_TYPE_COOKIE       |net->rxt_timer               |Yes |Yes |Yes |
1760  *|SCTP_TIMER_TYPE_NEWCOOKIE    |inp->sctp_ep.signature_change|Yes |No  |No  |
1761  *|SCTP_TIMER_TYPE_PATHMTURAISE |net->pmtu_timer              |Yes |Yes |Yes |
1762  *|SCTP_TIMER_TYPE_SHUTDOWNACK  |net->rxt_timer               |Yes |Yes |Yes |
1763  *|SCTP_TIMER_TYPE_ASCONF       |stcb->asoc.asconf_timer      |Yes |Yes |Yes |
1764  *|SCTP_TIMER_TYPE_SHUTDOWNGUARD|stcb->asoc.shut_guard_timer  |Yes |Yes |No  |
1765  *|SCTP_TIMER_TYPE_AUTOCLOSE    |stcb->asoc.autoclose_timer   |Yes |Yes |No  |
1766  *|SCTP_TIMER_TYPE_STRRESET     |stcb->asoc.strreset_timer    |Yes |Yes |No  |
1767  *|SCTP_TIMER_TYPE_INPKILL      |inp->sctp_ep.signature_change|Yes |No  |No  |
1768  *|SCTP_TIMER_TYPE_ASOCKILL     |stcb->asoc.strreset_timer    |Yes |Yes |No  |
1769  *|SCTP_TIMER_TYPE_ADDR_WQ      |SCTP_BASE_INFO(addr_wq_timer)|No  |No  |No  |
1770  *|SCTP_TIMER_TYPE_PRIM_DELETED |stcb->asoc.delete_prim_timer |Yes |Yes |No  |
1771  */
1772 
1773 void
sctp_timeout_handler(void * t)1774 sctp_timeout_handler(void *t)
1775 {
1776 #if defined(__FreeBSD__)
1777 	struct epoch_tracker et;
1778 #endif
1779 	struct timeval tv;
1780 	struct sctp_inpcb *inp;
1781 	struct sctp_tcb *stcb;
1782 	struct sctp_nets *net;
1783 	struct sctp_timer *tmr;
1784 	struct mbuf *op_err;
1785 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1786 	struct socket *so;
1787 #endif
1788 #if defined(__Userspace__)
1789 	struct socket *upcall_socket = NULL;
1790 #endif
1791 	int did_output;
1792 	int type;
1793 	int i, secret;
1794 
1795 	tmr = (struct sctp_timer *)t;
1796 	inp = (struct sctp_inpcb *)tmr->ep;
1797 	stcb = (struct sctp_tcb *)tmr->tcb;
1798 	net = (struct sctp_nets *)tmr->net;
1799 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1800 	CURVNET_SET((struct vnet *)tmr->vnet);
1801 #endif
1802 	did_output = 1;
1803 
1804 #ifdef SCTP_AUDITING_ENABLED
1805 	sctp_audit_log(0xF0, (uint8_t) tmr->type);
1806 	sctp_auditing(3, inp, stcb, net);
1807 #endif
1808 
1809 	/* sanity checks... */
1810 	KASSERT(tmr->self == tmr,
1811 	        ("sctp_timeout_handler: tmr->self corrupted"));
1812 	KASSERT(SCTP_IS_TIMER_TYPE_VALID(tmr->type),
1813 	        ("sctp_timeout_handler: invalid timer type %d", tmr->type));
1814 	type = tmr->type;
1815 	KASSERT(stcb == NULL || stcb->sctp_ep == inp,
1816 	        ("sctp_timeout_handler of type %d: inp = %p, stcb->sctp_ep %p",
1817 	         type, stcb, stcb->sctp_ep));
1818 	if (inp) {
1819 		SCTP_INP_INCR_REF(inp);
1820 	}
1821 	tmr->stopped_from = 0xa001;
1822 	if (stcb) {
1823 		atomic_add_int(&stcb->asoc.refcnt, 1);
1824 		if (stcb->asoc.state == 0) {
1825 			atomic_add_int(&stcb->asoc.refcnt, -1);
1826 			if (inp) {
1827 				SCTP_INP_DECR_REF(inp);
1828 			}
1829 			SCTPDBG(SCTP_DEBUG_TIMER2,
1830 			        "Timer type %d handler exiting due to CLOSED association.\n",
1831 			        type);
1832 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1833 			CURVNET_RESTORE();
1834 #endif
1835 			return;
1836 		}
1837 	}
1838 	tmr->stopped_from = 0xa002;
1839 	SCTPDBG(SCTP_DEBUG_TIMER2, "Timer type %d goes off.\n", type);
1840 	if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1841 		if (inp) {
1842 			SCTP_INP_DECR_REF(inp);
1843 		}
1844 		if (stcb) {
1845 			atomic_add_int(&stcb->asoc.refcnt, -1);
1846 		}
1847 		SCTPDBG(SCTP_DEBUG_TIMER2,
1848 			"Timer type %d handler exiting due to not being active.\n",
1849 			type);
1850 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1851 		CURVNET_RESTORE();
1852 #endif
1853 		return;
1854 	}
1855 
1856 	tmr->stopped_from = 0xa003;
1857 	if (stcb) {
1858 		SCTP_TCB_LOCK(stcb);
1859 		atomic_add_int(&stcb->asoc.refcnt, -1);
1860 		if ((type != SCTP_TIMER_TYPE_ASOCKILL) &&
1861 		    ((stcb->asoc.state == 0) ||
1862 		     (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) {
1863 			SCTP_TCB_UNLOCK(stcb);
1864 			if (inp) {
1865 				SCTP_INP_DECR_REF(inp);
1866 			}
1867 			SCTPDBG(SCTP_DEBUG_TIMER2,
1868 			        "Timer type %d handler exiting due to CLOSED association.\n",
1869 			        type);
1870 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1871 			CURVNET_RESTORE();
1872 #endif
1873 			return;
1874 		}
1875 	} else if (inp != NULL) {
1876 		SCTP_INP_WLOCK(inp);
1877 	} else {
1878 		SCTP_WQ_ADDR_LOCK();
1879 	}
1880 
1881 	/* Record in stopped_from which timeout occurred. */
1882 	tmr->stopped_from = type;
1883 #if defined(__FreeBSD__)
1884 	NET_EPOCH_ENTER(et);
1885 #endif
1886 	/* mark as being serviced now */
1887 	if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
1888 		/*
1889 		 * Callout has been rescheduled.
1890 		 */
1891 		goto get_out;
1892 	}
1893 	if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1894 		/*
1895 		 * Not active, so no action.
1896 		 */
1897 		goto get_out;
1898 	}
1899 	SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);
1900 
1901 #if defined(__Userspace__)
1902 	if ((stcb != NULL) &&
1903 	    !(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
1904 	    (stcb->sctp_socket != NULL)) {
1905 		upcall_socket = stcb->sctp_socket;
1906 		SOCK_LOCK(upcall_socket);
1907 		soref(upcall_socket);
1908 		SOCK_UNLOCK(upcall_socket);
1909 	}
1910 #endif
1911 	/* call the handler for the appropriate timer type */
1912 	switch (type) {
1913 	case SCTP_TIMER_TYPE_SEND:
1914 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
1915 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1916 		         type, inp, stcb, net));
1917 		SCTP_STAT_INCR(sctps_timodata);
1918 		stcb->asoc.timodata++;
1919 		stcb->asoc.num_send_timers_up--;
1920 		if (stcb->asoc.num_send_timers_up < 0) {
1921 			stcb->asoc.num_send_timers_up = 0;
1922 		}
1923 		SCTP_TCB_LOCK_ASSERT(stcb);
1924 		if (sctp_t3rxt_timer(inp, stcb, net)) {
1925 			/* no need to unlock on tcb its gone */
1926 
1927 			goto out_decr;
1928 		}
1929 		SCTP_TCB_LOCK_ASSERT(stcb);
1930 #ifdef SCTP_AUDITING_ENABLED
1931 		sctp_auditing(4, inp, stcb, net);
1932 #endif
1933 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1934 		if ((stcb->asoc.num_send_timers_up == 0) &&
1935 		    (stcb->asoc.sent_queue_cnt > 0)) {
1936 			struct sctp_tmit_chunk *chk;
1937 
1938 			/*
1939 			 * Safeguard. If there on some on the sent queue
1940 			 * somewhere but no timers running something is
1941 			 * wrong... so we start a timer on the first chunk
1942 			 * on the send queue on whatever net it is sent to.
1943 			 */
1944 			TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1945 				if (chk->whoTo != NULL) {
1946 					break;
1947 				}
1948 			}
1949 			if (chk != NULL) {
1950 				sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
1951 			}
1952 		}
1953 		break;
1954 	case SCTP_TIMER_TYPE_INIT:
1955 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
1956 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1957 		         type, inp, stcb, net));
1958 		SCTP_STAT_INCR(sctps_timoinit);
1959 		stcb->asoc.timoinit++;
1960 		if (sctp_t1init_timer(inp, stcb, net)) {
1961 			/* no need to unlock on tcb its gone */
1962 			goto out_decr;
1963 		}
1964 		/* We do output but not here */
1965 		did_output = 0;
1966 		break;
1967 	case SCTP_TIMER_TYPE_RECV:
1968 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
1969 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1970 		         type, inp, stcb, net));
1971 		SCTP_STAT_INCR(sctps_timosack);
1972 		stcb->asoc.timosack++;
1973 		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
1974 #ifdef SCTP_AUDITING_ENABLED
1975 		sctp_auditing(4, inp, stcb, NULL);
1976 #endif
1977 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED);
1978 		break;
1979 	case SCTP_TIMER_TYPE_SHUTDOWN:
1980 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
1981 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1982 		         type, inp, stcb, net));
1983 		SCTP_STAT_INCR(sctps_timoshutdown);
1984 		stcb->asoc.timoshutdown++;
1985 		if (sctp_shutdown_timer(inp, stcb, net)) {
1986 			/* no need to unlock on tcb its gone */
1987 			goto out_decr;
1988 		}
1989 #ifdef SCTP_AUDITING_ENABLED
1990 		sctp_auditing(4, inp, stcb, net);
1991 #endif
1992 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_NOT_LOCKED);
1993 		break;
1994 	case SCTP_TIMER_TYPE_HEARTBEAT:
1995 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
1996 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1997 		         type, inp, stcb, net));
1998 		SCTP_STAT_INCR(sctps_timoheartbeat);
1999 		stcb->asoc.timoheartbeat++;
2000 		if (sctp_heartbeat_timer(inp, stcb, net)) {
2001 			/* no need to unlock on tcb its gone */
2002 			goto out_decr;
2003 		}
2004 #ifdef SCTP_AUDITING_ENABLED
2005 		sctp_auditing(4, inp, stcb, net);
2006 #endif
2007 		if (!(net->dest_state & SCTP_ADDR_NOHB)) {
2008 			sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
2009 			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED);
2010 		}
2011 		break;
2012 	case SCTP_TIMER_TYPE_COOKIE:
2013 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
2014 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2015 		         type, inp, stcb, net));
2016 		SCTP_STAT_INCR(sctps_timocookie);
2017 		stcb->asoc.timocookie++;
2018 		if (sctp_cookie_timer(inp, stcb, net)) {
2019 			/* no need to unlock on tcb its gone */
2020 			goto out_decr;
2021 		}
2022 #ifdef SCTP_AUDITING_ENABLED
2023 		sctp_auditing(4, inp, stcb, net);
2024 #endif
2025 		/*
2026 		 * We consider T3 and Cookie timer pretty much the same with
2027 		 * respect to where from in chunk_output.
2028 		 */
2029 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
2030 		break;
2031 	case SCTP_TIMER_TYPE_NEWCOOKIE:
2032 		KASSERT(inp != NULL && stcb == NULL && net == NULL,
2033 			("timeout of type %d: inp = %p, stcb = %p, net = %p",
2034 			 type, inp, stcb, net));
2035 		SCTP_STAT_INCR(sctps_timosecret);
2036 		(void)SCTP_GETTIME_TIMEVAL(&tv);
2037 		inp->sctp_ep.time_of_secret_change = tv.tv_sec;
2038 		inp->sctp_ep.last_secret_number =
2039 		    inp->sctp_ep.current_secret_number;
2040 		inp->sctp_ep.current_secret_number++;
2041 		if (inp->sctp_ep.current_secret_number >=
2042 		    SCTP_HOW_MANY_SECRETS) {
2043 			inp->sctp_ep.current_secret_number = 0;
2044 		}
2045 		secret = (int)inp->sctp_ep.current_secret_number;
2046 		for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
2047 			inp->sctp_ep.secret_key[secret][i] =
2048 			    sctp_select_initial_TSN(&inp->sctp_ep);
2049 		}
2050 		sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
2051 		did_output = 0;
2052 		break;
2053 	case SCTP_TIMER_TYPE_PATHMTURAISE:
2054 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
2055 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2056 		         type, inp, stcb, net));
2057 		SCTP_STAT_INCR(sctps_timopathmtu);
2058 		sctp_pathmtu_timer(inp, stcb, net);
2059 		did_output = 0;
2060 		break;
2061 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
2062 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
2063 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2064 		         type, inp, stcb, net));
2065 		if (sctp_shutdownack_timer(inp, stcb, net)) {
2066 			/* no need to unlock on tcb its gone */
2067 			goto out_decr;
2068 		}
2069 		SCTP_STAT_INCR(sctps_timoshutdownack);
2070 		stcb->asoc.timoshutdownack++;
2071 #ifdef SCTP_AUDITING_ENABLED
2072 		sctp_auditing(4, inp, stcb, net);
2073 #endif
2074 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_ACK_TMR, SCTP_SO_NOT_LOCKED);
2075 		break;
2076 	case SCTP_TIMER_TYPE_ASCONF:
2077 		KASSERT(inp != NULL && stcb != NULL && net != NULL,
2078 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2079 		         type, inp, stcb, net));
2080 		SCTP_STAT_INCR(sctps_timoasconf);
2081 		if (sctp_asconf_timer(inp, stcb, net)) {
2082 			/* no need to unlock on tcb its gone */
2083 			goto out_decr;
2084 		}
2085 #ifdef SCTP_AUDITING_ENABLED
2086 		sctp_auditing(4, inp, stcb, net);
2087 #endif
2088 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_ASCONF_TMR, SCTP_SO_NOT_LOCKED);
2089 		break;
2090 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2091 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
2092 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2093 		         type, inp, stcb, net));
2094 		SCTP_STAT_INCR(sctps_timoshutdownguard);
2095 		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
2096 		                             "Shutdown guard timer expired");
2097 		sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
2098 		/* no need to unlock on tcb its gone */
2099 		goto out_decr;
2100 	case SCTP_TIMER_TYPE_AUTOCLOSE:
2101 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
2102 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2103 		         type, inp, stcb, net));
2104 		SCTP_STAT_INCR(sctps_timoautoclose);
2105 		sctp_autoclose_timer(inp, stcb);
2106 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED);
2107 		did_output = 0;
2108 		break;
2109 	case SCTP_TIMER_TYPE_STRRESET:
2110 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
2111 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2112 		         type, inp, stcb, net));
2113 		SCTP_STAT_INCR(sctps_timostrmrst);
2114 		if (sctp_strreset_timer(inp, stcb)) {
2115 			/* no need to unlock on tcb its gone */
2116 			goto out_decr;
2117 		}
2118 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_TMR, SCTP_SO_NOT_LOCKED);
2119 		break;
2120 	case SCTP_TIMER_TYPE_INPKILL:
2121 		KASSERT(inp != NULL && stcb == NULL && net == NULL,
2122 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2123 		         type, inp, stcb, net));
2124 		SCTP_STAT_INCR(sctps_timoinpkill);
2125 		/*
2126 		 * special case, take away our increment since WE are the
2127 		 * killer
2128 		 */
2129 		sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL,
2130 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
2131 #if defined(__APPLE__)
2132 		SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
2133 #endif
2134 		SCTP_INP_DECR_REF(inp);
2135 		SCTP_INP_WUNLOCK(inp);
2136 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
2137 				SCTP_CALLED_FROM_INPKILL_TIMER);
2138 #if defined(__APPLE__)
2139 		SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1);
2140 #endif
2141 		inp = NULL;
2142 		goto out_no_decr;
2143 	case SCTP_TIMER_TYPE_ASOCKILL:
2144 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
2145 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2146 		         type, inp, stcb, net));
2147 		SCTP_STAT_INCR(sctps_timoassockill);
2148 		/* Can we free it yet? */
2149 		SCTP_INP_DECR_REF(inp);
2150 		sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
2151 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
2152 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2153 		so = SCTP_INP_SO(inp);
2154 		atomic_add_int(&stcb->asoc.refcnt, 1);
2155 		SCTP_TCB_UNLOCK(stcb);
2156 		SCTP_SOCKET_LOCK(so, 1);
2157 		SCTP_TCB_LOCK(stcb);
2158 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
2159 #endif
2160 		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
2161 		                      SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
2162 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2163 		SCTP_SOCKET_UNLOCK(so, 1);
2164 #endif
2165 		/*
2166 		 * free asoc, always unlocks (or destroy's) so prevent
2167 		 * duplicate unlock or unlock of a free mtx :-0
2168 		 */
2169 		stcb = NULL;
2170 		goto out_no_decr;
2171 	case SCTP_TIMER_TYPE_ADDR_WQ:
2172 		KASSERT(inp == NULL && stcb == NULL && net == NULL,
2173 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2174 		         type, inp, stcb, net));
2175 		sctp_handle_addr_wq();
2176 		break;
2177 	case SCTP_TIMER_TYPE_PRIM_DELETED:
2178 		KASSERT(inp != NULL && stcb != NULL && net == NULL,
2179 		        ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2180 		         type, inp, stcb, net));
2181 		SCTP_STAT_INCR(sctps_timodelprim);
2182 		sctp_delete_prim_timer(inp, stcb);
2183 		break;
2184 	default:
2185 #ifdef INVARIANTS
2186 		panic("Unknown timer type %d", type);
2187 #else
2188 		goto get_out;
2189 #endif
2190 	}
2191 #ifdef SCTP_AUDITING_ENABLED
2192 	sctp_audit_log(0xF1, (uint8_t) type);
2193 	if (inp)
2194 		sctp_auditing(5, inp, stcb, net);
2195 #endif
2196 	if ((did_output) && stcb) {
2197 		/*
2198 		 * Now we need to clean up the control chunk chain if an
2199 		 * ECNE is on it. It must be marked as UNSENT again so next
2200 		 * call will continue to send it until such time that we get
2201 		 * a CWR, to remove it. It is, however, less likely that we
2202 		 * will find a ecn echo on the chain though.
2203 		 */
2204 		sctp_fix_ecn_echo(&stcb->asoc);
2205 	}
2206 get_out:
2207 	if (stcb) {
2208 		SCTP_TCB_UNLOCK(stcb);
2209 	} else if (inp != NULL) {
2210 		SCTP_INP_WUNLOCK(inp);
2211 	} else {
2212 		SCTP_WQ_ADDR_UNLOCK();
2213 	}
2214 
2215 out_decr:
2216 #if defined(__Userspace__)
2217 	if (upcall_socket != NULL) {
2218 		if ((upcall_socket->so_upcall != NULL) &&
2219 		    (upcall_socket->so_error != 0)) {
2220 			(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
2221 		}
2222 		ACCEPT_LOCK();
2223 		SOCK_LOCK(upcall_socket);
2224 		sorele(upcall_socket);
2225 	}
2226 #endif
2227 	if (inp) {
2228 		SCTP_INP_DECR_REF(inp);
2229 	}
2230 
2231 out_no_decr:
2232 	SCTPDBG(SCTP_DEBUG_TIMER2, "Timer type %d handler finished.\n", type);
2233 #if defined(__FreeBSD__)
2234 #if __FreeBSD_version >= 801000
2235 	CURVNET_RESTORE();
2236 #endif
2237 	NET_EPOCH_EXIT(et);
2238 #endif
2239 }
2240 
2241 /*-
2242  * The following table shows which parameters must be provided
2243  * when calling sctp_timer_start(). For parameters not being
2244  * provided, NULL must be used.
2245  *
2246  * |Name                         |inp |stcb|net |
2247  * |-----------------------------|----|----|----|
2248  * |SCTP_TIMER_TYPE_SEND         |Yes |Yes |Yes |
2249  * |SCTP_TIMER_TYPE_INIT         |Yes |Yes |Yes |
2250  * |SCTP_TIMER_TYPE_RECV         |Yes |Yes |No  |
2251  * |SCTP_TIMER_TYPE_SHUTDOWN     |Yes |Yes |Yes |
2252  * |SCTP_TIMER_TYPE_HEARTBEAT    |Yes |Yes |Yes |
2253  * |SCTP_TIMER_TYPE_COOKIE       |Yes |Yes |Yes |
2254  * |SCTP_TIMER_TYPE_NEWCOOKIE    |Yes |No  |No  |
2255  * |SCTP_TIMER_TYPE_PATHMTURAISE |Yes |Yes |Yes |
2256  * |SCTP_TIMER_TYPE_SHUTDOWNACK  |Yes |Yes |Yes |
2257  * |SCTP_TIMER_TYPE_ASCONF       |Yes |Yes |Yes |
2258  * |SCTP_TIMER_TYPE_SHUTDOWNGUARD|Yes |Yes |No  |
2259  * |SCTP_TIMER_TYPE_AUTOCLOSE    |Yes |Yes |No  |
2260  * |SCTP_TIMER_TYPE_STRRESET     |Yes |Yes |Yes |
2261  * |SCTP_TIMER_TYPE_INPKILL      |Yes |No  |No  |
2262  * |SCTP_TIMER_TYPE_ASOCKILL     |Yes |Yes |No  |
2263  * |SCTP_TIMER_TYPE_ADDR_WQ      |No  |No  |No  |
2264  * |SCTP_TIMER_TYPE_PRIM_DELETED |Yes |Yes |No  |
2265  *
2266  */
2267 
2268 void
sctp_timer_start(int t_type,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net)2269 sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2270     struct sctp_nets *net)
2271 {
2272 	struct sctp_timer *tmr;
2273 	uint32_t to_ticks;
2274 	uint32_t rndval, jitter;
2275 
2276 	KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2277 	        ("sctp_timer_start of type %d: inp = %p, stcb->sctp_ep %p",
2278 	         t_type, stcb, stcb->sctp_ep));
2279 	tmr = NULL;
2280 	to_ticks = 0;
2281 	if (stcb != NULL) {
2282 		SCTP_TCB_LOCK_ASSERT(stcb);
2283 	} else if (inp != NULL) {
2284 		SCTP_INP_WLOCK_ASSERT(inp);
2285 	} else {
2286 		SCTP_WQ_ADDR_LOCK_ASSERT();
2287 	}
2288 	if (stcb != NULL) {
2289 		/* Don't restart timer on association that's about to be killed. */
2290 		if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
2291 		    (t_type != SCTP_TIMER_TYPE_ASOCKILL)) {
2292 			SCTPDBG(SCTP_DEBUG_TIMER2,
2293 				"Timer type %d not started: inp=%p, stcb=%p, net=%p (stcb deleted).\n",
2294 				t_type, inp, stcb, net);
2295 			return;
2296 		}
2297 		/* Don't restart timer on net that's been removed. */
2298 		if (net != NULL && (net->dest_state & SCTP_ADDR_BEING_DELETED)) {
2299 			SCTPDBG(SCTP_DEBUG_TIMER2,
2300 				"Timer type %d not started: inp=%p, stcb=%p, net=%p (net deleted).\n",
2301 				t_type, inp, stcb, net);
2302 			return;
2303 		}
2304 	}
2305 	switch (t_type) {
2306 	case SCTP_TIMER_TYPE_SEND:
2307 		/* Here we use the RTO timer. */
2308 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2309 #ifdef INVARIANTS
2310 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2311 			      t_type, inp, stcb, net);
2312 #else
2313 			return;
2314 #endif
2315 		}
2316 		tmr = &net->rxt_timer;
2317 		if (net->RTO == 0) {
2318 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2319 		} else {
2320 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2321 		}
2322 		break;
2323 	case SCTP_TIMER_TYPE_INIT:
2324 		/*
2325 		 * Here we use the INIT timer default usually about 1
2326 		 * second.
2327 		 */
2328 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2329 #ifdef INVARIANTS
2330 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2331 			      t_type, inp, stcb, net);
2332 #else
2333 			return;
2334 #endif
2335 		}
2336 		tmr = &net->rxt_timer;
2337 		if (net->RTO == 0) {
2338 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2339 		} else {
2340 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2341 		}
2342 		break;
2343 	case SCTP_TIMER_TYPE_RECV:
2344 		/*
2345 		 * Here we use the Delayed-Ack timer value from the inp,
2346 		 * ususually about 200ms.
2347 		 */
2348 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2349 #ifdef INVARIANTS
2350 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2351 			      t_type, inp, stcb, net);
2352 #else
2353 			return;
2354 #endif
2355 		}
2356 		tmr = &stcb->asoc.dack_timer;
2357 		to_ticks = sctp_msecs_to_ticks(stcb->asoc.delayed_ack);
2358 		break;
2359 	case SCTP_TIMER_TYPE_SHUTDOWN:
2360 		/* Here we use the RTO of the destination. */
2361 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2362 #ifdef INVARIANTS
2363 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2364 			      t_type, inp, stcb, net);
2365 #else
2366 			return;
2367 #endif
2368 		}
2369 		tmr = &net->rxt_timer;
2370 		if (net->RTO == 0) {
2371 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2372 		} else {
2373 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2374 		}
2375 		break;
2376 	case SCTP_TIMER_TYPE_HEARTBEAT:
2377 		/*
2378 		 * The net is used here so that we can add in the RTO. Even
2379 		 * though we use a different timer. We also add the HB timer
2380 		 * PLUS a random jitter.
2381 		 */
2382 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2383 #ifdef INVARIANTS
2384 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2385 			      t_type, inp, stcb, net);
2386 #else
2387 			return;
2388 #endif
2389 		}
2390 		if ((net->dest_state & SCTP_ADDR_NOHB) &&
2391 		    !(net->dest_state & SCTP_ADDR_UNCONFIRMED)) {
2392 			SCTPDBG(SCTP_DEBUG_TIMER2,
2393 			        "Timer type %d not started: inp=%p, stcb=%p, net=%p.\n",
2394 			        t_type, inp, stcb, net);
2395 			return;
2396 		}
2397 		tmr = &net->hb_timer;
2398 		if (net->RTO == 0) {
2399 			to_ticks = stcb->asoc.initial_rto;
2400 		} else {
2401 			to_ticks = net->RTO;
2402 		}
2403 		rndval = sctp_select_initial_TSN(&inp->sctp_ep);
2404 		jitter = rndval % to_ticks;
2405 		if (jitter >= (to_ticks >> 1)) {
2406 			to_ticks = to_ticks + (jitter - (to_ticks >> 1));
2407 		} else {
2408 			to_ticks = to_ticks - jitter;
2409 		}
2410 		if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
2411 		    !(net->dest_state & SCTP_ADDR_PF)) {
2412 			to_ticks += net->heart_beat_delay;
2413 		}
2414 		/*
2415 		 * Now we must convert the to_ticks that are now in
2416 		 * ms to ticks.
2417 		 */
2418 		to_ticks = sctp_msecs_to_ticks(to_ticks);
2419 		break;
2420 	case SCTP_TIMER_TYPE_COOKIE:
2421 		/*
2422 		 * Here we can use the RTO timer from the network since one
2423 		 * RTT was complete. If a retransmission happened then we will
2424 		 * be using the RTO initial value.
2425 		 */
2426 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2427 #ifdef INVARIANTS
2428 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2429 			      t_type, inp, stcb, net);
2430 #else
2431 			return;
2432 #endif
2433 		}
2434 		tmr = &net->rxt_timer;
2435 		if (net->RTO == 0) {
2436 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2437 		} else {
2438 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2439 		}
2440 		break;
2441 	case SCTP_TIMER_TYPE_NEWCOOKIE:
2442 		/*
2443 		 * Nothing needed but the endpoint here ususually about 60
2444 		 * minutes.
2445 		 */
2446 		if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2447 #ifdef INVARIANTS
2448 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2449 			      t_type, inp, stcb, net);
2450 #else
2451 			return;
2452 #endif
2453 		}
2454 		tmr = &inp->sctp_ep.signature_change;
2455 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
2456 		break;
2457 	case SCTP_TIMER_TYPE_PATHMTURAISE:
2458 		/*
2459 		 * Here we use the value found in the EP for PMTUD, ususually
2460 		 * about 10 minutes.
2461 		 */
2462 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2463 #ifdef INVARIANTS
2464 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2465 			      t_type, inp, stcb, net);
2466 #else
2467 			return;
2468 #endif
2469 		}
2470 		if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
2471 			SCTPDBG(SCTP_DEBUG_TIMER2,
2472 			        "Timer type %d not started: inp=%p, stcb=%p, net=%p.\n",
2473 			        t_type, inp, stcb, net);
2474 			return;
2475 		}
2476 		tmr = &net->pmtu_timer;
2477 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
2478 		break;
2479 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
2480 		/* Here we use the RTO of the destination. */
2481 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2482 #ifdef INVARIANTS
2483 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2484 			      t_type, inp, stcb, net);
2485 #else
2486 			return;
2487 #endif
2488 		}
2489 		tmr = &net->rxt_timer;
2490 		if (net->RTO == 0) {
2491 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2492 		} else {
2493 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2494 		}
2495 		break;
2496 	case SCTP_TIMER_TYPE_ASCONF:
2497 		/*
2498 		 * Here the timer comes from the stcb but its value is from
2499 		 * the net's RTO.
2500 		 */
2501 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2502 #ifdef INVARIANTS
2503 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2504 			      t_type, inp, stcb, net);
2505 #else
2506 			return;
2507 #endif
2508 		}
2509 		tmr = &stcb->asoc.asconf_timer;
2510 		if (net->RTO == 0) {
2511 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2512 		} else {
2513 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2514 		}
2515 		break;
2516 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2517 		/*
2518 		 * Here we use the endpoints shutdown guard timer usually
2519 		 * about 3 minutes.
2520 		 */
2521 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2522 #ifdef INVARIANTS
2523 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2524 			      t_type, inp, stcb, net);
2525 #else
2526 			return;
2527 #endif
2528 		}
2529 		tmr = &stcb->asoc.shut_guard_timer;
2530 		if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) {
2531 			if (stcb->asoc.maxrto < UINT32_MAX / 5) {
2532 				to_ticks = sctp_msecs_to_ticks(5 * stcb->asoc.maxrto);
2533 			} else {
2534 				to_ticks = sctp_msecs_to_ticks(UINT32_MAX);
2535 			}
2536 		} else {
2537 			to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
2538 		}
2539 		break;
2540 	case SCTP_TIMER_TYPE_AUTOCLOSE:
2541 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2542 #ifdef INVARIANTS
2543 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2544 			      t_type, inp, stcb, net);
2545 #else
2546 			return;
2547 #endif
2548 		}
2549 		tmr = &stcb->asoc.autoclose_timer;
2550 		to_ticks = stcb->asoc.sctp_autoclose_ticks;
2551 		break;
2552 	case SCTP_TIMER_TYPE_STRRESET:
2553 		/*
2554 		 * Here the timer comes from the stcb but its value is from
2555 		 * the net's RTO.
2556 		 */
2557 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2558 #ifdef INVARIANTS
2559 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2560 			      t_type, inp, stcb, net);
2561 #else
2562 			return;
2563 #endif
2564 		}
2565 		tmr = &stcb->asoc.strreset_timer;
2566 		if (net->RTO == 0) {
2567 			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2568 		} else {
2569 			to_ticks = sctp_msecs_to_ticks(net->RTO);
2570 		}
2571 		break;
2572 	case SCTP_TIMER_TYPE_INPKILL:
2573 		/*
2574 		 * The inp is setup to die. We re-use the signature_chage
2575 		 * timer since that has stopped and we are in the GONE
2576 		 * state.
2577 		 */
2578 		if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2579 #ifdef INVARIANTS
2580 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2581 			      t_type, inp, stcb, net);
2582 #else
2583 			return;
2584 #endif
2585 		}
2586 		tmr = &inp->sctp_ep.signature_change;
2587 		to_ticks = sctp_msecs_to_ticks(SCTP_INP_KILL_TIMEOUT);
2588 		break;
2589 	case SCTP_TIMER_TYPE_ASOCKILL:
2590 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2591 #ifdef INVARIANTS
2592 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2593 			      t_type, inp, stcb, net);
2594 #else
2595 			return;
2596 #endif
2597 		}
2598 		tmr = &stcb->asoc.strreset_timer;
2599 		to_ticks = sctp_msecs_to_ticks(SCTP_ASOC_KILL_TIMEOUT);
2600 		break;
2601 	case SCTP_TIMER_TYPE_ADDR_WQ:
2602 		if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
2603 #ifdef INVARIANTS
2604 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2605 			      t_type, inp, stcb, net);
2606 #else
2607 			return;
2608 #endif
2609 		}
2610 		/* Only 1 tick away :-) */
2611 		tmr = &SCTP_BASE_INFO(addr_wq_timer);
2612 		to_ticks = SCTP_ADDRESS_TICK_DELAY;
2613 		break;
2614 	case SCTP_TIMER_TYPE_PRIM_DELETED:
2615 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2616 #ifdef INVARIANTS
2617 			panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2618 			      t_type, inp, stcb, net);
2619 #else
2620 			return;
2621 #endif
2622 		}
2623 		tmr = &stcb->asoc.delete_prim_timer;
2624 		to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2625 		break;
2626 	default:
2627 #ifdef INVARIANTS
2628 		panic("Unknown timer type %d", t_type);
2629 #else
2630 		return;
2631 #endif
2632 	}
2633 	KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2634 	KASSERT(to_ticks > 0, ("to_ticks == 0 for timer type %d", t_type));
2635 	if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
2636 		/*
2637 		 * We do NOT allow you to have it already running. If it is,
2638 		 * we leave the current one up unchanged.
2639 		 */
2640 		SCTPDBG(SCTP_DEBUG_TIMER2,
2641 		        "Timer type %d already running: inp=%p, stcb=%p, net=%p.\n",
2642 		         t_type, inp, stcb, net);
2643 		return;
2644 	}
2645 	/* At this point we can proceed. */
2646 	if (t_type == SCTP_TIMER_TYPE_SEND) {
2647 		stcb->asoc.num_send_timers_up++;
2648 	}
2649 	tmr->stopped_from = 0;
2650 	tmr->type = t_type;
2651 	tmr->ep = (void *)inp;
2652 	tmr->tcb = (void *)stcb;
2653 	if (t_type == SCTP_TIMER_TYPE_STRRESET) {
2654 		tmr->net = NULL;
2655 	} else {
2656 		tmr->net = (void *)net;
2657 	}
2658 	tmr->self = (void *)tmr;
2659 #if defined(__FreeBSD__)
2660 	tmr->vnet = (void *)curvnet;
2661 #endif
2662 	tmr->ticks = sctp_get_tick_count();
2663 	if (SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr) == 0) {
2664 		SCTPDBG(SCTP_DEBUG_TIMER2,
2665 		        "Timer type %d started: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2666 		         t_type, to_ticks, inp, stcb, net);
2667 	} else {
2668 		/*
2669 		 * This should not happen, since we checked for pending
2670 		 * above.
2671 		 */
2672 		SCTPDBG(SCTP_DEBUG_TIMER2,
2673 		        "Timer type %d restarted: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2674 		         t_type, to_ticks, inp, stcb, net);
2675 	}
2676 	return;
2677 }
2678 
2679 /*-
2680  * The following table shows which parameters must be provided
2681  * when calling sctp_timer_stop(). For parameters not being
2682  * provided, NULL must be used.
2683  *
2684  * |Name                         |inp |stcb|net |
2685  * |-----------------------------|----|----|----|
2686  * |SCTP_TIMER_TYPE_SEND         |Yes |Yes |Yes |
2687  * |SCTP_TIMER_TYPE_INIT         |Yes |Yes |Yes |
2688  * |SCTP_TIMER_TYPE_RECV         |Yes |Yes |No  |
2689  * |SCTP_TIMER_TYPE_SHUTDOWN     |Yes |Yes |Yes |
2690  * |SCTP_TIMER_TYPE_HEARTBEAT    |Yes |Yes |Yes |
2691  * |SCTP_TIMER_TYPE_COOKIE       |Yes |Yes |Yes |
2692  * |SCTP_TIMER_TYPE_NEWCOOKIE    |Yes |No  |No  |
2693  * |SCTP_TIMER_TYPE_PATHMTURAISE |Yes |Yes |Yes |
2694  * |SCTP_TIMER_TYPE_SHUTDOWNACK  |Yes |Yes |Yes |
2695  * |SCTP_TIMER_TYPE_ASCONF       |Yes |Yes |No  |
2696  * |SCTP_TIMER_TYPE_SHUTDOWNGUARD|Yes |Yes |No  |
2697  * |SCTP_TIMER_TYPE_AUTOCLOSE    |Yes |Yes |No  |
2698  * |SCTP_TIMER_TYPE_STRRESET     |Yes |Yes |No  |
2699  * |SCTP_TIMER_TYPE_INPKILL      |Yes |No  |No  |
2700  * |SCTP_TIMER_TYPE_ASOCKILL     |Yes |Yes |No  |
2701  * |SCTP_TIMER_TYPE_ADDR_WQ      |No  |No  |No  |
2702  * |SCTP_TIMER_TYPE_PRIM_DELETED |Yes |Yes |No  |
2703  *
2704  */
2705 
2706 void
sctp_timer_stop(int t_type,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net,uint32_t from)2707 sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2708     struct sctp_nets *net, uint32_t from)
2709 {
2710 	struct sctp_timer *tmr;
2711 
2712 	KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2713 	        ("sctp_timer_stop of type %d: inp = %p, stcb->sctp_ep %p",
2714 	         t_type, stcb, stcb->sctp_ep));
2715 	if (stcb != NULL) {
2716 		SCTP_TCB_LOCK_ASSERT(stcb);
2717 	} else if (inp != NULL) {
2718 		SCTP_INP_WLOCK_ASSERT(inp);
2719 	} else {
2720 		SCTP_WQ_ADDR_LOCK_ASSERT();
2721 	}
2722 	tmr = NULL;
2723 	switch (t_type) {
2724 	case SCTP_TIMER_TYPE_SEND:
2725 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2726 #ifdef INVARIANTS
2727 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2728 			      t_type, inp, stcb, net);
2729 #else
2730 			return;
2731 #endif
2732 		}
2733 		tmr = &net->rxt_timer;
2734 		break;
2735 	case SCTP_TIMER_TYPE_INIT:
2736 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2737 #ifdef INVARIANTS
2738 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2739 			      t_type, inp, stcb, net);
2740 #else
2741 			return;
2742 #endif
2743 		}
2744 		tmr = &net->rxt_timer;
2745 		break;
2746 	case SCTP_TIMER_TYPE_RECV:
2747 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2748 #ifdef INVARIANTS
2749 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2750 			      t_type, inp, stcb, net);
2751 #else
2752 			return;
2753 #endif
2754 		}
2755 		tmr = &stcb->asoc.dack_timer;
2756 		break;
2757 	case SCTP_TIMER_TYPE_SHUTDOWN:
2758 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2759 #ifdef INVARIANTS
2760 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2761 			      t_type, inp, stcb, net);
2762 #else
2763 			return;
2764 #endif
2765 		}
2766 		tmr = &net->rxt_timer;
2767 		break;
2768 	case SCTP_TIMER_TYPE_HEARTBEAT:
2769 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2770 #ifdef INVARIANTS
2771 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2772 			      t_type, inp, stcb, net);
2773 #else
2774 			return;
2775 #endif
2776 		}
2777 		tmr = &net->hb_timer;
2778 		break;
2779 	case SCTP_TIMER_TYPE_COOKIE:
2780 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2781 #ifdef INVARIANTS
2782 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2783 			      t_type, inp, stcb, net);
2784 #else
2785 			return;
2786 #endif
2787 		}
2788 		tmr = &net->rxt_timer;
2789 		break;
2790 	case SCTP_TIMER_TYPE_NEWCOOKIE:
2791 		if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2792 #ifdef INVARIANTS
2793 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2794 			      t_type, inp, stcb, net);
2795 #else
2796 			return;
2797 #endif
2798 		}
2799 		tmr = &inp->sctp_ep.signature_change;
2800 		break;
2801 	case SCTP_TIMER_TYPE_PATHMTURAISE:
2802 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2803 #ifdef INVARIANTS
2804 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2805 			      t_type, inp, stcb, net);
2806 #else
2807 			return;
2808 #endif
2809 		}
2810 		tmr = &net->pmtu_timer;
2811 		break;
2812 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
2813 		if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2814 #ifdef INVARIANTS
2815 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2816 			      t_type, inp, stcb, net);
2817 #else
2818 			return;
2819 #endif
2820 		}
2821 		tmr = &net->rxt_timer;
2822 		break;
2823 	case SCTP_TIMER_TYPE_ASCONF:
2824 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2825 #ifdef INVARIANTS
2826 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2827 			      t_type, inp, stcb, net);
2828 #else
2829 			return;
2830 #endif
2831 		}
2832 		tmr = &stcb->asoc.asconf_timer;
2833 		break;
2834 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2835 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2836 #ifdef INVARIANTS
2837 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2838 			      t_type, inp, stcb, net);
2839 #else
2840 			return;
2841 #endif
2842 		}
2843 		tmr = &stcb->asoc.shut_guard_timer;
2844 		break;
2845 	case SCTP_TIMER_TYPE_AUTOCLOSE:
2846 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2847 #ifdef INVARIANTS
2848 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2849 			      t_type, inp, stcb, net);
2850 #else
2851 			return;
2852 #endif
2853 		}
2854 		tmr = &stcb->asoc.autoclose_timer;
2855 		break;
2856 	case SCTP_TIMER_TYPE_STRRESET:
2857 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2858 #ifdef INVARIANTS
2859 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2860 			      t_type, inp, stcb, net);
2861 #else
2862 			return;
2863 #endif
2864 		}
2865 		tmr = &stcb->asoc.strreset_timer;
2866 		break;
2867 	case SCTP_TIMER_TYPE_INPKILL:
2868 		/*
2869 		 * The inp is setup to die. We re-use the signature_chage
2870 		 * timer since that has stopped and we are in the GONE
2871 		 * state.
2872 		 */
2873 		if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2874 #ifdef INVARIANTS
2875 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2876 			      t_type, inp, stcb, net);
2877 #else
2878 			return;
2879 #endif
2880 		}
2881 		tmr = &inp->sctp_ep.signature_change;
2882 		break;
2883 	case SCTP_TIMER_TYPE_ASOCKILL:
2884 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2885 #ifdef INVARIANTS
2886 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2887 			      t_type, inp, stcb, net);
2888 #else
2889 			return;
2890 #endif
2891 		}
2892 		tmr = &stcb->asoc.strreset_timer;
2893 		break;
2894 	case SCTP_TIMER_TYPE_ADDR_WQ:
2895 		if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
2896 #ifdef INVARIANTS
2897 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2898 			      t_type, inp, stcb, net);
2899 #else
2900 			return;
2901 #endif
2902 		}
2903 		tmr = &SCTP_BASE_INFO(addr_wq_timer);
2904 		break;
2905 	case SCTP_TIMER_TYPE_PRIM_DELETED:
2906 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2907 #ifdef INVARIANTS
2908 			panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2909 			      t_type, inp, stcb, net);
2910 #else
2911 			return;
2912 #endif
2913 		}
2914 		tmr = &stcb->asoc.delete_prim_timer;
2915 		break;
2916 	default:
2917 #ifdef INVARIANTS
2918 		panic("Unknown timer type %d", t_type);
2919 #else
2920 		return;
2921 #endif
2922 	}
2923 	KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2924 	if ((tmr->type != SCTP_TIMER_TYPE_NONE) &&
2925 	    (tmr->type != t_type)) {
2926 		/*
2927 		 * Ok we have a timer that is under joint use. Cookie timer
2928 		 * per chance with the SEND timer. We therefore are NOT
2929 		 * running the timer that the caller wants stopped.  So just
2930 		 * return.
2931 		 */
2932 		SCTPDBG(SCTP_DEBUG_TIMER2,
2933 		        "Shared timer type %d not running: inp=%p, stcb=%p, net=%p.\n",
2934 		         t_type, inp, stcb, net);
2935 		return;
2936 	}
2937 	if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) {
2938 		stcb->asoc.num_send_timers_up--;
2939 		if (stcb->asoc.num_send_timers_up < 0) {
2940 			stcb->asoc.num_send_timers_up = 0;
2941 		}
2942 	}
2943 	tmr->self = NULL;
2944 	tmr->stopped_from = from;
2945 	if (SCTP_OS_TIMER_STOP(&tmr->timer) == 1) {
2946 		KASSERT(tmr->ep == inp,
2947 		        ("sctp_timer_stop of type %d: inp = %p, tmr->inp = %p",
2948 		         t_type, inp, tmr->ep));
2949 		KASSERT(tmr->tcb == stcb,
2950 		        ("sctp_timer_stop of type %d: stcb = %p, tmr->stcb = %p",
2951 		         t_type, stcb, tmr->tcb));
2952 		KASSERT(((t_type == SCTP_TIMER_TYPE_ASCONF) && (tmr->net != NULL)) ||
2953 		        ((t_type != SCTP_TIMER_TYPE_ASCONF) && (tmr->net == net)),
2954 		        ("sctp_timer_stop of type %d: net = %p, tmr->net = %p",
2955 		         t_type, net, tmr->net));
2956 		SCTPDBG(SCTP_DEBUG_TIMER2,
2957 		        "Timer type %d stopped: inp=%p, stcb=%p, net=%p.\n",
2958 		        t_type, inp, stcb, net);
2959 		tmr->ep = NULL;
2960 		tmr->tcb = NULL;
2961 		tmr->net = NULL;
2962 	} else {
2963 		SCTPDBG(SCTP_DEBUG_TIMER2,
2964 		        "Timer type %d not stopped: inp=%p, stcb=%p, net=%p.\n",
2965 		         t_type, inp, stcb, net);
2966 	}
2967 	return;
2968 }
2969 
2970 uint32_t
sctp_calculate_len(struct mbuf * m)2971 sctp_calculate_len(struct mbuf *m)
2972 {
2973 	uint32_t tlen = 0;
2974 	struct mbuf *at;
2975 
2976 	at = m;
2977 	while (at) {
2978 		tlen += SCTP_BUF_LEN(at);
2979 		at = SCTP_BUF_NEXT(at);
2980 	}
2981 	return (tlen);
2982 }
2983 
2984 void
sctp_mtu_size_reset(struct sctp_inpcb * inp,struct sctp_association * asoc,uint32_t mtu)2985 sctp_mtu_size_reset(struct sctp_inpcb *inp,
2986     struct sctp_association *asoc, uint32_t mtu)
2987 {
2988 	/*
2989 	 * Reset the P-MTU size on this association, this involves changing
2990 	 * the asoc MTU, going through ANY chunk+overhead larger than mtu to
2991 	 * allow the DF flag to be cleared.
2992 	 */
2993 	struct sctp_tmit_chunk *chk;
2994 	unsigned int eff_mtu, ovh;
2995 
2996 	asoc->smallest_mtu = mtu;
2997 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2998 		ovh = SCTP_MIN_OVERHEAD;
2999 	} else {
3000 		ovh = SCTP_MIN_V4_OVERHEAD;
3001 	}
3002 	eff_mtu = mtu - ovh;
3003 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
3004 		if (chk->send_size > eff_mtu) {
3005 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
3006 		}
3007 	}
3008 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
3009 		if (chk->send_size > eff_mtu) {
3010 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
3011 		}
3012 	}
3013 }
3014 
3015 
3016 /*
3017  * Given an association and starting time of the current RTT period, update
3018  * RTO in number of msecs. net should point to the current network.
3019  * Return 1, if an RTO update was performed, return 0 if no update was
3020  * performed due to invalid starting point.
3021  */
3022 
3023 int
sctp_calculate_rto(struct sctp_tcb * stcb,struct sctp_association * asoc,struct sctp_nets * net,struct timeval * old,int rtt_from_sack)3024 sctp_calculate_rto(struct sctp_tcb *stcb,
3025 		   struct sctp_association *asoc,
3026 		   struct sctp_nets *net,
3027 		   struct timeval *old,
3028 		   int rtt_from_sack)
3029 {
3030 	struct timeval now;
3031 	uint64_t rtt_us;	/* RTT in us */
3032 	int32_t rtt;		/* RTT in ms */
3033 	uint32_t new_rto;
3034 	int first_measure = 0;
3035 
3036 	/************************/
3037 	/* 1. calculate new RTT */
3038 	/************************/
3039 	/* get the current time */
3040 	if (stcb->asoc.use_precise_time) {
3041 		(void)SCTP_GETPTIME_TIMEVAL(&now);
3042 	} else {
3043 		(void)SCTP_GETTIME_TIMEVAL(&now);
3044 	}
3045 	if ((old->tv_sec > now.tv_sec) ||
3046 	    ((old->tv_sec == now.tv_sec) && (old->tv_usec > now.tv_usec))) {
3047 		/* The starting point is in the future. */
3048 		return (0);
3049 	}
3050 	timevalsub(&now, old);
3051 	rtt_us = (uint64_t)1000000 * (uint64_t)now.tv_sec + (uint64_t)now.tv_usec;
3052 	if (rtt_us > SCTP_RTO_UPPER_BOUND * 1000) {
3053 		/* The RTT is larger than a sane value. */
3054 		return (0);
3055 	}
3056 	/* store the current RTT in us */
3057 	net->rtt = rtt_us;
3058 	/* compute rtt in ms */
3059 	rtt = (int32_t)(net->rtt / 1000);
3060 	if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) {
3061 		/* Tell the CC module that a new update has just occurred from a sack */
3062 		(*asoc->cc_functions.sctp_rtt_calculated)(stcb, net, &now);
3063 	}
3064 	/* Do we need to determine the lan? We do this only
3065 	 * on sacks i.e. RTT being determined from data not
3066 	 * non-data (HB/INIT->INITACK).
3067 	 */
3068 	if ((rtt_from_sack == SCTP_RTT_FROM_DATA) &&
3069 	    (net->lan_type == SCTP_LAN_UNKNOWN)) {
3070 		if (net->rtt > SCTP_LOCAL_LAN_RTT) {
3071 			net->lan_type = SCTP_LAN_INTERNET;
3072 		} else {
3073 			net->lan_type = SCTP_LAN_LOCAL;
3074 		}
3075 	}
3076 
3077 	/***************************/
3078 	/* 2. update RTTVAR & SRTT */
3079 	/***************************/
3080 	/*-
3081 	 * Compute the scaled average lastsa and the
3082 	 * scaled variance lastsv as described in van Jacobson
3083 	 * Paper "Congestion Avoidance and Control", Annex A.
3084 	 *
3085 	 * (net->lastsa >> SCTP_RTT_SHIFT) is the srtt
3086 	 * (net->lastsv >> SCTP_RTT_VAR_SHIFT) is the rttvar
3087 	 */
3088 	if (net->RTO_measured) {
3089 		rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
3090 		net->lastsa += rtt;
3091 		if (rtt < 0) {
3092 			rtt = -rtt;
3093 		}
3094 		rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);
3095 		net->lastsv += rtt;
3096 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3097 			rto_logging(net, SCTP_LOG_RTTVAR);
3098 		}
3099 	} else {
3100 		/* First RTO measurment */
3101 		net->RTO_measured = 1;
3102 		first_measure = 1;
3103 		net->lastsa = rtt << SCTP_RTT_SHIFT;
3104 		net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT;
3105 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3106 			rto_logging(net, SCTP_LOG_INITIAL_RTT);
3107 		}
3108 	}
3109 	if (net->lastsv == 0) {
3110 		net->lastsv = SCTP_CLOCK_GRANULARITY;
3111 	}
3112 	new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
3113 	if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
3114 	    (stcb->asoc.sat_network_lockout == 0)) {
3115 		stcb->asoc.sat_network = 1;
3116 	} else if ((!first_measure) && stcb->asoc.sat_network) {
3117 		stcb->asoc.sat_network = 0;
3118 		stcb->asoc.sat_network_lockout = 1;
3119 	}
3120 	/* bound it, per C6/C7 in Section 5.3.1 */
3121 	if (new_rto < stcb->asoc.minrto) {
3122 		new_rto = stcb->asoc.minrto;
3123 	}
3124 	if (new_rto > stcb->asoc.maxrto) {
3125 		new_rto = stcb->asoc.maxrto;
3126 	}
3127 	net->RTO = new_rto;
3128 	return (1);
3129 }
3130 
3131 /*
3132  * return a pointer to a contiguous piece of data from the given mbuf chain
3133  * starting at 'off' for 'len' bytes.  If the desired piece spans more than
3134  * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size
3135  * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain.
3136  */
3137 caddr_t
sctp_m_getptr(struct mbuf * m,int off,int len,uint8_t * in_ptr)3138 sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr)
3139 {
3140 	uint32_t count;
3141 	uint8_t *ptr;
3142 
3143 	ptr = in_ptr;
3144 	if ((off < 0) || (len <= 0))
3145 		return (NULL);
3146 
3147 	/* find the desired start location */
3148 	while ((m != NULL) && (off > 0)) {
3149 		if (off < SCTP_BUF_LEN(m))
3150 			break;
3151 		off -= SCTP_BUF_LEN(m);
3152 		m = SCTP_BUF_NEXT(m);
3153 	}
3154 	if (m == NULL)
3155 		return (NULL);
3156 
3157 	/* is the current mbuf large enough (eg. contiguous)? */
3158 	if ((SCTP_BUF_LEN(m) - off) >= len) {
3159 		return (mtod(m, caddr_t) + off);
3160 	} else {
3161 		/* else, it spans more than one mbuf, so save a temp copy... */
3162 		while ((m != NULL) && (len > 0)) {
3163 			count = min(SCTP_BUF_LEN(m) - off, len);
3164 			memcpy(ptr, mtod(m, caddr_t) + off, count);
3165 			len -= count;
3166 			ptr += count;
3167 			off = 0;
3168 			m = SCTP_BUF_NEXT(m);
3169 		}
3170 		if ((m == NULL) && (len > 0))
3171 			return (NULL);
3172 		else
3173 			return ((caddr_t)in_ptr);
3174 	}
3175 }
3176 
3177 
3178 
3179 struct sctp_paramhdr *
sctp_get_next_param(struct mbuf * m,int offset,struct sctp_paramhdr * pull,int pull_limit)3180 sctp_get_next_param(struct mbuf *m,
3181     int offset,
3182     struct sctp_paramhdr *pull,
3183     int pull_limit)
3184 {
3185 	/* This just provides a typed signature to Peter's Pull routine */
3186 	return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
3187 	    (uint8_t *) pull));
3188 }
3189 
3190 
3191 struct mbuf *
sctp_add_pad_tombuf(struct mbuf * m,int padlen)3192 sctp_add_pad_tombuf(struct mbuf *m, int padlen)
3193 {
3194 	struct mbuf *m_last;
3195 	caddr_t dp;
3196 
3197 	if (padlen > 3) {
3198 		return (NULL);
3199 	}
3200 	if (padlen <= M_TRAILINGSPACE(m)) {
3201 		/*
3202 		 * The easy way. We hope the majority of the time we hit
3203 		 * here :)
3204 		 */
3205 		m_last = m;
3206 	} else {
3207 		/* Hard way we must grow the mbuf chain */
3208 		m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
3209 		if (m_last == NULL) {
3210 			return (NULL);
3211 		}
3212 		SCTP_BUF_LEN(m_last) = 0;
3213 		SCTP_BUF_NEXT(m_last) = NULL;
3214 		SCTP_BUF_NEXT(m) = m_last;
3215 	}
3216 	dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
3217 	SCTP_BUF_LEN(m_last) += padlen;
3218 	memset(dp, 0, padlen);
3219 	return (m_last);
3220 }
3221 
3222 struct mbuf *
sctp_pad_lastmbuf(struct mbuf * m,int padval,struct mbuf * last_mbuf)3223 sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
3224 {
3225 	/* find the last mbuf in chain and pad it */
3226 	struct mbuf *m_at;
3227 
3228 	if (last_mbuf != NULL) {
3229 		return (sctp_add_pad_tombuf(last_mbuf, padval));
3230 	} else {
3231 		for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
3232 			if (SCTP_BUF_NEXT(m_at) == NULL) {
3233 				return (sctp_add_pad_tombuf(m_at, padval));
3234 			}
3235 		}
3236 	}
3237 	return (NULL);
3238 }
3239 
3240 static void
sctp_notify_assoc_change(uint16_t state,struct sctp_tcb * stcb,uint16_t error,struct sctp_abort_chunk * abort,uint8_t from_peer,int so_locked SCTP_UNUSED)3241 sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
3242     uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked
3243 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3244     SCTP_UNUSED
3245 #endif
3246     )
3247 {
3248 	struct mbuf *m_notify;
3249 	struct sctp_assoc_change *sac;
3250 	struct sctp_queued_to_read *control;
3251 	unsigned int notif_len;
3252 	uint16_t abort_len;
3253 	unsigned int i;
3254 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3255 	struct socket *so;
3256 #endif
3257 
3258 	if (stcb == NULL) {
3259 		return;
3260 	}
3261 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
3262 		notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
3263 		if (abort != NULL) {
3264 			abort_len = ntohs(abort->ch.chunk_length);
3265 			/*
3266 			 * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
3267 			 * contiguous.
3268 			 */
3269 			if (abort_len > SCTP_CHUNK_BUFFER_SIZE) {
3270 				abort_len = SCTP_CHUNK_BUFFER_SIZE;
3271 			}
3272 		} else {
3273 			abort_len = 0;
3274 		}
3275 		if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3276 			notif_len += SCTP_ASSOC_SUPPORTS_MAX;
3277 		} else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3278 			notif_len += abort_len;
3279 		}
3280 		m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
3281 		if (m_notify == NULL) {
3282 			/* Retry with smaller value. */
3283 			notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
3284 			m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
3285 			if (m_notify == NULL) {
3286 				goto set_error;
3287 			}
3288 		}
3289 		SCTP_BUF_NEXT(m_notify) = NULL;
3290 		sac = mtod(m_notify, struct sctp_assoc_change *);
3291 		memset(sac, 0, notif_len);
3292 		sac->sac_type = SCTP_ASSOC_CHANGE;
3293 		sac->sac_flags = 0;
3294 		sac->sac_length = sizeof(struct sctp_assoc_change);
3295 		sac->sac_state = state;
3296 		sac->sac_error = error;
3297 		/* XXX verify these stream counts */
3298 		sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
3299 		sac->sac_inbound_streams = stcb->asoc.streamincnt;
3300 		sac->sac_assoc_id = sctp_get_associd(stcb);
3301 		if (notif_len > sizeof(struct sctp_assoc_change)) {
3302 			if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3303 				i = 0;
3304 				if (stcb->asoc.prsctp_supported == 1) {
3305 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
3306 				}
3307 				if (stcb->asoc.auth_supported == 1) {
3308 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
3309 				}
3310 				if (stcb->asoc.asconf_supported == 1) {
3311 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
3312 				}
3313 				if (stcb->asoc.idata_supported == 1) {
3314 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_INTERLEAVING;
3315 				}
3316 				sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
3317 				if (stcb->asoc.reconfig_supported == 1) {
3318 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
3319 				}
3320 				sac->sac_length += i;
3321 			} else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3322 				memcpy(sac->sac_info, abort, abort_len);
3323 				sac->sac_length += abort_len;
3324 			}
3325 		}
3326 		SCTP_BUF_LEN(m_notify) = sac->sac_length;
3327 		control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3328 		                                 0, 0, stcb->asoc.context, 0, 0, 0,
3329 		                                 m_notify);
3330 		if (control != NULL) {
3331 			control->length = SCTP_BUF_LEN(m_notify);
3332 			control->spec_flags = M_NOTIFICATION;
3333 			/* not that we need this */
3334 			control->tail_mbuf = m_notify;
3335 			sctp_add_to_readq(stcb->sctp_ep, stcb,
3336 			                  control,
3337 			                  &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
3338 			                  so_locked);
3339 		} else {
3340 			sctp_m_freem(m_notify);
3341 		}
3342 	}
3343 	/*
3344 	 * For 1-to-1 style sockets, we send up and error when an ABORT
3345 	 * comes in.
3346 	 */
3347 set_error:
3348 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3349 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3350 	    ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3351 		SOCK_LOCK(stcb->sctp_socket);
3352 		if (from_peer) {
3353 			if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) {
3354 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
3355 				stcb->sctp_socket->so_error = ECONNREFUSED;
3356 			} else {
3357 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
3358 				stcb->sctp_socket->so_error = ECONNRESET;
3359 			}
3360 		} else {
3361 			if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
3362 			    (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
3363 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT);
3364 				stcb->sctp_socket->so_error = ETIMEDOUT;
3365 			} else {
3366 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
3367 				stcb->sctp_socket->so_error = ECONNABORTED;
3368 			}
3369 		}
3370 		SOCK_UNLOCK(stcb->sctp_socket);
3371 	}
3372 	/* Wake ANY sleepers */
3373 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3374 	so = SCTP_INP_SO(stcb->sctp_ep);
3375 	if (!so_locked) {
3376 		atomic_add_int(&stcb->asoc.refcnt, 1);
3377 		SCTP_TCB_UNLOCK(stcb);
3378 		SCTP_SOCKET_LOCK(so, 1);
3379 		SCTP_TCB_LOCK(stcb);
3380 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
3381 		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3382 			SCTP_SOCKET_UNLOCK(so, 1);
3383 			return;
3384 		}
3385 	}
3386 #endif
3387 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3388 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3389 	    ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3390 		socantrcvmore(stcb->sctp_socket);
3391 	}
3392 	sorwakeup(stcb->sctp_socket);
3393 	sowwakeup(stcb->sctp_socket);
3394 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3395 	if (!so_locked) {
3396 		SCTP_SOCKET_UNLOCK(so, 1);
3397 	}
3398 #endif
3399 }
3400 
3401 static void
sctp_notify_peer_addr_change(struct sctp_tcb * stcb,uint32_t state,struct sockaddr * sa,uint32_t error,int so_locked SCTP_UNUSED)3402 sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
3403     struct sockaddr *sa, uint32_t error, int so_locked
3404 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3405     SCTP_UNUSED
3406 #endif
3407 )
3408 {
3409 	struct mbuf *m_notify;
3410 	struct sctp_paddr_change *spc;
3411 	struct sctp_queued_to_read *control;
3412 
3413 	if ((stcb == NULL) ||
3414 	    sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) {
3415 		/* event not enabled */
3416 		return;
3417 	}
3418 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA);
3419 	if (m_notify == NULL)
3420 		return;
3421 	SCTP_BUF_LEN(m_notify) = 0;
3422 	spc = mtod(m_notify, struct sctp_paddr_change *);
3423 	memset(spc, 0, sizeof(struct sctp_paddr_change));
3424 	spc->spc_type = SCTP_PEER_ADDR_CHANGE;
3425 	spc->spc_flags = 0;
3426 	spc->spc_length = sizeof(struct sctp_paddr_change);
3427 	switch (sa->sa_family) {
3428 #ifdef INET
3429 	case AF_INET:
3430 #ifdef INET6
3431 		if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
3432 			in6_sin_2_v4mapsin6((struct sockaddr_in *)sa,
3433 			                    (struct sockaddr_in6 *)&spc->spc_aaddr);
3434 		} else {
3435 			memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3436 		}
3437 #else
3438 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3439 #endif
3440 		break;
3441 #endif
3442 #ifdef INET6
3443 	case AF_INET6:
3444 	{
3445 #ifdef SCTP_EMBEDDED_V6_SCOPE
3446 		struct sockaddr_in6 *sin6;
3447 #endif /* SCTP_EMBEDDED_V6_SCOPE */
3448 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
3449 
3450 #ifdef SCTP_EMBEDDED_V6_SCOPE
3451 		sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
3452 		if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3453 			if (sin6->sin6_scope_id == 0) {
3454 				/* recover scope_id for user */
3455 #ifdef SCTP_KAME
3456 				(void)sa6_recoverscope(sin6);
3457 #else
3458 				(void)in6_recoverscope(sin6, &sin6->sin6_addr,
3459 						       NULL);
3460 #endif
3461 			} else {
3462 				/* clear embedded scope_id for user */
3463 				in6_clearscope(&sin6->sin6_addr);
3464 			}
3465 		}
3466 #endif /* SCTP_EMBEDDED_V6_SCOPE */
3467 		break;
3468 	}
3469 #endif
3470 #if defined(__Userspace__)
3471 	case AF_CONN:
3472 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_conn));
3473 		break;
3474 #endif
3475 	default:
3476 		/* TSNH */
3477 		break;
3478 	}
3479 	spc->spc_state = state;
3480 	spc->spc_error = error;
3481 	spc->spc_assoc_id = sctp_get_associd(stcb);
3482 
3483 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change);
3484 	SCTP_BUF_NEXT(m_notify) = NULL;
3485 
3486 	/* append to socket */
3487 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3488 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3489 	                                 m_notify);
3490 	if (control == NULL) {
3491 		/* no memory */
3492 		sctp_m_freem(m_notify);
3493 		return;
3494 	}
3495 	control->length = SCTP_BUF_LEN(m_notify);
3496 	control->spec_flags = M_NOTIFICATION;
3497 	/* not that we need this */
3498 	control->tail_mbuf = m_notify;
3499 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3500 	                  control,
3501 	                  &stcb->sctp_socket->so_rcv, 1,
3502 	                  SCTP_READ_LOCK_NOT_HELD,
3503 	                  so_locked);
3504 }
3505 
3506 
3507 static void
sctp_notify_send_failed(struct sctp_tcb * stcb,uint8_t sent,uint32_t error,struct sctp_tmit_chunk * chk,int so_locked SCTP_UNUSED)3508 sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
3509     struct sctp_tmit_chunk *chk, int so_locked
3510 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3511     SCTP_UNUSED
3512 #endif
3513     )
3514 {
3515 	struct mbuf *m_notify;
3516 	struct sctp_send_failed *ssf;
3517 	struct sctp_send_failed_event *ssfe;
3518 	struct sctp_queued_to_read *control;
3519 	struct sctp_chunkhdr *chkhdr;
3520 	int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len;
3521 
3522 	if ((stcb == NULL) ||
3523 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
3524 	     sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
3525 		/* event not enabled */
3526 		return;
3527 	}
3528 
3529 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3530 		notifhdr_len = sizeof(struct sctp_send_failed_event);
3531 	} else {
3532 		notifhdr_len = sizeof(struct sctp_send_failed);
3533 	}
3534 	m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3535 	if (m_notify == NULL)
3536 		/* no space left */
3537 		return;
3538 	SCTP_BUF_LEN(m_notify) = notifhdr_len;
3539 	if (stcb->asoc.idata_supported) {
3540 		chkhdr_len = sizeof(struct sctp_idata_chunk);
3541 	} else {
3542 		chkhdr_len = sizeof(struct sctp_data_chunk);
3543 	}
3544 	/* Use some defaults in case we can't access the chunk header */
3545 	if (chk->send_size >= chkhdr_len) {
3546 		payload_len = chk->send_size - chkhdr_len;
3547 	} else {
3548 		payload_len = 0;
3549 	}
3550 	padding_len = 0;
3551 	if (chk->data != NULL) {
3552 		chkhdr = mtod(chk->data, struct sctp_chunkhdr *);
3553 		if (chkhdr != NULL) {
3554 			chk_len = ntohs(chkhdr->chunk_length);
3555 			if ((chk_len >= chkhdr_len) &&
3556 			    (chk->send_size >= chk_len) &&
3557 			    (chk->send_size - chk_len < 4)) {
3558 				padding_len = chk->send_size - chk_len;
3559 				payload_len = chk->send_size - chkhdr_len - padding_len;
3560 			}
3561 		}
3562 	}
3563 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3564 		ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3565 		memset(ssfe, 0, notifhdr_len);
3566 		ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3567 		if (sent) {
3568 			ssfe->ssfe_flags = SCTP_DATA_SENT;
3569 		} else {
3570 			ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3571 		}
3572 		ssfe->ssfe_length = (uint32_t)(notifhdr_len + payload_len);
3573 		ssfe->ssfe_error = error;
3574 		/* not exactly what the user sent in, but should be close :) */
3575 		ssfe->ssfe_info.snd_sid = chk->rec.data.sid;
3576 		ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
3577 		ssfe->ssfe_info.snd_ppid = chk->rec.data.ppid;
3578 		ssfe->ssfe_info.snd_context = chk->rec.data.context;
3579 		ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3580 		ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3581 	} else {
3582 		ssf = mtod(m_notify, struct sctp_send_failed *);
3583 		memset(ssf, 0, notifhdr_len);
3584 		ssf->ssf_type = SCTP_SEND_FAILED;
3585 		if (sent) {
3586 			ssf->ssf_flags = SCTP_DATA_SENT;
3587 		} else {
3588 			ssf->ssf_flags = SCTP_DATA_UNSENT;
3589 		}
3590 		ssf->ssf_length = (uint32_t)(notifhdr_len + payload_len);
3591 		ssf->ssf_error = error;
3592 		/* not exactly what the user sent in, but should be close :) */
3593 		ssf->ssf_info.sinfo_stream = chk->rec.data.sid;
3594 		ssf->ssf_info.sinfo_ssn = (uint16_t)chk->rec.data.mid;
3595 		ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
3596 		ssf->ssf_info.sinfo_ppid = chk->rec.data.ppid;
3597 		ssf->ssf_info.sinfo_context = chk->rec.data.context;
3598 		ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3599 		ssf->ssf_assoc_id = sctp_get_associd(stcb);
3600 	}
3601 	if (chk->data != NULL) {
3602 		/* Trim off the sctp chunk header (it should be there) */
3603 		if (chk->send_size == chkhdr_len + payload_len + padding_len) {
3604 			m_adj(chk->data, chkhdr_len);
3605 			m_adj(chk->data, -padding_len);
3606 			sctp_mbuf_crush(chk->data);
3607 			chk->send_size -= (chkhdr_len + padding_len);
3608 		}
3609 	}
3610 	SCTP_BUF_NEXT(m_notify) = chk->data;
3611 	/* Steal off the mbuf */
3612 	chk->data = NULL;
3613 	/*
3614 	 * For this case, we check the actual socket buffer, since the assoc
3615 	 * is going away we don't want to overfill the socket buffer for a
3616 	 * non-reader
3617 	 */
3618 	if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3619 		sctp_m_freem(m_notify);
3620 		return;
3621 	}
3622 	/* append to socket */
3623 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3624 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3625 	                                 m_notify);
3626 	if (control == NULL) {
3627 		/* no memory */
3628 		sctp_m_freem(m_notify);
3629 		return;
3630 	}
3631 	control->length = SCTP_BUF_LEN(m_notify);
3632 	control->spec_flags = M_NOTIFICATION;
3633 	/* not that we need this */
3634 	control->tail_mbuf = m_notify;
3635 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3636 	                  control,
3637 	                  &stcb->sctp_socket->so_rcv, 1,
3638 	                  SCTP_READ_LOCK_NOT_HELD,
3639 	                  so_locked);
3640 }
3641 
3642 
3643 static void
sctp_notify_send_failed2(struct sctp_tcb * stcb,uint32_t error,struct sctp_stream_queue_pending * sp,int so_locked SCTP_UNUSED)3644 sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
3645 			 struct sctp_stream_queue_pending *sp, int so_locked
3646 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3647                          SCTP_UNUSED
3648 #endif
3649                          )
3650 {
3651 	struct mbuf *m_notify;
3652 	struct sctp_send_failed *ssf;
3653 	struct sctp_send_failed_event *ssfe;
3654 	struct sctp_queued_to_read *control;
3655 	int notifhdr_len;
3656 
3657 	if ((stcb == NULL) ||
3658 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
3659 	     sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
3660 		/* event not enabled */
3661 		return;
3662 	}
3663 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3664 		notifhdr_len = sizeof(struct sctp_send_failed_event);
3665 	} else {
3666 		notifhdr_len = sizeof(struct sctp_send_failed);
3667 	}
3668 	m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3669 	if (m_notify == NULL) {
3670 		/* no space left */
3671 		return;
3672 	}
3673 	SCTP_BUF_LEN(m_notify) = notifhdr_len;
3674 	if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3675 		ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3676 		memset(ssfe, 0, notifhdr_len);
3677 		ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3678 		ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3679 		ssfe->ssfe_length = (uint32_t)(notifhdr_len + sp->length);
3680 		ssfe->ssfe_error = error;
3681 		/* not exactly what the user sent in, but should be close :) */
3682 		ssfe->ssfe_info.snd_sid = sp->sid;
3683 		if (sp->some_taken) {
3684 			ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
3685 		} else {
3686 			ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG;
3687 		}
3688 		ssfe->ssfe_info.snd_ppid = sp->ppid;
3689 		ssfe->ssfe_info.snd_context = sp->context;
3690 		ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3691 		ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3692 	} else {
3693 		ssf = mtod(m_notify, struct sctp_send_failed *);
3694 		memset(ssf, 0, notifhdr_len);
3695 		ssf->ssf_type = SCTP_SEND_FAILED;
3696 		ssf->ssf_flags = SCTP_DATA_UNSENT;
3697 		ssf->ssf_length = (uint32_t)(notifhdr_len + sp->length);
3698 		ssf->ssf_error = error;
3699 		/* not exactly what the user sent in, but should be close :) */
3700 		ssf->ssf_info.sinfo_stream = sp->sid;
3701 		ssf->ssf_info.sinfo_ssn = 0;
3702 		if (sp->some_taken) {
3703 			ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
3704 		} else {
3705 			ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG;
3706 		}
3707 		ssf->ssf_info.sinfo_ppid = sp->ppid;
3708 		ssf->ssf_info.sinfo_context = sp->context;
3709 		ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3710 		ssf->ssf_assoc_id = sctp_get_associd(stcb);
3711 	}
3712 	SCTP_BUF_NEXT(m_notify) = sp->data;
3713 
3714 	/* Steal off the mbuf */
3715 	sp->data = NULL;
3716 	/*
3717 	 * For this case, we check the actual socket buffer, since the assoc
3718 	 * is going away we don't want to overfill the socket buffer for a
3719 	 * non-reader
3720 	 */
3721 	if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3722 		sctp_m_freem(m_notify);
3723 		return;
3724 	}
3725 	/* append to socket */
3726 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3727 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3728 	                                 m_notify);
3729 	if (control == NULL) {
3730 		/* no memory */
3731 		sctp_m_freem(m_notify);
3732 		return;
3733 	}
3734 	control->length = SCTP_BUF_LEN(m_notify);
3735 	control->spec_flags = M_NOTIFICATION;
3736 	/* not that we need this */
3737 	control->tail_mbuf = m_notify;
3738 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3739 	    control,
3740 	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
3741 }
3742 
3743 
3744 
3745 static void
sctp_notify_adaptation_layer(struct sctp_tcb * stcb)3746 sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
3747 {
3748 	struct mbuf *m_notify;
3749 	struct sctp_adaptation_event *sai;
3750 	struct sctp_queued_to_read *control;
3751 
3752 	if ((stcb == NULL) ||
3753 	    sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) {
3754 		/* event not enabled */
3755 		return;
3756 	}
3757 
3758 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_NOWAIT, 1, MT_DATA);
3759 	if (m_notify == NULL)
3760 		/* no space left */
3761 		return;
3762 	SCTP_BUF_LEN(m_notify) = 0;
3763 	sai = mtod(m_notify, struct sctp_adaptation_event *);
3764 	memset(sai, 0, sizeof(struct sctp_adaptation_event));
3765 	sai->sai_type = SCTP_ADAPTATION_INDICATION;
3766 	sai->sai_flags = 0;
3767 	sai->sai_length = sizeof(struct sctp_adaptation_event);
3768 	sai->sai_adaptation_ind = stcb->asoc.peers_adaptation;
3769 	sai->sai_assoc_id = sctp_get_associd(stcb);
3770 
3771 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event);
3772 	SCTP_BUF_NEXT(m_notify) = NULL;
3773 
3774 	/* append to socket */
3775 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3776 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3777 	                                 m_notify);
3778 	if (control == NULL) {
3779 		/* no memory */
3780 		sctp_m_freem(m_notify);
3781 		return;
3782 	}
3783 	control->length = SCTP_BUF_LEN(m_notify);
3784 	control->spec_flags = M_NOTIFICATION;
3785 	/* not that we need this */
3786 	control->tail_mbuf = m_notify;
3787 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3788 	    control,
3789 	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
3790 }
3791 
3792 /* This always must be called with the read-queue LOCKED in the INP */
3793 static void
sctp_notify_partial_delivery_indication(struct sctp_tcb * stcb,uint32_t error,uint32_t val,int so_locked SCTP_UNUSED)3794 sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
3795 					uint32_t val, int so_locked
3796 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3797                              SCTP_UNUSED
3798 #endif
3799                                         )
3800 {
3801 	struct mbuf *m_notify;
3802 	struct sctp_pdapi_event *pdapi;
3803 	struct sctp_queued_to_read *control;
3804 	struct sockbuf *sb;
3805 
3806 	if ((stcb == NULL) ||
3807 	    sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) {
3808 		/* event not enabled */
3809 		return;
3810 	}
3811 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
3812 		return;
3813 	}
3814 
3815 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA);
3816 	if (m_notify == NULL)
3817 		/* no space left */
3818 		return;
3819 	SCTP_BUF_LEN(m_notify) = 0;
3820 	pdapi = mtod(m_notify, struct sctp_pdapi_event *);
3821 	memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
3822 	pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
3823 	pdapi->pdapi_flags = 0;
3824 	pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
3825 	pdapi->pdapi_indication = error;
3826 	pdapi->pdapi_stream = (val >> 16);
3827 	pdapi->pdapi_seq = (val & 0x0000ffff);
3828 	pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
3829 
3830 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
3831 	SCTP_BUF_NEXT(m_notify) = NULL;
3832 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3833 					 0, 0, stcb->asoc.context, 0, 0, 0,
3834 					 m_notify);
3835 	if (control == NULL) {
3836 		/* no memory */
3837 		sctp_m_freem(m_notify);
3838 		return;
3839 	}
3840 	control->length = SCTP_BUF_LEN(m_notify);
3841 	control->spec_flags = M_NOTIFICATION;
3842 	/* not that we need this */
3843 	control->tail_mbuf = m_notify;
3844 	sb = &stcb->sctp_socket->so_rcv;
3845 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
3846 		sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify));
3847 	}
3848 	sctp_sballoc(stcb, sb, m_notify);
3849 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
3850 		sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
3851 	}
3852 	control->end_added = 1;
3853 	if (stcb->asoc.control_pdapi)
3854 		TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi,  control, next);
3855 	else {
3856 		/* we really should not see this case */
3857 		TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next);
3858 	}
3859 	if (stcb->sctp_ep && stcb->sctp_socket) {
3860 		/* This should always be the case */
3861 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3862 		struct socket *so;
3863 
3864 		so = SCTP_INP_SO(stcb->sctp_ep);
3865 		if (!so_locked) {
3866 			atomic_add_int(&stcb->asoc.refcnt, 1);
3867 			SCTP_TCB_UNLOCK(stcb);
3868 			SCTP_SOCKET_LOCK(so, 1);
3869 			SCTP_TCB_LOCK(stcb);
3870 			atomic_subtract_int(&stcb->asoc.refcnt, 1);
3871 			if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
3872 				SCTP_SOCKET_UNLOCK(so, 1);
3873 				return;
3874 			}
3875 		}
3876 #endif
3877 		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
3878 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3879 		if (!so_locked) {
3880 			SCTP_SOCKET_UNLOCK(so, 1);
3881 		}
3882 #endif
3883 	}
3884 }
3885 
3886 static void
sctp_notify_shutdown_event(struct sctp_tcb * stcb)3887 sctp_notify_shutdown_event(struct sctp_tcb *stcb)
3888 {
3889 	struct mbuf *m_notify;
3890 	struct sctp_shutdown_event *sse;
3891 	struct sctp_queued_to_read *control;
3892 
3893 	/*
3894 	 * For TCP model AND UDP connected sockets we will send an error up
3895 	 * when an SHUTDOWN completes
3896 	 */
3897 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3898 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
3899 		/* mark socket closed for read/write and wakeup! */
3900 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3901 		struct socket *so;
3902 
3903 		so = SCTP_INP_SO(stcb->sctp_ep);
3904 		atomic_add_int(&stcb->asoc.refcnt, 1);
3905 		SCTP_TCB_UNLOCK(stcb);
3906 		SCTP_SOCKET_LOCK(so, 1);
3907 		SCTP_TCB_LOCK(stcb);
3908 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
3909 		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3910 			SCTP_SOCKET_UNLOCK(so, 1);
3911 			return;
3912 		}
3913 #endif
3914 		socantsendmore(stcb->sctp_socket);
3915 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3916 		SCTP_SOCKET_UNLOCK(so, 1);
3917 #endif
3918 	}
3919 	if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) {
3920 		/* event not enabled */
3921 		return;
3922 	}
3923 
3924 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_NOWAIT, 1, MT_DATA);
3925 	if (m_notify == NULL)
3926 		/* no space left */
3927 		return;
3928 	sse = mtod(m_notify, struct sctp_shutdown_event *);
3929 	memset(sse, 0, sizeof(struct sctp_shutdown_event));
3930 	sse->sse_type = SCTP_SHUTDOWN_EVENT;
3931 	sse->sse_flags = 0;
3932 	sse->sse_length = sizeof(struct sctp_shutdown_event);
3933 	sse->sse_assoc_id = sctp_get_associd(stcb);
3934 
3935 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event);
3936 	SCTP_BUF_NEXT(m_notify) = NULL;
3937 
3938 	/* append to socket */
3939 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3940 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3941 	                                 m_notify);
3942 	if (control == NULL) {
3943 		/* no memory */
3944 		sctp_m_freem(m_notify);
3945 		return;
3946 	}
3947 	control->length = SCTP_BUF_LEN(m_notify);
3948 	control->spec_flags = M_NOTIFICATION;
3949 	/* not that we need this */
3950 	control->tail_mbuf = m_notify;
3951 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3952 	    control,
3953 	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
3954 }
3955 
3956 static void
sctp_notify_sender_dry_event(struct sctp_tcb * stcb,int so_locked SCTP_UNUSED)3957 sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
3958                              int so_locked
3959 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3960                              SCTP_UNUSED
3961 #endif
3962                              )
3963 {
3964 	struct mbuf *m_notify;
3965 	struct sctp_sender_dry_event *event;
3966 	struct sctp_queued_to_read *control;
3967 
3968 	if ((stcb == NULL) ||
3969 	    sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) {
3970 		/* event not enabled */
3971 		return;
3972 	}
3973 
3974 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_sender_dry_event), 0, M_NOWAIT, 1, MT_DATA);
3975 	if (m_notify == NULL) {
3976 		/* no space left */
3977 		return;
3978 	}
3979 	SCTP_BUF_LEN(m_notify) = 0;
3980 	event = mtod(m_notify, struct sctp_sender_dry_event *);
3981 	memset(event, 0, sizeof(struct sctp_sender_dry_event));
3982 	event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
3983 	event->sender_dry_flags = 0;
3984 	event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
3985 	event->sender_dry_assoc_id = sctp_get_associd(stcb);
3986 
3987 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_sender_dry_event);
3988 	SCTP_BUF_NEXT(m_notify) = NULL;
3989 
3990 	/* append to socket */
3991 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3992 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
3993 	                                 m_notify);
3994 	if (control == NULL) {
3995 		/* no memory */
3996 		sctp_m_freem(m_notify);
3997 		return;
3998 	}
3999 	control->length = SCTP_BUF_LEN(m_notify);
4000 	control->spec_flags = M_NOTIFICATION;
4001 	/* not that we need this */
4002 	control->tail_mbuf = m_notify;
4003 	sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4004 	                  &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
4005 }
4006 
4007 
4008 void
sctp_notify_stream_reset_add(struct sctp_tcb * stcb,uint16_t numberin,uint16_t numberout,int flag)4009 sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t numberout, int flag)
4010 {
4011 	struct mbuf *m_notify;
4012 	struct sctp_queued_to_read *control;
4013 	struct sctp_stream_change_event *stradd;
4014 
4015 	if ((stcb == NULL) ||
4016 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
4017 		/* event not enabled */
4018 		return;
4019 	}
4020 	if ((stcb->asoc.peer_req_out) && flag) {
4021 		/* Peer made the request, don't tell the local user */
4022 		stcb->asoc.peer_req_out = 0;
4023 		return;
4024 	}
4025 	stcb->asoc.peer_req_out = 0;
4026 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
4027 	if (m_notify == NULL)
4028 		/* no space left */
4029 		return;
4030 	SCTP_BUF_LEN(m_notify) = 0;
4031 	stradd = mtod(m_notify, struct sctp_stream_change_event *);
4032 	memset(stradd, 0, sizeof(struct sctp_stream_change_event));
4033 	stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
4034 	stradd->strchange_flags = flag;
4035 	stradd->strchange_length = sizeof(struct sctp_stream_change_event);
4036 	stradd->strchange_assoc_id = sctp_get_associd(stcb);
4037 	stradd->strchange_instrms = numberin;
4038 	stradd->strchange_outstrms = numberout;
4039 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
4040 	SCTP_BUF_NEXT(m_notify) = NULL;
4041 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4042 		/* no space */
4043 		sctp_m_freem(m_notify);
4044 		return;
4045 	}
4046 	/* append to socket */
4047 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4048 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
4049 	                                 m_notify);
4050 	if (control == NULL) {
4051 		/* no memory */
4052 		sctp_m_freem(m_notify);
4053 		return;
4054 	}
4055 	control->length = SCTP_BUF_LEN(m_notify);
4056 	control->spec_flags = M_NOTIFICATION;
4057 	/* not that we need this */
4058 	control->tail_mbuf = m_notify;
4059 	sctp_add_to_readq(stcb->sctp_ep, stcb,
4060 	    control,
4061 	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4062 }
4063 
4064 void
sctp_notify_stream_reset_tsn(struct sctp_tcb * stcb,uint32_t sending_tsn,uint32_t recv_tsn,int flag)4065 sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag)
4066 {
4067 	struct mbuf *m_notify;
4068 	struct sctp_queued_to_read *control;
4069 	struct sctp_assoc_reset_event *strasoc;
4070 
4071 	if ((stcb == NULL) ||
4072 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
4073 		/* event not enabled */
4074 		return;
4075 	}
4076 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
4077 	if (m_notify == NULL)
4078 		/* no space left */
4079 		return;
4080 	SCTP_BUF_LEN(m_notify) = 0;
4081 	strasoc = mtod(m_notify, struct sctp_assoc_reset_event  *);
4082 	memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
4083 	strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
4084 	strasoc->assocreset_flags = flag;
4085 	strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
4086 	strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
4087 	strasoc->assocreset_local_tsn = sending_tsn;
4088 	strasoc->assocreset_remote_tsn = recv_tsn;
4089 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
4090 	SCTP_BUF_NEXT(m_notify) = NULL;
4091 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4092 		/* no space */
4093 		sctp_m_freem(m_notify);
4094 		return;
4095 	}
4096 	/* append to socket */
4097 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4098 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
4099 	                                 m_notify);
4100 	if (control == NULL) {
4101 		/* no memory */
4102 		sctp_m_freem(m_notify);
4103 		return;
4104 	}
4105 	control->length = SCTP_BUF_LEN(m_notify);
4106 	control->spec_flags = M_NOTIFICATION;
4107 	/* not that we need this */
4108 	control->tail_mbuf = m_notify;
4109 	sctp_add_to_readq(stcb->sctp_ep, stcb,
4110 	    control,
4111 	    &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4112 }
4113 
4114 
4115 
4116 static void
sctp_notify_stream_reset(struct sctp_tcb * stcb,int number_entries,uint16_t * list,int flag)4117 sctp_notify_stream_reset(struct sctp_tcb *stcb,
4118     int number_entries, uint16_t * list, int flag)
4119 {
4120 	struct mbuf *m_notify;
4121 	struct sctp_queued_to_read *control;
4122 	struct sctp_stream_reset_event *strreset;
4123 	int len;
4124 
4125 	if ((stcb == NULL) ||
4126 	    (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) {
4127 		/* event not enabled */
4128 		return;
4129 	}
4130 
4131 	m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
4132 	if (m_notify == NULL)
4133 		/* no space left */
4134 		return;
4135 	SCTP_BUF_LEN(m_notify) = 0;
4136 	len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
4137 	if (len > M_TRAILINGSPACE(m_notify)) {
4138 		/* never enough room */
4139 		sctp_m_freem(m_notify);
4140 		return;
4141 	}
4142 	strreset = mtod(m_notify, struct sctp_stream_reset_event *);
4143 	memset(strreset, 0, len);
4144 	strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
4145 	strreset->strreset_flags = flag;
4146 	strreset->strreset_length = len;
4147 	strreset->strreset_assoc_id = sctp_get_associd(stcb);
4148 	if (number_entries) {
4149 		int i;
4150 
4151 		for (i = 0; i < number_entries; i++) {
4152 			strreset->strreset_stream_list[i] = ntohs(list[i]);
4153 		}
4154 	}
4155 	SCTP_BUF_LEN(m_notify) = len;
4156 	SCTP_BUF_NEXT(m_notify) = NULL;
4157 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4158 		/* no space */
4159 		sctp_m_freem(m_notify);
4160 		return;
4161 	}
4162 	/* append to socket */
4163 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4164 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
4165 	                                 m_notify);
4166 	if (control == NULL) {
4167 		/* no memory */
4168 		sctp_m_freem(m_notify);
4169 		return;
4170 	}
4171 	control->length = SCTP_BUF_LEN(m_notify);
4172 	control->spec_flags = M_NOTIFICATION;
4173 	/* not that we need this */
4174 	control->tail_mbuf = m_notify;
4175 	sctp_add_to_readq(stcb->sctp_ep, stcb,
4176 	                  control,
4177 	                  &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4178 }
4179 
4180 
4181 static void
sctp_notify_remote_error(struct sctp_tcb * stcb,uint16_t error,struct sctp_error_chunk * chunk)4182 sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_error_chunk *chunk)
4183 {
4184 	struct mbuf *m_notify;
4185 	struct sctp_remote_error *sre;
4186 	struct sctp_queued_to_read *control;
4187 	unsigned int notif_len;
4188 	uint16_t chunk_len;
4189 
4190 	if ((stcb == NULL) ||
4191 	    sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) {
4192 		return;
4193 	}
4194 	if (chunk != NULL) {
4195 		chunk_len = ntohs(chunk->ch.chunk_length);
4196 		/*
4197 		 * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
4198 		 * contiguous.
4199 		 */
4200 		if (chunk_len > SCTP_CHUNK_BUFFER_SIZE) {
4201 			chunk_len = SCTP_CHUNK_BUFFER_SIZE;
4202 		}
4203 	} else {
4204 		chunk_len = 0;
4205 	}
4206 	notif_len = (unsigned int)(sizeof(struct sctp_remote_error) + chunk_len);
4207 	m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
4208 	if (m_notify == NULL) {
4209 		/* Retry with smaller value. */
4210 		notif_len = (unsigned int)sizeof(struct sctp_remote_error);
4211 		m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
4212 		if (m_notify == NULL) {
4213 			return;
4214 		}
4215 	}
4216 	SCTP_BUF_NEXT(m_notify) = NULL;
4217 	sre = mtod(m_notify, struct sctp_remote_error *);
4218 	memset(sre, 0, notif_len);
4219 	sre->sre_type = SCTP_REMOTE_ERROR;
4220 	sre->sre_flags = 0;
4221 	sre->sre_length = sizeof(struct sctp_remote_error);
4222 	sre->sre_error = error;
4223 	sre->sre_assoc_id = sctp_get_associd(stcb);
4224 	if (notif_len > sizeof(struct sctp_remote_error)) {
4225 		memcpy(sre->sre_data, chunk, chunk_len);
4226 		sre->sre_length += chunk_len;
4227 	}
4228 	SCTP_BUF_LEN(m_notify) = sre->sre_length;
4229 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4230 	                                 0, 0, stcb->asoc.context, 0, 0, 0,
4231 	                                 m_notify);
4232 	if (control != NULL) {
4233 		control->length = SCTP_BUF_LEN(m_notify);
4234 		control->spec_flags = M_NOTIFICATION;
4235 		/* not that we need this */
4236 		control->tail_mbuf = m_notify;
4237 		sctp_add_to_readq(stcb->sctp_ep, stcb,
4238 		                  control,
4239 		                  &stcb->sctp_socket->so_rcv, 1,
4240 				  SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4241 	} else {
4242 		sctp_m_freem(m_notify);
4243 	}
4244 }
4245 
4246 
4247 void
sctp_ulp_notify(uint32_t notification,struct sctp_tcb * stcb,uint32_t error,void * data,int so_locked SCTP_UNUSED)4248 sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
4249     uint32_t error, void *data, int so_locked
4250 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4251     SCTP_UNUSED
4252 #endif
4253     )
4254 {
4255 	if ((stcb == NULL) ||
4256 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4257 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4258 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
4259 		/* If the socket is gone we are out of here */
4260 		return;
4261 	}
4262 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
4263 	if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) {
4264 #else
4265 	if (stcb->sctp_socket->so_state & SS_CANTRCVMORE) {
4266 #endif
4267 		return;
4268 	}
4269 #if defined(__APPLE__)
4270 	if (so_locked) {
4271 		sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4272 	} else {
4273 		sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4274 	}
4275 #endif
4276 	if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4277 	    (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4278 		if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
4279 		    (notification == SCTP_NOTIFY_INTERFACE_UP) ||
4280 		    (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
4281 			/* Don't report these in front states */
4282 			return;
4283 		}
4284 	}
4285 	switch (notification) {
4286 	case SCTP_NOTIFY_ASSOC_UP:
4287 		if (stcb->asoc.assoc_up_sent == 0) {
4288 			sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked);
4289 			stcb->asoc.assoc_up_sent = 1;
4290 		}
4291 		if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
4292 			sctp_notify_adaptation_layer(stcb);
4293 		}
4294 		if (stcb->asoc.auth_supported == 0) {
4295 			sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
4296 			                NULL, so_locked);
4297 		}
4298 		break;
4299 	case SCTP_NOTIFY_ASSOC_DOWN:
4300 		sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked);
4301 #if defined(__Userspace__)
4302 		if (stcb->sctp_ep->recv_callback) {
4303 			if (stcb->sctp_socket) {
4304 				union sctp_sockstore addr;
4305 				struct sctp_rcvinfo rcv;
4306 
4307 				memset(&addr, 0, sizeof(union sctp_sockstore));
4308 				memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
4309 				atomic_add_int(&stcb->asoc.refcnt, 1);
4310 				SCTP_TCB_UNLOCK(stcb);
4311 				stcb->sctp_ep->recv_callback(stcb->sctp_socket, addr, NULL, 0, rcv, 0, stcb->sctp_ep->ulp_info);
4312 				SCTP_TCB_LOCK(stcb);
4313 				atomic_subtract_int(&stcb->asoc.refcnt, 1);
4314 			}
4315 		}
4316 #endif
4317 		break;
4318 	case SCTP_NOTIFY_INTERFACE_DOWN:
4319 		{
4320 			struct sctp_nets *net;
4321 
4322 			net = (struct sctp_nets *)data;
4323 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
4324 			    (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4325 			break;
4326 		}
4327 	case SCTP_NOTIFY_INTERFACE_UP:
4328 		{
4329 			struct sctp_nets *net;
4330 
4331 			net = (struct sctp_nets *)data;
4332 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
4333 			    (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4334 			break;
4335 		}
4336 	case SCTP_NOTIFY_INTERFACE_CONFIRMED:
4337 		{
4338 			struct sctp_nets *net;
4339 
4340 			net = (struct sctp_nets *)data;
4341 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
4342 			    (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4343 			break;
4344 		}
4345 	case SCTP_NOTIFY_SPECIAL_SP_FAIL:
4346 		sctp_notify_send_failed2(stcb, error,
4347 		                         (struct sctp_stream_queue_pending *)data, so_locked);
4348 		break;
4349 	case SCTP_NOTIFY_SENT_DG_FAIL:
4350 		sctp_notify_send_failed(stcb, 1, error,
4351 		    (struct sctp_tmit_chunk *)data, so_locked);
4352 		break;
4353 	case SCTP_NOTIFY_UNSENT_DG_FAIL:
4354 		sctp_notify_send_failed(stcb, 0, error,
4355 		                        (struct sctp_tmit_chunk *)data, so_locked);
4356 		break;
4357 	case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
4358 		{
4359 			uint32_t val;
4360 			val = *((uint32_t *)data);
4361 
4362 			sctp_notify_partial_delivery_indication(stcb, error, val, so_locked);
4363 		break;
4364 		}
4365 	case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
4366 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4367 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4368 			sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked);
4369 		} else {
4370 			sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked);
4371 		}
4372 		break;
4373 	case SCTP_NOTIFY_ASSOC_REM_ABORTED:
4374 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4375 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4376 			sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked);
4377 		} else {
4378 			sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked);
4379 		}
4380 		break;
4381 	case SCTP_NOTIFY_ASSOC_RESTART:
4382 		sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
4383 		if (stcb->asoc.auth_supported == 0) {
4384 			sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
4385 			                NULL, so_locked);
4386 		}
4387 		break;
4388 	case SCTP_NOTIFY_STR_RESET_SEND:
4389 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN);
4390 		break;
4391 	case SCTP_NOTIFY_STR_RESET_RECV:
4392 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING);
4393 		break;
4394 	case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
4395 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4396 		                         (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
4397 		break;
4398 	case SCTP_NOTIFY_STR_RESET_DENIED_OUT:
4399 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4400 		                         (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_DENIED));
4401 		break;
4402 	case SCTP_NOTIFY_STR_RESET_FAILED_IN:
4403 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4404 		                         (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
4405 		break;
4406 	case SCTP_NOTIFY_STR_RESET_DENIED_IN:
4407 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4408 		                         (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED));
4409 		break;
4410 	case SCTP_NOTIFY_ASCONF_ADD_IP:
4411 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
4412 		    error, so_locked);
4413 		break;
4414 	case SCTP_NOTIFY_ASCONF_DELETE_IP:
4415 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
4416 		                             error, so_locked);
4417 		break;
4418 	case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
4419 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
4420 		                             error, so_locked);
4421 		break;
4422 	case SCTP_NOTIFY_PEER_SHUTDOWN:
4423 		sctp_notify_shutdown_event(stcb);
4424 		break;
4425 	case SCTP_NOTIFY_AUTH_NEW_KEY:
4426 		sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error,
4427 		                           (uint16_t)(uintptr_t)data,
4428 		                           so_locked);
4429 		break;
4430 	case SCTP_NOTIFY_AUTH_FREE_KEY:
4431 		sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error,
4432 		                           (uint16_t)(uintptr_t)data,
4433 		                           so_locked);
4434 		break;
4435 	case SCTP_NOTIFY_NO_PEER_AUTH:
4436 		sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error,
4437 		                           (uint16_t)(uintptr_t)data,
4438 		                           so_locked);
4439 		break;
4440 	case SCTP_NOTIFY_SENDER_DRY:
4441 		sctp_notify_sender_dry_event(stcb, so_locked);
4442 		break;
4443 	case SCTP_NOTIFY_REMOTE_ERROR:
4444 		sctp_notify_remote_error(stcb, error, data);
4445 		break;
4446 	default:
4447 		SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n",
4448 			__func__, notification, notification);
4449 		break;
4450 	}			/* end switch */
4451 }
4452 
4453 void
4454 sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
4455 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4456     SCTP_UNUSED
4457 #endif
4458     )
4459 {
4460 	struct sctp_association *asoc;
4461 	struct sctp_stream_out *outs;
4462 	struct sctp_tmit_chunk *chk, *nchk;
4463 	struct sctp_stream_queue_pending *sp, *nsp;
4464 	int i;
4465 
4466 	if (stcb == NULL) {
4467 		return;
4468 	}
4469 	asoc = &stcb->asoc;
4470 	if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4471 		/* already being freed */
4472 		return;
4473 	}
4474 #if defined(__APPLE__)
4475 	if (so_locked) {
4476 		sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4477 	} else {
4478 		sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4479 	}
4480 #endif
4481 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4482 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4483 	    (asoc->state & SCTP_STATE_CLOSED_SOCKET)) {
4484 		return;
4485 	}
4486 	/* now through all the gunk freeing chunks */
4487 	if (holds_lock == 0) {
4488 		SCTP_TCB_SEND_LOCK(stcb);
4489 	}
4490 	/* sent queue SHOULD be empty */
4491 	TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
4492 		TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
4493 		asoc->sent_queue_cnt--;
4494 		if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
4495 			if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4496 				asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4497 #ifdef INVARIANTS
4498 			} else {
4499 				panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4500 #endif
4501 			}
4502 		}
4503 		if (chk->data != NULL) {
4504 			sctp_free_bufspace(stcb, asoc, chk, 1);
4505 			sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
4506 			                error, chk, so_locked);
4507 			if (chk->data) {
4508 				sctp_m_freem(chk->data);
4509 				chk->data = NULL;
4510 			}
4511 		}
4512 		sctp_free_a_chunk(stcb, chk, so_locked);
4513 		/*sa_ignore FREED_MEMORY*/
4514 	}
4515 	/* pending send queue SHOULD be empty */
4516 	TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
4517 		TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
4518 		asoc->send_queue_cnt--;
4519 		if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4520 			asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4521 #ifdef INVARIANTS
4522 		} else {
4523 			panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4524 #endif
4525 		}
4526 		if (chk->data != NULL) {
4527 			sctp_free_bufspace(stcb, asoc, chk, 1);
4528 			sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
4529 			                error, chk, so_locked);
4530 			if (chk->data) {
4531 				sctp_m_freem(chk->data);
4532 				chk->data = NULL;
4533 			}
4534 		}
4535 		sctp_free_a_chunk(stcb, chk, so_locked);
4536 		/*sa_ignore FREED_MEMORY*/
4537 	}
4538 	for (i = 0; i < asoc->streamoutcnt; i++) {
4539 		/* For each stream */
4540 		outs = &asoc->strmout[i];
4541 		/* clean up any sends there */
4542 		TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
4543 			atomic_subtract_int(&asoc->stream_queue_cnt, 1);
4544 			TAILQ_REMOVE(&outs->outqueue, sp, next);
4545 			stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 1);
4546 			sctp_free_spbufspace(stcb, asoc, sp);
4547 			if (sp->data) {
4548 				sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
4549 						error, (void *)sp, so_locked);
4550 				if (sp->data) {
4551 					sctp_m_freem(sp->data);
4552 					sp->data = NULL;
4553 					sp->tail_mbuf = NULL;
4554 					sp->length = 0;
4555 				}
4556 			}
4557 			if (sp->net) {
4558 				sctp_free_remote_addr(sp->net);
4559 				sp->net = NULL;
4560 			}
4561 			/* Free the chunk */
4562 			sctp_free_a_strmoq(stcb, sp, so_locked);
4563 			/*sa_ignore FREED_MEMORY*/
4564 		}
4565 	}
4566 
4567 	if (holds_lock == 0) {
4568 		SCTP_TCB_SEND_UNLOCK(stcb);
4569 	}
4570 }
4571 
4572 void
4573 sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error,
4574 			struct sctp_abort_chunk *abort, int so_locked
4575 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4576     SCTP_UNUSED
4577 #endif
4578     )
4579 {
4580 	if (stcb == NULL) {
4581 		return;
4582 	}
4583 #if defined(__APPLE__)
4584 	if (so_locked) {
4585 		sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4586 	} else {
4587 		sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4588 	}
4589 #endif
4590 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
4591 	    ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4592 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
4593 		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
4594 	}
4595 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4596 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4597 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
4598 		return;
4599 	}
4600 	/* Tell them we lost the asoc */
4601 	sctp_report_all_outbound(stcb, error, 0, so_locked);
4602 	if (from_peer) {
4603 		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
4604 	} else {
4605 		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked);
4606 	}
4607 }
4608 
4609 void
4610 sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
4611                        struct mbuf *m, int iphlen,
4612                        struct sockaddr *src, struct sockaddr *dst,
4613                        struct sctphdr *sh, struct mbuf *op_err,
4614 #if defined(__FreeBSD__)
4615                        uint8_t mflowtype, uint32_t mflowid,
4616 #endif
4617                        uint32_t vrf_id, uint16_t port)
4618 {
4619 	uint32_t vtag;
4620 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4621 	struct socket *so;
4622 #endif
4623 
4624 	vtag = 0;
4625 	if (stcb != NULL) {
4626 		vtag = stcb->asoc.peer_vtag;
4627 		vrf_id = stcb->asoc.vrf_id;
4628 	}
4629 	sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
4630 #if defined(__FreeBSD__)
4631 	                mflowtype, mflowid, inp->fibnum,
4632 #endif
4633 	                vrf_id, port);
4634 	if (stcb != NULL) {
4635 		/* We have a TCB to abort, send notification too */
4636 		sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
4637 		SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
4638 		/* Ok, now lets free it */
4639 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4640 		so = SCTP_INP_SO(inp);
4641 		atomic_add_int(&stcb->asoc.refcnt, 1);
4642 		SCTP_TCB_UNLOCK(stcb);
4643 		SCTP_SOCKET_LOCK(so, 1);
4644 		SCTP_TCB_LOCK(stcb);
4645 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
4646 #endif
4647 		SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4648 		if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4649 		    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4650 			SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4651 		}
4652 		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4653 		                      SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
4654 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4655 		SCTP_SOCKET_UNLOCK(so, 1);
4656 #endif
4657 	}
4658 }
4659 #ifdef SCTP_ASOCLOG_OF_TSNS
4660 void
4661 sctp_print_out_track_log(struct sctp_tcb *stcb)
4662 {
4663 #ifdef NOSIY_PRINTS
4664 	int i;
4665 	SCTP_PRINTF("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code);
4666 	SCTP_PRINTF("IN bound TSN log-aaa\n");
4667 	if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) {
4668 		SCTP_PRINTF("None rcvd\n");
4669 		goto none_in;
4670 	}
4671 	if (stcb->asoc.tsn_in_wrapped) {
4672 		for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) {
4673 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4674 				    stcb->asoc.in_tsnlog[i].tsn,
4675 				    stcb->asoc.in_tsnlog[i].strm,
4676 				    stcb->asoc.in_tsnlog[i].seq,
4677 				    stcb->asoc.in_tsnlog[i].flgs,
4678 				    stcb->asoc.in_tsnlog[i].sz);
4679 		}
4680 	}
4681 	if (stcb->asoc.tsn_in_at) {
4682 		for (i = 0; i < stcb->asoc.tsn_in_at; i++) {
4683 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4684 				    stcb->asoc.in_tsnlog[i].tsn,
4685 				    stcb->asoc.in_tsnlog[i].strm,
4686 				    stcb->asoc.in_tsnlog[i].seq,
4687 				    stcb->asoc.in_tsnlog[i].flgs,
4688 				    stcb->asoc.in_tsnlog[i].sz);
4689 		}
4690 	}
4691  none_in:
4692 	SCTP_PRINTF("OUT bound TSN log-aaa\n");
4693 	if ((stcb->asoc.tsn_out_at == 0) &&
4694 	    (stcb->asoc.tsn_out_wrapped == 0)) {
4695 		SCTP_PRINTF("None sent\n");
4696 	}
4697 	if (stcb->asoc.tsn_out_wrapped) {
4698 		for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) {
4699 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4700 				    stcb->asoc.out_tsnlog[i].tsn,
4701 				    stcb->asoc.out_tsnlog[i].strm,
4702 				    stcb->asoc.out_tsnlog[i].seq,
4703 				    stcb->asoc.out_tsnlog[i].flgs,
4704 				    stcb->asoc.out_tsnlog[i].sz);
4705 		}
4706 	}
4707 	if (stcb->asoc.tsn_out_at) {
4708 		for (i = 0; i < stcb->asoc.tsn_out_at; i++) {
4709 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4710 				    stcb->asoc.out_tsnlog[i].tsn,
4711 				    stcb->asoc.out_tsnlog[i].strm,
4712 				    stcb->asoc.out_tsnlog[i].seq,
4713 				    stcb->asoc.out_tsnlog[i].flgs,
4714 				    stcb->asoc.out_tsnlog[i].sz);
4715 		}
4716 	}
4717 #endif
4718 }
4719 #endif
4720 
4721 void
4722 sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
4723                           struct mbuf *op_err,
4724                           int so_locked
4725 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4726                           SCTP_UNUSED
4727 #endif
4728 )
4729 {
4730 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4731 	struct socket *so;
4732 #endif
4733 
4734 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4735 	so = SCTP_INP_SO(inp);
4736 #endif
4737 #if defined(__APPLE__)
4738 	if (so_locked) {
4739 		sctp_lock_assert(SCTP_INP_SO(inp));
4740 	} else {
4741 		sctp_unlock_assert(SCTP_INP_SO(inp));
4742 	}
4743 #endif
4744 	if (stcb == NULL) {
4745 		/* Got to have a TCB */
4746 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
4747 			if (LIST_EMPTY(&inp->sctp_asoc_list)) {
4748 #if defined(__APPLE__)
4749 				if (!so_locked) {
4750 					SCTP_SOCKET_LOCK(so, 1);
4751 				}
4752 #endif
4753 				sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
4754 						SCTP_CALLED_DIRECTLY_NOCMPSET);
4755 #if defined(__APPLE__)
4756 				if (!so_locked) {
4757 					SCTP_SOCKET_UNLOCK(so, 1);
4758 				}
4759 #endif
4760 			}
4761 		}
4762 		return;
4763 	} else {
4764 		SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
4765 	}
4766 	/* notify the peer */
4767 	sctp_send_abort_tcb(stcb, op_err, so_locked);
4768 	SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4769 	if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4770 	    (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4771 		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4772 	}
4773 	/* notify the ulp */
4774 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
4775 		sctp_abort_notification(stcb, 0, 0, NULL, so_locked);
4776 	}
4777 	/* now free the asoc */
4778 #ifdef SCTP_ASOCLOG_OF_TSNS
4779 	sctp_print_out_track_log(stcb);
4780 #endif
4781 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4782 	if (!so_locked) {
4783 		atomic_add_int(&stcb->asoc.refcnt, 1);
4784 		SCTP_TCB_UNLOCK(stcb);
4785 		SCTP_SOCKET_LOCK(so, 1);
4786 		SCTP_TCB_LOCK(stcb);
4787 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
4788 	}
4789 #endif
4790 	(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4791 	                      SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
4792 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4793 	if (!so_locked) {
4794 		SCTP_SOCKET_UNLOCK(so, 1);
4795 	}
4796 #endif
4797 }
4798 
4799 void
4800 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
4801                  struct sockaddr *src, struct sockaddr *dst,
4802                  struct sctphdr *sh, struct sctp_inpcb *inp,
4803                  struct mbuf *cause,
4804 #if defined(__FreeBSD__)
4805                  uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
4806 #endif
4807                  uint32_t vrf_id, uint16_t port)
4808 {
4809 	struct sctp_chunkhdr *ch, chunk_buf;
4810 	unsigned int chk_length;
4811 	int contains_init_chunk;
4812 
4813 	SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
4814 	/* Generate a TO address for future reference */
4815 	if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
4816 		if (LIST_EMPTY(&inp->sctp_asoc_list)) {
4817 #if defined(__APPLE__)
4818 			SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
4819 #endif
4820 			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
4821 					SCTP_CALLED_DIRECTLY_NOCMPSET);
4822 #if defined(__APPLE__)
4823 			SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1);
4824 #endif
4825 		}
4826 	}
4827 	contains_init_chunk = 0;
4828 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4829 	    sizeof(*ch), (uint8_t *) & chunk_buf);
4830 	while (ch != NULL) {
4831 		chk_length = ntohs(ch->chunk_length);
4832 		if (chk_length < sizeof(*ch)) {
4833 			/* break to abort land */
4834 			break;
4835 		}
4836 		switch (ch->chunk_type) {
4837 		case SCTP_INIT:
4838 			contains_init_chunk = 1;
4839 			break;
4840 		case SCTP_PACKET_DROPPED:
4841 			/* we don't respond to pkt-dropped */
4842 			return;
4843 		case SCTP_ABORT_ASSOCIATION:
4844 			/* we don't respond with an ABORT to an ABORT */
4845 			return;
4846 		case SCTP_SHUTDOWN_COMPLETE:
4847 			/*
4848 			 * we ignore it since we are not waiting for it and
4849 			 * peer is gone
4850 			 */
4851 			return;
4852 		case SCTP_SHUTDOWN_ACK:
4853 			sctp_send_shutdown_complete2(src, dst, sh,
4854 #if defined(__FreeBSD__)
4855 			                             mflowtype, mflowid, fibnum,
4856 #endif
4857 			                             vrf_id, port);
4858 			return;
4859 		default:
4860 			break;
4861 		}
4862 		offset += SCTP_SIZE32(chk_length);
4863 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4864 		    sizeof(*ch), (uint8_t *) & chunk_buf);
4865 	}
4866 	if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
4867 	    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
4868 	     (contains_init_chunk == 0))) {
4869 		sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
4870 #if defined(__FreeBSD__)
4871 		                mflowtype, mflowid, fibnum,
4872 #endif
4873 		                vrf_id, port);
4874 	}
4875 }
4876 
4877 /*
4878  * check the inbound datagram to make sure there is not an abort inside it,
4879  * if there is return 1, else return 0.
4880  */
4881 int
4882 sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t * vtagfill)
4883 {
4884 	struct sctp_chunkhdr *ch;
4885 	struct sctp_init_chunk *init_chk, chunk_buf;
4886 	int offset;
4887 	unsigned int chk_length;
4888 
4889 	offset = iphlen + sizeof(struct sctphdr);
4890 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
4891 	    (uint8_t *) & chunk_buf);
4892 	while (ch != NULL) {
4893 		chk_length = ntohs(ch->chunk_length);
4894 		if (chk_length < sizeof(*ch)) {
4895 			/* packet is probably corrupt */
4896 			break;
4897 		}
4898 		/* we seem to be ok, is it an abort? */
4899 		if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
4900 			/* yep, tell them */
4901 			return (1);
4902 		}
4903 		if (ch->chunk_type == SCTP_INITIATION) {
4904 			/* need to update the Vtag */
4905 			init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
4906 			    offset, sizeof(*init_chk), (uint8_t *) & chunk_buf);
4907 			if (init_chk != NULL) {
4908 				*vtagfill = ntohl(init_chk->init.initiate_tag);
4909 			}
4910 		}
4911 		/* Nope, move to the next chunk */
4912 		offset += SCTP_SIZE32(chk_length);
4913 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4914 		    sizeof(*ch), (uint8_t *) & chunk_buf);
4915 	}
4916 	return (0);
4917 }
4918 
4919 /*
4920  * currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id
4921  * set (i.e. it's 0) so, create this function to compare link local scopes
4922  */
4923 #ifdef INET6
4924 uint32_t
4925 sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2)
4926 {
4927 #if defined(__Userspace__)
4928     /*__Userspace__ Returning 1 here always */
4929 #endif
4930 #if defined(SCTP_EMBEDDED_V6_SCOPE)
4931 	struct sockaddr_in6 a, b;
4932 
4933 	/* save copies */
4934 	a = *addr1;
4935 	b = *addr2;
4936 
4937 	if (a.sin6_scope_id == 0)
4938 #ifdef SCTP_KAME
4939 		if (sa6_recoverscope(&a)) {
4940 #else
4941 		if (in6_recoverscope(&a, &a.sin6_addr, NULL)) {
4942 #endif				/* SCTP_KAME */
4943 			/* can't get scope, so can't match */
4944 			return (0);
4945 		}
4946 	if (b.sin6_scope_id == 0)
4947 #ifdef SCTP_KAME
4948 		if (sa6_recoverscope(&b)) {
4949 #else
4950 		if (in6_recoverscope(&b, &b.sin6_addr, NULL)) {
4951 #endif				/* SCTP_KAME */
4952 			/* can't get scope, so can't match */
4953 			return (0);
4954 		}
4955 	if (a.sin6_scope_id != b.sin6_scope_id)
4956 		return (0);
4957 #else
4958 	if (addr1->sin6_scope_id != addr2->sin6_scope_id)
4959 		return (0);
4960 #endif /* SCTP_EMBEDDED_V6_SCOPE */
4961 
4962 	return (1);
4963 }
4964 
4965 #if defined(SCTP_EMBEDDED_V6_SCOPE)
4966 /*
4967  * returns a sockaddr_in6 with embedded scope recovered and removed
4968  */
4969 struct sockaddr_in6 *
4970 sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
4971 {
4972 	/* check and strip embedded scope junk */
4973 	if (addr->sin6_family == AF_INET6) {
4974 		if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
4975 			if (addr->sin6_scope_id == 0) {
4976 				*store = *addr;
4977 #ifdef SCTP_KAME
4978 				if (!sa6_recoverscope(store)) {
4979 #else
4980 				if (!in6_recoverscope(store, &store->sin6_addr,
4981 				    NULL)) {
4982 #endif /* SCTP_KAME */
4983 					/* use the recovered scope */
4984 					addr = store;
4985 				}
4986 			} else {
4987 				/* else, return the original "to" addr */
4988 				in6_clearscope(&addr->sin6_addr);
4989 			}
4990 		}
4991 	}
4992 	return (addr);
4993 }
4994 #endif /* SCTP_EMBEDDED_V6_SCOPE */
4995 #endif
4996 
4997 /*
4998  * are the two addresses the same?  currently a "scopeless" check returns: 1
4999  * if same, 0 if not
5000  */
5001 int
5002 sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
5003 {
5004 
5005 	/* must be valid */
5006 	if (sa1 == NULL || sa2 == NULL)
5007 		return (0);
5008 
5009 	/* must be the same family */
5010 	if (sa1->sa_family != sa2->sa_family)
5011 		return (0);
5012 
5013 	switch (sa1->sa_family) {
5014 #ifdef INET6
5015 	case AF_INET6:
5016 	{
5017 		/* IPv6 addresses */
5018 		struct sockaddr_in6 *sin6_1, *sin6_2;
5019 
5020 		sin6_1 = (struct sockaddr_in6 *)sa1;
5021 		sin6_2 = (struct sockaddr_in6 *)sa2;
5022 		return (SCTP6_ARE_ADDR_EQUAL(sin6_1,
5023 		    sin6_2));
5024 	}
5025 #endif
5026 #ifdef INET
5027 	case AF_INET:
5028 	{
5029 		/* IPv4 addresses */
5030 		struct sockaddr_in *sin_1, *sin_2;
5031 
5032 		sin_1 = (struct sockaddr_in *)sa1;
5033 		sin_2 = (struct sockaddr_in *)sa2;
5034 		return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
5035 	}
5036 #endif
5037 #if defined(__Userspace__)
5038 	case AF_CONN:
5039 	{
5040 		struct sockaddr_conn *sconn_1, *sconn_2;
5041 
5042 		sconn_1 = (struct sockaddr_conn *)sa1;
5043 		sconn_2 = (struct sockaddr_conn *)sa2;
5044 		return (sconn_1->sconn_addr == sconn_2->sconn_addr);
5045 	}
5046 #endif
5047 	default:
5048 		/* we don't do these... */
5049 		return (0);
5050 	}
5051 }
5052 
5053 void
5054 sctp_print_address(struct sockaddr *sa)
5055 {
5056 #ifdef INET6
5057 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
5058 	char ip6buf[INET6_ADDRSTRLEN];
5059 #endif
5060 #endif
5061 
5062 	switch (sa->sa_family) {
5063 #ifdef INET6
5064 	case AF_INET6:
5065 	{
5066 		struct sockaddr_in6 *sin6;
5067 
5068 		sin6 = (struct sockaddr_in6 *)sa;
5069 #if defined(__Userspace__)
5070 		SCTP_PRINTF("IPv6 address: %x:%x:%x:%x:%x:%x:%x:%x:port:%d scope:%u\n",
5071 			    ntohs(sin6->sin6_addr.s6_addr16[0]),
5072 			    ntohs(sin6->sin6_addr.s6_addr16[1]),
5073 			    ntohs(sin6->sin6_addr.s6_addr16[2]),
5074 			    ntohs(sin6->sin6_addr.s6_addr16[3]),
5075 			    ntohs(sin6->sin6_addr.s6_addr16[4]),
5076 			    ntohs(sin6->sin6_addr.s6_addr16[5]),
5077 			    ntohs(sin6->sin6_addr.s6_addr16[6]),
5078 			    ntohs(sin6->sin6_addr.s6_addr16[7]),
5079 			    ntohs(sin6->sin6_port),
5080 			    sin6->sin6_scope_id);
5081 #else
5082 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
5083 		SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
5084 			    ip6_sprintf(ip6buf, &sin6->sin6_addr),
5085 			    ntohs(sin6->sin6_port),
5086 			    sin6->sin6_scope_id);
5087 #else
5088 		SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
5089 			    ip6_sprintf(&sin6->sin6_addr),
5090 			    ntohs(sin6->sin6_port),
5091 			    sin6->sin6_scope_id);
5092 #endif
5093 #endif
5094 		break;
5095 	}
5096 #endif
5097 #ifdef INET
5098 	case AF_INET:
5099 	{
5100 		struct sockaddr_in *sin;
5101 		unsigned char *p;
5102 
5103 		sin = (struct sockaddr_in *)sa;
5104 		p = (unsigned char *)&sin->sin_addr;
5105 		SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n",
5106 			    p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
5107 		break;
5108 	}
5109 #endif
5110 #if defined(__Userspace__)
5111 	case AF_CONN:
5112 	{
5113 		struct sockaddr_conn *sconn;
5114 
5115 		sconn = (struct sockaddr_conn *)sa;
5116 		SCTP_PRINTF("AF_CONN address: %p\n", sconn->sconn_addr);
5117 		break;
5118 	}
5119 #endif
5120 	default:
5121 		SCTP_PRINTF("?\n");
5122 		break;
5123 	}
5124 }
5125 
5126 void
5127 sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
5128     struct sctp_inpcb *new_inp,
5129     struct sctp_tcb *stcb,
5130     int waitflags)
5131 {
5132 	/*
5133 	 * go through our old INP and pull off any control structures that
5134 	 * belong to stcb and move then to the new inp.
5135 	 */
5136 	struct socket *old_so, *new_so;
5137 	struct sctp_queued_to_read *control, *nctl;
5138 	struct sctp_readhead tmp_queue;
5139 	struct mbuf *m;
5140 #if defined(__FreeBSD__) || defined(__APPLE__)
5141 	int error = 0;
5142 #endif
5143 
5144 	old_so = old_inp->sctp_socket;
5145 	new_so = new_inp->sctp_socket;
5146 	TAILQ_INIT(&tmp_queue);
5147 #if defined(__FreeBSD__) || defined(__APPLE__)
5148 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5149 	SOCKBUF_LOCK(&(old_so->so_rcv));
5150 #endif
5151 	error = sblock(&old_so->so_rcv, waitflags);
5152 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5153 	SOCKBUF_UNLOCK(&(old_so->so_rcv));
5154 #endif
5155 	if (error) {
5156 		/* Gak, can't get sblock, we have a problem.
5157 		 * data will be left stranded.. and we
5158 		 * don't dare look at it since the
5159 		 * other thread may be reading something.
5160 		 * Oh well, its a screwed up app that does
5161 		 * a peeloff OR a accept while reading
5162 		 * from the main socket... actually its
5163 		 * only the peeloff() case, since I think
5164 		 * read will fail on a listening socket..
5165 		 */
5166 		return;
5167 	}
5168 #endif
5169 	/* lock the socket buffers */
5170 	SCTP_INP_READ_LOCK(old_inp);
5171 	TAILQ_FOREACH_SAFE(control, &old_inp->read_queue, next, nctl) {
5172 		/* Pull off all for out target stcb */
5173 		if (control->stcb == stcb) {
5174 			/* remove it we want it */
5175 			TAILQ_REMOVE(&old_inp->read_queue, control, next);
5176 			TAILQ_INSERT_TAIL(&tmp_queue, control, next);
5177 			m = control->data;
5178 			while (m) {
5179 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5180 					sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE,SCTP_BUF_LEN(m));
5181 				}
5182 				sctp_sbfree(control, stcb, &old_so->so_rcv, m);
5183 				if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5184 					sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5185 				}
5186 				m = SCTP_BUF_NEXT(m);
5187 			}
5188 		}
5189 	}
5190 	SCTP_INP_READ_UNLOCK(old_inp);
5191 	/* Remove the sb-lock on the old socket */
5192 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5193 	SOCKBUF_LOCK(&(old_so->so_rcv));
5194 #endif
5195 #if defined(__APPLE__)
5196 	sbunlock(&old_so->so_rcv, 1);
5197 #endif
5198 
5199 #if defined(__FreeBSD__)
5200 	sbunlock(&old_so->so_rcv);
5201 #endif
5202 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5203 	SOCKBUF_UNLOCK(&(old_so->so_rcv));
5204 #endif
5205 	/* Now we move them over to the new socket buffer */
5206 	SCTP_INP_READ_LOCK(new_inp);
5207 	TAILQ_FOREACH_SAFE(control, &tmp_queue, next, nctl) {
5208 		TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next);
5209 		m = control->data;
5210 		while (m) {
5211 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5212 				sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
5213 			}
5214 			sctp_sballoc(stcb, &new_so->so_rcv, m);
5215 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5216 				sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5217 			}
5218 			m = SCTP_BUF_NEXT(m);
5219 		}
5220 	}
5221 	SCTP_INP_READ_UNLOCK(new_inp);
5222 }
5223 
5224 void
5225 sctp_wakeup_the_read_socket(struct sctp_inpcb *inp,
5226     struct sctp_tcb *stcb,
5227     int so_locked
5228 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5229     SCTP_UNUSED
5230 #endif
5231 )
5232 {
5233 	if ((inp != NULL) && (inp->sctp_socket != NULL)) {
5234 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5235 		struct socket *so;
5236 
5237 		so = SCTP_INP_SO(inp);
5238 		if (!so_locked) {
5239 			if (stcb) {
5240 				atomic_add_int(&stcb->asoc.refcnt, 1);
5241 				SCTP_TCB_UNLOCK(stcb);
5242 			}
5243 			SCTP_SOCKET_LOCK(so, 1);
5244 			if (stcb) {
5245 				SCTP_TCB_LOCK(stcb);
5246 				atomic_subtract_int(&stcb->asoc.refcnt, 1);
5247 			}
5248 			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5249 				SCTP_SOCKET_UNLOCK(so, 1);
5250 				return;
5251 			}
5252 		}
5253 #endif
5254 		sctp_sorwakeup(inp, inp->sctp_socket);
5255 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5256 		if (!so_locked) {
5257 			SCTP_SOCKET_UNLOCK(so, 1);
5258 		}
5259 #endif
5260 	}
5261 }
5262 #if defined(__Userspace__)
5263 
5264 void
5265 sctp_invoke_recv_callback(struct sctp_inpcb *inp,
5266                           struct sctp_tcb *stcb,
5267                           struct sctp_queued_to_read *control,
5268                           int inp_read_lock_held)
5269 {
5270 	uint32_t pd_point, length;
5271 
5272 	if ((inp->recv_callback == NULL) ||
5273 	    (stcb == NULL) ||
5274 	    (stcb->sctp_socket == NULL)) {
5275 		return;
5276 	}
5277 
5278 	length = control->length;
5279 	if (stcb != NULL && stcb->sctp_socket != NULL) {
5280 		pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
5281 			       stcb->sctp_ep->partial_delivery_point);
5282 	} else {
5283 		pd_point = inp->partial_delivery_point;
5284 	}
5285 	if ((control->end_added == 1) || (length >= pd_point)) {
5286 		struct socket *so;
5287 		struct mbuf *m;
5288 		char *buffer;
5289 		struct sctp_rcvinfo rcv;
5290 		union sctp_sockstore addr;
5291 		int flags;
5292 
5293 		if ((buffer = malloc(length)) == NULL) {
5294 			return;
5295 		}
5296 		if (inp_read_lock_held == 0) {
5297 			SCTP_INP_READ_LOCK(inp);
5298 		}
5299 		so = stcb->sctp_socket;
5300 		for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
5301 			sctp_sbfree(control, control->stcb, &so->so_rcv, m);
5302 		}
5303 		m_copydata(control->data, 0, length, buffer);
5304 		memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
5305 		rcv.rcv_sid = control->sinfo_stream;
5306 		rcv.rcv_ssn = (uint16_t)control->mid;
5307 		rcv.rcv_flags = control->sinfo_flags;
5308 		rcv.rcv_ppid = control->sinfo_ppid;
5309 		rcv.rcv_tsn = control->sinfo_tsn;
5310 		rcv.rcv_cumtsn = control->sinfo_cumtsn;
5311 		rcv.rcv_context = control->sinfo_context;
5312 		rcv.rcv_assoc_id = control->sinfo_assoc_id;
5313 		memset(&addr, 0, sizeof(union sctp_sockstore));
5314 		switch (control->whoFrom->ro._l_addr.sa.sa_family) {
5315 #ifdef INET
5316 		case AF_INET:
5317 			addr.sin = control->whoFrom->ro._l_addr.sin;
5318 			break;
5319 #endif
5320 #ifdef INET6
5321 		case AF_INET6:
5322 			addr.sin6 = control->whoFrom->ro._l_addr.sin6;
5323 			break;
5324 #endif
5325 		case AF_CONN:
5326 			addr.sconn = control->whoFrom->ro._l_addr.sconn;
5327 			break;
5328 		default:
5329 			addr.sa = control->whoFrom->ro._l_addr.sa;
5330 			break;
5331 		}
5332 		flags = 0;
5333 		if (control->end_added == 1) {
5334 			flags |= MSG_EOR;
5335 		}
5336 		if (control->spec_flags & M_NOTIFICATION) {
5337 			flags |= MSG_NOTIFICATION;
5338 		}
5339 		sctp_m_freem(control->data);
5340 		control->data = NULL;
5341 		control->tail_mbuf = NULL;
5342 		control->length = 0;
5343 		if (control->end_added) {
5344 			TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
5345 			control->on_read_q = 0;
5346 			sctp_free_remote_addr(control->whoFrom);
5347 			control->whoFrom = NULL;
5348 			sctp_free_a_readq(stcb, control);
5349 		}
5350 		atomic_add_int(&stcb->asoc.refcnt, 1);
5351 		SCTP_TCB_UNLOCK(stcb);
5352 		if (inp_read_lock_held == 0) {
5353 			SCTP_INP_READ_UNLOCK(inp);
5354 		}
5355 		inp->recv_callback(so, addr, buffer, length, rcv, flags, inp->ulp_info);
5356 		SCTP_TCB_LOCK(stcb);
5357 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
5358 	}
5359 }
5360 #endif
5361 
5362 void
5363 sctp_add_to_readq(struct sctp_inpcb *inp,
5364     struct sctp_tcb *stcb,
5365     struct sctp_queued_to_read *control,
5366     struct sockbuf *sb,
5367     int end,
5368     int inp_read_lock_held,
5369     int so_locked
5370 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5371     SCTP_UNUSED
5372 #endif
5373     )
5374 {
5375 	/*
5376 	 * Here we must place the control on the end of the socket read
5377 	 * queue AND increment sb_cc so that select will work properly on
5378 	 * read.
5379 	 */
5380 	struct mbuf *m, *prev = NULL;
5381 
5382 	if (inp == NULL) {
5383 		/* Gak, TSNH!! */
5384 #ifdef INVARIANTS
5385 		panic("Gak, inp NULL on add_to_readq");
5386 #endif
5387 		return;
5388 	}
5389 #if defined(__APPLE__)
5390 	if (so_locked) {
5391 		sctp_lock_assert(SCTP_INP_SO(inp));
5392 	} else {
5393 		sctp_unlock_assert(SCTP_INP_SO(inp));
5394 	}
5395 #endif
5396 	if (inp_read_lock_held == 0)
5397 		SCTP_INP_READ_LOCK(inp);
5398 	if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
5399 		if (!control->on_strm_q) {
5400 			sctp_free_remote_addr(control->whoFrom);
5401 			if (control->data) {
5402 				sctp_m_freem(control->data);
5403 				control->data = NULL;
5404 			}
5405 			sctp_free_a_readq(stcb, control);
5406 		}
5407 		if (inp_read_lock_held == 0)
5408 			SCTP_INP_READ_UNLOCK(inp);
5409 		return;
5410 	}
5411 	if (!(control->spec_flags & M_NOTIFICATION)) {
5412 		atomic_add_int(&inp->total_recvs, 1);
5413 		if (!control->do_not_ref_stcb) {
5414 			atomic_add_int(&stcb->total_recvs, 1);
5415 		}
5416 	}
5417 	m = control->data;
5418 	control->held_length = 0;
5419 	control->length = 0;
5420 	while (m) {
5421 		if (SCTP_BUF_LEN(m) == 0) {
5422 			/* Skip mbufs with NO length */
5423 			if (prev == NULL) {
5424 				/* First one */
5425 				control->data = sctp_m_free(m);
5426 				m = control->data;
5427 			} else {
5428 				SCTP_BUF_NEXT(prev) = sctp_m_free(m);
5429 				m = SCTP_BUF_NEXT(prev);
5430 			}
5431 			if (m == NULL) {
5432 				control->tail_mbuf = prev;
5433 			}
5434 			continue;
5435 		}
5436 		prev = m;
5437 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5438 			sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
5439 		}
5440 		sctp_sballoc(stcb, sb, m);
5441 		if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5442 			sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5443 		}
5444 		atomic_add_int(&control->length, SCTP_BUF_LEN(m));
5445 		m = SCTP_BUF_NEXT(m);
5446 	}
5447 	if (prev != NULL) {
5448 		control->tail_mbuf = prev;
5449 	} else {
5450 		/* Everything got collapsed out?? */
5451 		if (!control->on_strm_q) {
5452 			sctp_free_remote_addr(control->whoFrom);
5453 			sctp_free_a_readq(stcb, control);
5454 		}
5455 		if (inp_read_lock_held == 0)
5456 			SCTP_INP_READ_UNLOCK(inp);
5457 		return;
5458 	}
5459 	if (end) {
5460 		control->end_added = 1;
5461 	}
5462 	TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
5463 	control->on_read_q = 1;
5464 	if (inp_read_lock_held == 0)
5465 		SCTP_INP_READ_UNLOCK(inp);
5466 #if defined(__Userspace__)
5467 	sctp_invoke_recv_callback(inp, stcb, control, inp_read_lock_held);
5468 #endif
5469 	if (inp && inp->sctp_socket) {
5470 		sctp_wakeup_the_read_socket(inp, stcb, so_locked);
5471 	}
5472 }
5473 
5474 /*************HOLD THIS COMMENT FOR PATCH FILE OF
5475  *************ALTERNATE ROUTING CODE
5476  */
5477 
5478 /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
5479  *************ALTERNATE ROUTING CODE
5480  */
5481 
5482 struct mbuf *
5483 sctp_generate_cause(uint16_t code, char *info)
5484 {
5485 	struct mbuf *m;
5486 	struct sctp_gen_error_cause *cause;
5487 	size_t info_len;
5488 	uint16_t len;
5489 
5490 	if ((code == 0) || (info == NULL)) {
5491 		return (NULL);
5492 	}
5493 	info_len = strlen(info);
5494 	if (info_len > (SCTP_MAX_CAUSE_LENGTH - sizeof(struct sctp_paramhdr))) {
5495 		return (NULL);
5496 	}
5497 	len = (uint16_t)(sizeof(struct sctp_paramhdr) + info_len);
5498 	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5499 	if (m != NULL) {
5500 		SCTP_BUF_LEN(m) = len;
5501 		cause = mtod(m, struct sctp_gen_error_cause *);
5502 		cause->code = htons(code);
5503 		cause->length = htons(len);
5504 		memcpy(cause->info, info, info_len);
5505 	}
5506 	return (m);
5507 }
5508 
5509 struct mbuf *
5510 sctp_generate_no_user_data_cause(uint32_t tsn)
5511 {
5512 	struct mbuf *m;
5513 	struct sctp_error_no_user_data *no_user_data_cause;
5514 	uint16_t len;
5515 
5516 	len = (uint16_t)sizeof(struct sctp_error_no_user_data);
5517 	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5518 	if (m != NULL) {
5519 		SCTP_BUF_LEN(m) = len;
5520 		no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
5521 		no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
5522 		no_user_data_cause->cause.length = htons(len);
5523 		no_user_data_cause->tsn = htonl(tsn);
5524 	}
5525 	return (m);
5526 }
5527 
5528 #ifdef SCTP_MBCNT_LOGGING
5529 void
5530 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
5531     struct sctp_tmit_chunk *tp1, int chk_cnt)
5532 {
5533 	if (tp1->data == NULL) {
5534 		return;
5535 	}
5536 	asoc->chunks_on_out_queue -= chk_cnt;
5537 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBCNT_LOGGING_ENABLE) {
5538 		sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
5539 			       asoc->total_output_queue_size,
5540 			       tp1->book_size,
5541 			       0,
5542 			       tp1->mbcnt);
5543 	}
5544 	if (asoc->total_output_queue_size >= tp1->book_size) {
5545 		atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size);
5546 	} else {
5547 		asoc->total_output_queue_size = 0;
5548 	}
5549 
5550 	if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) ||
5551 				  ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) {
5552 		if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
5553 			stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
5554 		} else {
5555 			stcb->sctp_socket->so_snd.sb_cc = 0;
5556 
5557 		}
5558 	}
5559 }
5560 
5561 #endif
5562 
5563 int
5564 sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
5565 			   uint8_t sent, int so_locked
5566 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5567 			   SCTP_UNUSED
5568 #endif
5569 	)
5570 {
5571 	struct sctp_stream_out *strq;
5572 	struct sctp_tmit_chunk *chk = NULL, *tp2;
5573 	struct sctp_stream_queue_pending *sp;
5574 	uint32_t mid;
5575 	uint16_t sid;
5576 	uint8_t foundeom = 0;
5577 	int ret_sz = 0;
5578 	int notdone;
5579 	int do_wakeup_routine = 0;
5580 
5581 #if defined(__APPLE__)
5582 	if (so_locked) {
5583 		sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
5584 	} else {
5585 		sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
5586 	}
5587 #endif
5588 	sid = tp1->rec.data.sid;
5589 	mid = tp1->rec.data.mid;
5590 	if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
5591 		stcb->asoc.abandoned_sent[0]++;
5592 		stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
5593 		stcb->asoc.strmout[sid].abandoned_sent[0]++;
5594 #if defined(SCTP_DETAILED_STR_STATS)
5595 		stcb->asoc.strmout[sid].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
5596 #endif
5597 	} else {
5598 		stcb->asoc.abandoned_unsent[0]++;
5599 		stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
5600 		stcb->asoc.strmout[sid].abandoned_unsent[0]++;
5601 #if defined(SCTP_DETAILED_STR_STATS)
5602 		stcb->asoc.strmout[sid].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
5603 #endif
5604 	}
5605 	do {
5606 		ret_sz += tp1->book_size;
5607 		if (tp1->data != NULL) {
5608 			if (tp1->sent < SCTP_DATAGRAM_RESEND) {
5609 				sctp_flight_size_decrease(tp1);
5610 				sctp_total_flight_decrease(stcb, tp1);
5611 			}
5612 			sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
5613 			stcb->asoc.peers_rwnd += tp1->send_size;
5614 			stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
5615 			if (sent) {
5616 				sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
5617 			} else {
5618 				sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
5619 			}
5620 			if (tp1->data) {
5621 				sctp_m_freem(tp1->data);
5622 				tp1->data = NULL;
5623 			}
5624 			do_wakeup_routine = 1;
5625 			if (PR_SCTP_BUF_ENABLED(tp1->flags)) {
5626 				stcb->asoc.sent_queue_cnt_removeable--;
5627 			}
5628 		}
5629 		tp1->sent = SCTP_FORWARD_TSN_SKIP;
5630 		if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
5631 		    SCTP_DATA_NOT_FRAG) {
5632 			/* not frag'ed we ae done   */
5633 			notdone = 0;
5634 			foundeom = 1;
5635 		} else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
5636 			/* end of frag, we are done */
5637 			notdone = 0;
5638 			foundeom = 1;
5639 		} else {
5640 			/*
5641 			 * Its a begin or middle piece, we must mark all of
5642 			 * it
5643 			 */
5644 			notdone = 1;
5645 			tp1 = TAILQ_NEXT(tp1, sctp_next);
5646 		}
5647 	} while (tp1 && notdone);
5648 	if (foundeom == 0) {
5649 		/*
5650 		 * The multi-part message was scattered across the send and
5651 		 * sent queue.
5652 		 */
5653 		TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
5654 			if ((tp1->rec.data.sid != sid) ||
5655 			    (!SCTP_MID_EQ(stcb->asoc.idata_supported, tp1->rec.data.mid, mid))) {
5656 				break;
5657 			}
5658 			/* save to chk in case we have some on stream out
5659 			 * queue. If so and we have an un-transmitted one
5660 			 * we don't have to fudge the TSN.
5661 			 */
5662 			chk = tp1;
5663 			ret_sz += tp1->book_size;
5664 			sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
5665 			if (sent) {
5666 				sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
5667 			} else {
5668 				sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
5669 			}
5670 			if (tp1->data) {
5671 				sctp_m_freem(tp1->data);
5672 				tp1->data = NULL;
5673 			}
5674 			/* No flight involved here book the size to 0 */
5675 			tp1->book_size = 0;
5676 			if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
5677 				foundeom = 1;
5678 			}
5679 			do_wakeup_routine = 1;
5680 			tp1->sent = SCTP_FORWARD_TSN_SKIP;
5681 			TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
5682 			/* on to the sent queue so we can wait for it to be passed by. */
5683 			TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
5684 					  sctp_next);
5685 			stcb->asoc.send_queue_cnt--;
5686 			stcb->asoc.sent_queue_cnt++;
5687 		}
5688 	}
5689 	if (foundeom == 0) {
5690 		/*
5691 		 * Still no eom found. That means there
5692 		 * is stuff left on the stream out queue.. yuck.
5693 		 */
5694 		SCTP_TCB_SEND_LOCK(stcb);
5695 		strq = &stcb->asoc.strmout[sid];
5696 		sp = TAILQ_FIRST(&strq->outqueue);
5697 		if (sp != NULL) {
5698 			sp->discard_rest = 1;
5699 			/*
5700 			 * We may need to put a chunk on the
5701 			 * queue that holds the TSN that
5702 			 * would have been sent with the LAST
5703 			 * bit.
5704 			 */
5705 			if (chk == NULL) {
5706 				/* Yep, we have to */
5707 				sctp_alloc_a_chunk(stcb, chk);
5708 				if (chk == NULL) {
5709 					/* we are hosed. All we can
5710 					 * do is nothing.. which will
5711 					 * cause an abort if the peer is
5712 					 * paying attention.
5713 					 */
5714 					goto oh_well;
5715 				}
5716 				memset(chk, 0, sizeof(*chk));
5717 				chk->rec.data.rcv_flags = 0;
5718 				chk->sent = SCTP_FORWARD_TSN_SKIP;
5719 				chk->asoc = &stcb->asoc;
5720 				if (stcb->asoc.idata_supported == 0) {
5721 					if (sp->sinfo_flags & SCTP_UNORDERED) {
5722 						chk->rec.data.mid = 0;
5723 					} else {
5724 						chk->rec.data.mid = strq->next_mid_ordered;
5725 					}
5726 				} else {
5727 					if (sp->sinfo_flags & SCTP_UNORDERED) {
5728 						chk->rec.data.mid = strq->next_mid_unordered;
5729 					} else {
5730 						chk->rec.data.mid = strq->next_mid_ordered;
5731 					}
5732 				}
5733 				chk->rec.data.sid = sp->sid;
5734 				chk->rec.data.ppid = sp->ppid;
5735 				chk->rec.data.context = sp->context;
5736 				chk->flags = sp->act_flags;
5737 				chk->whoTo = NULL;
5738 #if defined(__FreeBSD__) || defined(__Panda__)
5739 				chk->rec.data.tsn = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
5740 #else
5741 				chk->rec.data.tsn = stcb->asoc.sending_seq++;
5742 #endif
5743 				strq->chunks_on_queues++;
5744 				TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
5745 				stcb->asoc.sent_queue_cnt++;
5746 				stcb->asoc.pr_sctp_cnt++;
5747 			}
5748 			chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
5749 			if (sp->sinfo_flags & SCTP_UNORDERED) {
5750 				chk->rec.data.rcv_flags |= SCTP_DATA_UNORDERED;
5751 			}
5752 			if (stcb->asoc.idata_supported == 0) {
5753 				if ((sp->sinfo_flags & SCTP_UNORDERED) == 0) {
5754 					strq->next_mid_ordered++;
5755 				}
5756 			} else {
5757 				if (sp->sinfo_flags & SCTP_UNORDERED) {
5758 					strq->next_mid_unordered++;
5759 				} else {
5760 					strq->next_mid_ordered++;
5761 				}
5762 			}
5763 		oh_well:
5764 			if (sp->data) {
5765 				/* Pull any data to free up the SB and
5766 				 * allow sender to "add more" while we
5767 				 * will throw away :-)
5768 				 */
5769 				sctp_free_spbufspace(stcb, &stcb->asoc, sp);
5770 				ret_sz += sp->length;
5771 				do_wakeup_routine = 1;
5772 				sp->some_taken = 1;
5773 				sctp_m_freem(sp->data);
5774 				sp->data = NULL;
5775 				sp->tail_mbuf = NULL;
5776 				sp->length = 0;
5777 			}
5778 		}
5779 		SCTP_TCB_SEND_UNLOCK(stcb);
5780 	}
5781 	if (do_wakeup_routine) {
5782 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5783 		struct socket *so;
5784 
5785 		so = SCTP_INP_SO(stcb->sctp_ep);
5786 		if (!so_locked) {
5787 			atomic_add_int(&stcb->asoc.refcnt, 1);
5788 			SCTP_TCB_UNLOCK(stcb);
5789 			SCTP_SOCKET_LOCK(so, 1);
5790 			SCTP_TCB_LOCK(stcb);
5791 			atomic_subtract_int(&stcb->asoc.refcnt, 1);
5792 			if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
5793 				/* assoc was freed while we were unlocked */
5794 				SCTP_SOCKET_UNLOCK(so, 1);
5795 				return (ret_sz);
5796 			}
5797 		}
5798 #endif
5799 		sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
5800 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5801 		if (!so_locked) {
5802 			SCTP_SOCKET_UNLOCK(so, 1);
5803 		}
5804 #endif
5805 	}
5806 	return (ret_sz);
5807 }
5808 
5809 /*
5810  * checks to see if the given address, sa, is one that is currently known by
5811  * the kernel note: can't distinguish the same address on multiple interfaces
5812  * and doesn't handle multiple addresses with different zone/scope id's note:
5813  * ifa_ifwithaddr() compares the entire sockaddr struct
5814  */
5815 struct sctp_ifa *
5816 sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
5817 		    int holds_lock)
5818 {
5819 	struct sctp_laddr *laddr;
5820 
5821 	if (holds_lock == 0) {
5822 		SCTP_INP_RLOCK(inp);
5823 	}
5824 
5825 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
5826 		if (laddr->ifa == NULL)
5827 			continue;
5828 		if (addr->sa_family != laddr->ifa->address.sa.sa_family)
5829 			continue;
5830 #ifdef INET
5831 		if (addr->sa_family == AF_INET) {
5832 			if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
5833 			    laddr->ifa->address.sin.sin_addr.s_addr) {
5834 				/* found him. */
5835 				if (holds_lock == 0) {
5836 					SCTP_INP_RUNLOCK(inp);
5837 				}
5838 				return (laddr->ifa);
5839 				break;
5840 			}
5841 		}
5842 #endif
5843 #ifdef INET6
5844 		if (addr->sa_family == AF_INET6) {
5845 			if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
5846 						 &laddr->ifa->address.sin6)) {
5847 				/* found him. */
5848 				if (holds_lock == 0) {
5849 					SCTP_INP_RUNLOCK(inp);
5850 				}
5851 				return (laddr->ifa);
5852 				break;
5853 			}
5854 		}
5855 #endif
5856 #if defined(__Userspace__)
5857 		if (addr->sa_family == AF_CONN) {
5858 			if (((struct sockaddr_conn *)addr)->sconn_addr == laddr->ifa->address.sconn.sconn_addr) {
5859 				/* found him. */
5860 				if (holds_lock == 0) {
5861 					SCTP_INP_RUNLOCK(inp);
5862 				}
5863 				return (laddr->ifa);
5864 				break;
5865 			}
5866 		}
5867 #endif
5868 	}
5869 	if (holds_lock == 0) {
5870 		SCTP_INP_RUNLOCK(inp);
5871 	}
5872 	return (NULL);
5873 }
5874 
5875 uint32_t
5876 sctp_get_ifa_hash_val(struct sockaddr *addr)
5877 {
5878 	switch (addr->sa_family) {
5879 #ifdef INET
5880 	case AF_INET:
5881 	{
5882 		struct sockaddr_in *sin;
5883 
5884 		sin = (struct sockaddr_in *)addr;
5885 		return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16));
5886 	}
5887 #endif
5888 #ifdef INET6
5889 	case AF_INET6:
5890 	{
5891 		struct sockaddr_in6 *sin6;
5892 		uint32_t hash_of_addr;
5893 
5894 		sin6 = (struct sockaddr_in6 *)addr;
5895 #if !defined(__Windows__) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_Windows)
5896 		hash_of_addr = (sin6->sin6_addr.s6_addr32[0] +
5897 				sin6->sin6_addr.s6_addr32[1] +
5898 				sin6->sin6_addr.s6_addr32[2] +
5899 				sin6->sin6_addr.s6_addr32[3]);
5900 #else
5901 		hash_of_addr = (((uint32_t *)&sin6->sin6_addr)[0] +
5902 				((uint32_t *)&sin6->sin6_addr)[1] +
5903 				((uint32_t *)&sin6->sin6_addr)[2] +
5904 				((uint32_t *)&sin6->sin6_addr)[3]);
5905 #endif
5906 		hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16));
5907 		return (hash_of_addr);
5908 	}
5909 #endif
5910 #if defined(__Userspace__)
5911 	case AF_CONN:
5912 	{
5913 		struct sockaddr_conn *sconn;
5914 		uintptr_t temp;
5915 
5916 		sconn = (struct sockaddr_conn *)addr;
5917 		temp = (uintptr_t)sconn->sconn_addr;
5918 		return ((uint32_t)(temp ^ (temp >> 16)));
5919 	}
5920 #endif
5921 	default:
5922 		break;
5923 	}
5924 	return (0);
5925 }
5926 
5927 struct sctp_ifa *
5928 sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
5929 {
5930 	struct sctp_ifa *sctp_ifap;
5931 	struct sctp_vrf *vrf;
5932 	struct sctp_ifalist *hash_head;
5933 	uint32_t hash_of_addr;
5934 
5935 	if (holds_lock == 0)
5936 		SCTP_IPI_ADDR_RLOCK();
5937 
5938 	vrf = sctp_find_vrf(vrf_id);
5939 	if (vrf == NULL) {
5940 		if (holds_lock == 0)
5941 			SCTP_IPI_ADDR_RUNLOCK();
5942 		return (NULL);
5943 	}
5944 
5945 	hash_of_addr = sctp_get_ifa_hash_val(addr);
5946 
5947 	hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
5948 	if (hash_head == NULL) {
5949 		SCTP_PRINTF("hash_of_addr:%x mask:%x table:%x - ",
5950 			    hash_of_addr, (uint32_t)vrf->vrf_addr_hashmark,
5951 			    (uint32_t)(hash_of_addr & vrf->vrf_addr_hashmark));
5952 		sctp_print_address(addr);
5953 		SCTP_PRINTF("No such bucket for address\n");
5954 		if (holds_lock == 0)
5955 			SCTP_IPI_ADDR_RUNLOCK();
5956 
5957 		return (NULL);
5958 	}
5959 	LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
5960 		if (addr->sa_family != sctp_ifap->address.sa.sa_family)
5961 			continue;
5962 #ifdef INET
5963 		if (addr->sa_family == AF_INET) {
5964 			if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
5965 			    sctp_ifap->address.sin.sin_addr.s_addr) {
5966 				/* found him. */
5967 				if (holds_lock == 0)
5968 					SCTP_IPI_ADDR_RUNLOCK();
5969 				return (sctp_ifap);
5970 				break;
5971 			}
5972 		}
5973 #endif
5974 #ifdef INET6
5975 		if (addr->sa_family == AF_INET6) {
5976 			if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
5977 						 &sctp_ifap->address.sin6)) {
5978 				/* found him. */
5979 				if (holds_lock == 0)
5980 					SCTP_IPI_ADDR_RUNLOCK();
5981 				return (sctp_ifap);
5982 				break;
5983 			}
5984 		}
5985 #endif
5986 #if defined(__Userspace__)
5987 		if (addr->sa_family == AF_CONN) {
5988 			if (((struct sockaddr_conn *)addr)->sconn_addr == sctp_ifap->address.sconn.sconn_addr) {
5989 				/* found him. */
5990 				if (holds_lock == 0)
5991 					SCTP_IPI_ADDR_RUNLOCK();
5992 				return (sctp_ifap);
5993 				break;
5994 			}
5995 		}
5996 #endif
5997 	}
5998 	if (holds_lock == 0)
5999 		SCTP_IPI_ADDR_RUNLOCK();
6000 	return (NULL);
6001 }
6002 
6003 static void
6004 sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock,
6005 	       uint32_t rwnd_req)
6006 {
6007 	/* User pulled some data, do we need a rwnd update? */
6008 #if defined(__FreeBSD__)
6009 	struct epoch_tracker et;
6010 #endif
6011 	int r_unlocked = 0;
6012 	uint32_t dif, rwnd;
6013 	struct socket *so = NULL;
6014 
6015 	if (stcb == NULL)
6016 		return;
6017 
6018 	atomic_add_int(&stcb->asoc.refcnt, 1);
6019 
6020 	if ((SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
6021 	    (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED | SCTP_STATE_SHUTDOWN_RECEIVED))) {
6022 		/* Pre-check If we are freeing no update */
6023 		goto no_lock;
6024 	}
6025 	SCTP_INP_INCR_REF(stcb->sctp_ep);
6026 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6027 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
6028 		goto out;
6029 	}
6030 	so = stcb->sctp_socket;
6031 	if (so == NULL) {
6032 		goto out;
6033 	}
6034 	atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far);
6035 	/* Have you have freed enough to look */
6036 	*freed_so_far = 0;
6037 	/* Yep, its worth a look and the lock overhead */
6038 
6039 	/* Figure out what the rwnd would be */
6040 	rwnd = sctp_calc_rwnd(stcb, &stcb->asoc);
6041 	if (rwnd >= stcb->asoc.my_last_reported_rwnd) {
6042 		dif = rwnd - stcb->asoc.my_last_reported_rwnd;
6043 	} else {
6044 		dif = 0;
6045 	}
6046 	if (dif >= rwnd_req) {
6047 		if (hold_rlock) {
6048 			SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
6049 			r_unlocked = 1;
6050 		}
6051 		if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6052 			/*
6053 			 * One last check before we allow the guy possibly
6054 			 * to get in. There is a race, where the guy has not
6055 			 * reached the gate. In that case
6056 			 */
6057 			goto out;
6058 		}
6059 		SCTP_TCB_LOCK(stcb);
6060 		if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6061 			/* No reports here */
6062 			SCTP_TCB_UNLOCK(stcb);
6063 			goto out;
6064 		}
6065 		SCTP_STAT_INCR(sctps_wu_sacks_sent);
6066 #if defined(__FreeBSD__)
6067 		NET_EPOCH_ENTER(et);
6068 #endif
6069 		sctp_send_sack(stcb, SCTP_SO_LOCKED);
6070 
6071 		sctp_chunk_output(stcb->sctp_ep, stcb,
6072 				  SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
6073 		/* make sure no timer is running */
6074 #if defined(__FreeBSD__)
6075 		NET_EPOCH_EXIT(et);
6076 #endif
6077 		sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
6078 		                SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
6079 		SCTP_TCB_UNLOCK(stcb);
6080 	} else {
6081 		/* Update how much we have pending */
6082 		stcb->freed_by_sorcv_sincelast = dif;
6083 	}
6084  out:
6085 	if (so && r_unlocked && hold_rlock) {
6086 		SCTP_INP_READ_LOCK(stcb->sctp_ep);
6087 	}
6088 
6089 	SCTP_INP_DECR_REF(stcb->sctp_ep);
6090  no_lock:
6091 	atomic_add_int(&stcb->asoc.refcnt, -1);
6092 	return;
6093 }
6094 
6095 int
6096 sctp_sorecvmsg(struct socket *so,
6097     struct uio *uio,
6098     struct mbuf **mp,
6099     struct sockaddr *from,
6100     int fromlen,
6101     int *msg_flags,
6102     struct sctp_sndrcvinfo *sinfo,
6103     int filling_sinfo)
6104 {
6105 	/*
6106 	 * MSG flags we will look at MSG_DONTWAIT - non-blocking IO.
6107 	 * MSG_PEEK - Look don't touch :-D (only valid with OUT mbuf copy
6108 	 * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ??
6109 	 * On the way out we may send out any combination of:
6110 	 * MSG_NOTIFICATION MSG_EOR
6111 	 *
6112 	 */
6113 	struct sctp_inpcb *inp = NULL;
6114 	ssize_t my_len = 0;
6115 	ssize_t cp_len = 0;
6116 	int error = 0;
6117 	struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL;
6118 	struct mbuf *m = NULL;
6119 	struct sctp_tcb *stcb = NULL;
6120 	int wakeup_read_socket = 0;
6121 	int freecnt_applied = 0;
6122 	int out_flags = 0, in_flags = 0;
6123 	int block_allowed = 1;
6124 	uint32_t freed_so_far = 0;
6125 	ssize_t copied_so_far = 0;
6126 	int in_eeor_mode = 0;
6127 	int no_rcv_needed = 0;
6128 	uint32_t rwnd_req = 0;
6129 	int hold_sblock = 0;
6130 	int hold_rlock = 0;
6131 	ssize_t slen = 0;
6132 	uint32_t held_length = 0;
6133 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
6134 	int sockbuf_lock = 0;
6135 #endif
6136 
6137 	if (uio == NULL) {
6138 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6139 		return (EINVAL);
6140 	}
6141 
6142 	if (msg_flags) {
6143 		in_flags = *msg_flags;
6144 		if (in_flags & MSG_PEEK)
6145 			SCTP_STAT_INCR(sctps_read_peeks);
6146 	} else {
6147 		in_flags = 0;
6148 	}
6149 #if defined(__APPLE__)
6150 #if defined(APPLE_LEOPARD)
6151 	slen = uio->uio_resid;
6152 #else
6153 	slen = uio_resid(uio);
6154 #endif
6155 #else
6156 	slen = uio->uio_resid;
6157 #endif
6158 
6159 	/* Pull in and set up our int flags */
6160 	if (in_flags & MSG_OOB) {
6161 		/* Out of band's NOT supported */
6162 		return (EOPNOTSUPP);
6163 	}
6164 	if ((in_flags & MSG_PEEK) && (mp != NULL)) {
6165 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6166 		return (EINVAL);
6167 	}
6168 	if ((in_flags & (MSG_DONTWAIT
6169 #if defined(__FreeBSD__) && __FreeBSD_version > 500000
6170 			 | MSG_NBIO
6171 #endif
6172 		     )) ||
6173 	    SCTP_SO_IS_NBIO(so)) {
6174 		block_allowed = 0;
6175 	}
6176 	/* setup the endpoint */
6177 	inp = (struct sctp_inpcb *)so->so_pcb;
6178 	if (inp == NULL) {
6179 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
6180 		return (EFAULT);
6181 	}
6182 	rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
6183 	/* Must be at least a MTU's worth */
6184 	if (rwnd_req < SCTP_MIN_RWND)
6185 		rwnd_req = SCTP_MIN_RWND;
6186 	in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
6187 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) {
6188 #if defined(__APPLE__)
6189 #if defined(APPLE_LEOPARD)
6190 		sctp_misc_ints(SCTP_SORECV_ENTER,
6191 			       rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid);
6192 #else
6193 		sctp_misc_ints(SCTP_SORECV_ENTER,
6194 			       rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio_resid(uio));
6195 #endif
6196 #else
6197 		sctp_misc_ints(SCTP_SORECV_ENTER,
6198 			       rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid);
6199 #endif
6200 	}
6201 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
6202 	SOCKBUF_LOCK(&so->so_rcv);
6203 	hold_sblock = 1;
6204 #endif
6205 	if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
6206 #if defined(__APPLE__)
6207 #if defined(APPLE_LEOPARD)
6208 		sctp_misc_ints(SCTP_SORECV_ENTERPL,
6209 			       rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid);
6210 #else
6211 		sctp_misc_ints(SCTP_SORECV_ENTERPL,
6212 			       rwnd_req, block_allowed, so->so_rcv.sb_cc, uio_resid(uio));
6213 #endif
6214 #else
6215 		sctp_misc_ints(SCTP_SORECV_ENTERPL,
6216 			       rwnd_req, block_allowed, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid);
6217 #endif
6218 	}
6219 
6220 #if defined(__APPLE__)
6221 	error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6222 #endif
6223 
6224 #if defined(__FreeBSD__)
6225 	error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0));
6226 #endif
6227 	if (error) {
6228 		goto release_unlocked;
6229 	}
6230 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
6231         sockbuf_lock = 1;
6232 #endif
6233  restart:
6234 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
6235 	if (hold_sblock == 0) {
6236 		SOCKBUF_LOCK(&so->so_rcv);
6237 		hold_sblock = 1;
6238 	}
6239 #endif
6240 #if defined(__APPLE__)
6241 	sbunlock(&so->so_rcv, 1);
6242 #endif
6243 
6244 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
6245 	sbunlock(&so->so_rcv);
6246 #endif
6247 
6248  restart_nosblocks:
6249 	if (hold_sblock == 0) {
6250 		SOCKBUF_LOCK(&so->so_rcv);
6251 		hold_sblock = 1;
6252 	}
6253 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6254 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
6255 		goto out;
6256 	}
6257 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
6258 	if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) {
6259 #else
6260 	if ((so->so_state & SS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) {
6261 #endif
6262 		if (so->so_error) {
6263 			error = so->so_error;
6264 			if ((in_flags & MSG_PEEK) == 0)
6265 				so->so_error = 0;
6266 			goto out;
6267 		} else {
6268 			if (so->so_rcv.sb_cc == 0) {
6269 				/* indicate EOF */
6270 				error = 0;
6271 				goto out;
6272 			}
6273 		}
6274 	}
6275 	if (so->so_rcv.sb_cc <= held_length) {
6276 		if (so->so_error) {
6277 			error = so->so_error;
6278 			if ((in_flags & MSG_PEEK) == 0) {
6279 				so->so_error = 0;
6280 			}
6281 			goto out;
6282 		}
6283 		if ((so->so_rcv.sb_cc == 0) &&
6284 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
6285 		     (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
6286 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) {
6287 				/* For active open side clear flags for re-use
6288 				 * passive open is blocked by connect.
6289 				 */
6290 				if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) {
6291 					/* You were aborted, passive side always hits here */
6292 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
6293 					error = ECONNRESET;
6294 				}
6295 				so->so_state &= ~(SS_ISCONNECTING |
6296 						  SS_ISDISCONNECTING |
6297 						  SS_ISCONFIRMING |
6298 						  SS_ISCONNECTED);
6299 				if (error == 0) {
6300 					if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
6301 						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
6302 						error = ENOTCONN;
6303 					}
6304 				}
6305 				goto out;
6306 			}
6307 		}
6308 		if (block_allowed) {
6309 			error = sbwait(&so->so_rcv);
6310 			if (error) {
6311 				goto out;
6312 			}
6313 			held_length = 0;
6314 			goto restart_nosblocks;
6315 		} else {
6316 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK);
6317 			error = EWOULDBLOCK;
6318 			goto out;
6319 		}
6320 	}
6321 	if (hold_sblock == 1) {
6322 		SOCKBUF_UNLOCK(&so->so_rcv);
6323 		hold_sblock = 0;
6324 	}
6325 #if defined(__APPLE__)
6326 	error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6327 #endif
6328 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
6329 	error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0));
6330 #endif
6331 	/* we possibly have data we can read */
6332 	/*sa_ignore FREED_MEMORY*/
6333 	control = TAILQ_FIRST(&inp->read_queue);
6334 	if (control == NULL) {
6335 		/* This could be happening since
6336 		 * the appender did the increment but as not
6337 		 * yet did the tailq insert onto the read_queue
6338 		 */
6339 		if (hold_rlock == 0) {
6340 			SCTP_INP_READ_LOCK(inp);
6341 		}
6342 		control = TAILQ_FIRST(&inp->read_queue);
6343 		if ((control == NULL) && (so->so_rcv.sb_cc != 0)) {
6344 #ifdef INVARIANTS
6345 			panic("Huh, its non zero and nothing on control?");
6346 #endif
6347 			so->so_rcv.sb_cc = 0;
6348 		}
6349 		SCTP_INP_READ_UNLOCK(inp);
6350 		hold_rlock = 0;
6351 		goto restart;
6352 	}
6353 
6354 	if ((control->length == 0) &&
6355 	    (control->do_not_ref_stcb)) {
6356 		/* Clean up code for freeing assoc that left behind a pdapi..
6357 		 * maybe a peer in EEOR that just closed after sending and
6358 		 * never indicated a EOR.
6359 		 */
6360 		if (hold_rlock == 0) {
6361 			hold_rlock = 1;
6362 			SCTP_INP_READ_LOCK(inp);
6363 		}
6364 		control->held_length = 0;
6365 		if (control->data) {
6366 			/* Hmm there is data here .. fix */
6367 			struct mbuf *m_tmp;
6368 			int cnt = 0;
6369 			m_tmp = control->data;
6370 			while (m_tmp) {
6371 				cnt += SCTP_BUF_LEN(m_tmp);
6372 				if (SCTP_BUF_NEXT(m_tmp) == NULL) {
6373 					control->tail_mbuf = m_tmp;
6374 					control->end_added = 1;
6375 				}
6376 				m_tmp = SCTP_BUF_NEXT(m_tmp);
6377 			}
6378 			control->length = cnt;
6379 		} else {
6380 			/* remove it */
6381 			TAILQ_REMOVE(&inp->read_queue, control, next);
6382 			/* Add back any hiddend data */
6383 			sctp_free_remote_addr(control->whoFrom);
6384 			sctp_free_a_readq(stcb, control);
6385 		}
6386 		if (hold_rlock) {
6387 			hold_rlock = 0;
6388 			SCTP_INP_READ_UNLOCK(inp);
6389 		}
6390 		goto restart;
6391 	}
6392 	if ((control->length == 0) &&
6393 	    (control->end_added == 1)) {
6394 		/* Do we also need to check for (control->pdapi_aborted == 1)? */
6395 		if (hold_rlock == 0) {
6396 			hold_rlock = 1;
6397 			SCTP_INP_READ_LOCK(inp);
6398 		}
6399 		TAILQ_REMOVE(&inp->read_queue, control, next);
6400 		if (control->data) {
6401 #ifdef INVARIANTS
6402 			panic("control->data not null but control->length == 0");
6403 #else
6404 			SCTP_PRINTF("Strange, data left in the control buffer. Cleaning up.\n");
6405 			sctp_m_freem(control->data);
6406 			control->data = NULL;
6407 #endif
6408 		}
6409 		if (control->aux_data) {
6410 			sctp_m_free (control->aux_data);
6411 			control->aux_data = NULL;
6412 		}
6413 #ifdef INVARIANTS
6414 		if (control->on_strm_q) {
6415 			panic("About to free ctl:%p so:%p and its in %d",
6416 			      control, so, control->on_strm_q);
6417 		}
6418 #endif
6419 		sctp_free_remote_addr(control->whoFrom);
6420 		sctp_free_a_readq(stcb, control);
6421 		if (hold_rlock) {
6422 			hold_rlock = 0;
6423 			SCTP_INP_READ_UNLOCK(inp);
6424 		}
6425 		goto restart;
6426 	}
6427 	if (control->length == 0) {
6428 		if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) &&
6429 		    (filling_sinfo)) {
6430 			/* find a more suitable one then this */
6431 			ctl = TAILQ_NEXT(control, next);
6432 			while (ctl) {
6433 				if ((ctl->stcb != control->stcb) && (ctl->length) &&
6434 				    (ctl->some_taken ||
6435 				     (ctl->spec_flags & M_NOTIFICATION) ||
6436 				     ((ctl->do_not_ref_stcb == 0) &&
6437 				      (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
6438 					) {
6439 					/*-
6440 					 * If we have a different TCB next, and there is data
6441 					 * present. If we have already taken some (pdapi), OR we can
6442 					 * ref the tcb and no delivery as started on this stream, we
6443 					 * take it. Note we allow a notification on a different
6444 					 * assoc to be delivered..
6445 					 */
6446 					control = ctl;
6447 					goto found_one;
6448 				} else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) &&
6449 					   (ctl->length) &&
6450 					   ((ctl->some_taken) ||
6451 					    ((ctl->do_not_ref_stcb == 0) &&
6452 					     ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
6453 					     (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) {
6454 					/*-
6455 					 * If we have the same tcb, and there is data present, and we
6456 					 * have the strm interleave feature present. Then if we have
6457 					 * taken some (pdapi) or we can refer to tht tcb AND we have
6458 					 * not started a delivery for this stream, we can take it.
6459 					 * Note we do NOT allow a notificaiton on the same assoc to
6460 					 * be delivered.
6461 					 */
6462 					control = ctl;
6463 					goto found_one;
6464 				}
6465 				ctl = TAILQ_NEXT(ctl, next);
6466 			}
6467 		}
6468 		/*
6469 		 * if we reach here, not suitable replacement is available
6470 		 * <or> fragment interleave is NOT on. So stuff the sb_cc
6471 		 * into the our held count, and its time to sleep again.
6472 		 */
6473 		held_length = so->so_rcv.sb_cc;
6474 		control->held_length = so->so_rcv.sb_cc;
6475 		goto restart;
6476 	}
6477 	/* Clear the held length since there is something to read */
6478 	control->held_length = 0;
6479  found_one:
6480 	/*
6481 	 * If we reach here, control has a some data for us to read off.
6482 	 * Note that stcb COULD be NULL.
6483 	 */
6484 	if (hold_rlock == 0) {
6485 		hold_rlock = 1;
6486 		SCTP_INP_READ_LOCK(inp);
6487 	}
6488 	control->some_taken++;
6489 	stcb = control->stcb;
6490 	if (stcb) {
6491 		if ((control->do_not_ref_stcb == 0) &&
6492 		    (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
6493 			if (freecnt_applied == 0)
6494 				stcb = NULL;
6495 		} else if (control->do_not_ref_stcb == 0) {
6496 			/* you can't free it on me please */
6497 			/*
6498 			 * The lock on the socket buffer protects us so the
6499 			 * free code will stop. But since we used the socketbuf
6500 			 * lock and the sender uses the tcb_lock to increment,
6501 			 * we need to use the atomic add to the refcnt
6502 			 */
6503 			if (freecnt_applied) {
6504 #ifdef INVARIANTS
6505 				panic("refcnt already incremented");
6506 #else
6507 				SCTP_PRINTF("refcnt already incremented?\n");
6508 #endif
6509 			} else {
6510 				atomic_add_int(&stcb->asoc.refcnt, 1);
6511 				freecnt_applied = 1;
6512 			}
6513 			/*
6514 			 * Setup to remember how much we have not yet told
6515 			 * the peer our rwnd has opened up. Note we grab
6516 			 * the value from the tcb from last time.
6517 			 * Note too that sack sending clears this when a sack
6518 			 * is sent, which is fine. Once we hit the rwnd_req,
6519 			 * we then will go to the sctp_user_rcvd() that will
6520 			 * not lock until it KNOWs it MUST send a WUP-SACK.
6521 			 */
6522 			freed_so_far = (uint32_t)stcb->freed_by_sorcv_sincelast;
6523 			stcb->freed_by_sorcv_sincelast = 0;
6524 		}
6525 	}
6526 	if (stcb &&
6527 	    ((control->spec_flags & M_NOTIFICATION) == 0) &&
6528 	    control->do_not_ref_stcb == 0) {
6529 		stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
6530 	}
6531 
6532 	/* First lets get off the sinfo and sockaddr info */
6533 	if ((sinfo != NULL) && (filling_sinfo != 0)) {
6534 		sinfo->sinfo_stream = control->sinfo_stream;
6535 		sinfo->sinfo_ssn = (uint16_t)control->mid;
6536 		sinfo->sinfo_flags = control->sinfo_flags;
6537 		sinfo->sinfo_ppid = control->sinfo_ppid;
6538 		sinfo->sinfo_context =control->sinfo_context;
6539 		sinfo->sinfo_timetolive = control->sinfo_timetolive;
6540 		sinfo->sinfo_tsn = control->sinfo_tsn;
6541 		sinfo->sinfo_cumtsn = control->sinfo_cumtsn;
6542 		sinfo->sinfo_assoc_id = control->sinfo_assoc_id;
6543 		nxt = TAILQ_NEXT(control, next);
6544 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
6545 		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) {
6546 			struct sctp_extrcvinfo *s_extra;
6547 			s_extra = (struct sctp_extrcvinfo *)sinfo;
6548 			if ((nxt) &&
6549 			    (nxt->length)) {
6550 				s_extra->serinfo_next_flags = SCTP_NEXT_MSG_AVAIL;
6551 				if (nxt->sinfo_flags & SCTP_UNORDERED) {
6552 					s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED;
6553 				}
6554 				if (nxt->spec_flags & M_NOTIFICATION) {
6555 					s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION;
6556 				}
6557 				s_extra->serinfo_next_aid = nxt->sinfo_assoc_id;
6558 				s_extra->serinfo_next_length = nxt->length;
6559 				s_extra->serinfo_next_ppid = nxt->sinfo_ppid;
6560 				s_extra->serinfo_next_stream = nxt->sinfo_stream;
6561 				if (nxt->tail_mbuf != NULL) {
6562 					if (nxt->end_added) {
6563 						s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE;
6564 					}
6565 				}
6566 			} else {
6567 				/* we explicitly 0 this, since the memcpy got
6568 				 * some other things beyond the older sinfo_
6569 				 * that is on the control's structure :-D
6570 				 */
6571 				nxt = NULL;
6572 				s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
6573 				s_extra->serinfo_next_aid = 0;
6574 				s_extra->serinfo_next_length = 0;
6575 				s_extra->serinfo_next_ppid = 0;
6576 				s_extra->serinfo_next_stream = 0;
6577 			}
6578 		}
6579 		/*
6580 		 * update off the real current cum-ack, if we have an stcb.
6581 		 */
6582 		if ((control->do_not_ref_stcb == 0) && stcb)
6583 			sinfo->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
6584 		/*
6585 		 * mask off the high bits, we keep the actual chunk bits in
6586 		 * there.
6587 		 */
6588 		sinfo->sinfo_flags &= 0x00ff;
6589 		if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) {
6590 			sinfo->sinfo_flags |= SCTP_UNORDERED;
6591 		}
6592 	}
6593 #ifdef SCTP_ASOCLOG_OF_TSNS
6594 	{
6595 		int index, newindex;
6596 		struct sctp_pcbtsn_rlog *entry;
6597 		do {
6598 			index = inp->readlog_index;
6599 			newindex = index + 1;
6600 			if (newindex >= SCTP_READ_LOG_SIZE) {
6601 				newindex = 0;
6602 			}
6603 		} while (atomic_cmpset_int(&inp->readlog_index, index, newindex) == 0);
6604 		entry = &inp->readlog[index];
6605 		entry->vtag = control->sinfo_assoc_id;
6606 		entry->strm = control->sinfo_stream;
6607 		entry->seq = (uint16_t)control->mid;
6608 		entry->sz = control->length;
6609 		entry->flgs = control->sinfo_flags;
6610 	}
6611 #endif
6612 	if ((fromlen > 0) && (from != NULL)) {
6613 		union sctp_sockstore store;
6614 		size_t len;
6615 
6616 		switch (control->whoFrom->ro._l_addr.sa.sa_family) {
6617 #ifdef INET6
6618 			case AF_INET6:
6619 				len = sizeof(struct sockaddr_in6);
6620 				store.sin6 = control->whoFrom->ro._l_addr.sin6;
6621 				store.sin6.sin6_port = control->port_from;
6622 				break;
6623 #endif
6624 #ifdef INET
6625 			case AF_INET:
6626 #ifdef INET6
6627 				if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
6628 					len = sizeof(struct sockaddr_in6);
6629 					in6_sin_2_v4mapsin6(&control->whoFrom->ro._l_addr.sin,
6630 							    &store.sin6);
6631 					store.sin6.sin6_port = control->port_from;
6632 				} else {
6633 					len = sizeof(struct sockaddr_in);
6634 					store.sin = control->whoFrom->ro._l_addr.sin;
6635 					store.sin.sin_port = control->port_from;
6636 				}
6637 #else
6638 				len = sizeof(struct sockaddr_in);
6639 				store.sin = control->whoFrom->ro._l_addr.sin;
6640 				store.sin.sin_port = control->port_from;
6641 #endif
6642 				break;
6643 #endif
6644 #if defined(__Userspace__)
6645 			case AF_CONN:
6646 				len = sizeof(struct sockaddr_conn);
6647 				store.sconn = control->whoFrom->ro._l_addr.sconn;
6648 				store.sconn.sconn_port = control->port_from;
6649 				break;
6650 #endif
6651 			default:
6652 				len = 0;
6653 				break;
6654 		}
6655 		memcpy(from, &store, min((size_t)fromlen, len));
6656 #if defined(SCTP_EMBEDDED_V6_SCOPE)
6657 #ifdef INET6
6658 		{
6659 			struct sockaddr_in6 lsa6, *from6;
6660 
6661 			from6 = (struct sockaddr_in6 *)from;
6662 			sctp_recover_scope_mac(from6, (&lsa6));
6663 		}
6664 #endif
6665 #endif
6666 	}
6667 	if (hold_rlock) {
6668 		SCTP_INP_READ_UNLOCK(inp);
6669 		hold_rlock = 0;
6670 	}
6671 	if (hold_sblock) {
6672 		SOCKBUF_UNLOCK(&so->so_rcv);
6673 		hold_sblock = 0;
6674 	}
6675 	/* now copy out what data we can */
6676 	if (mp == NULL) {
6677 		/* copy out each mbuf in the chain up to length */
6678 	get_more_data:
6679 		m = control->data;
6680 		while (m) {
6681 			/* Move out all we can */
6682 #if defined(__APPLE__)
6683 #if defined(APPLE_LEOPARD)
6684 			cp_len = uio->uio_resid;
6685 #else
6686 			cp_len = uio_resid(uio);
6687 #endif
6688 #else
6689 			cp_len = uio->uio_resid;
6690 #endif
6691 			my_len = SCTP_BUF_LEN(m);
6692 			if (cp_len > my_len) {
6693 				/* not enough in this buf */
6694 				cp_len = my_len;
6695 			}
6696 			if (hold_rlock) {
6697 				SCTP_INP_READ_UNLOCK(inp);
6698 				hold_rlock = 0;
6699 			}
6700 #if defined(__APPLE__)
6701 			SCTP_SOCKET_UNLOCK(so, 0);
6702 #endif
6703 			if (cp_len > 0)
6704 				error = uiomove(mtod(m, char *), (int)cp_len, uio);
6705 #if defined(__APPLE__)
6706 			SCTP_SOCKET_LOCK(so, 0);
6707 #endif
6708 			/* re-read */
6709 			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
6710 				goto release;
6711 			}
6712 
6713 			if ((control->do_not_ref_stcb == 0) && stcb &&
6714 			    stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6715 				no_rcv_needed = 1;
6716 			}
6717 			if (error) {
6718 				/* error we are out of here */
6719 				goto release;
6720 			}
6721 			SCTP_INP_READ_LOCK(inp);
6722 			hold_rlock = 1;
6723 			if (cp_len == SCTP_BUF_LEN(m)) {
6724 				if ((SCTP_BUF_NEXT(m)== NULL) &&
6725 				    (control->end_added)) {
6726 					out_flags |= MSG_EOR;
6727 					if ((control->do_not_ref_stcb == 0)  &&
6728 					    (control->stcb != NULL) &&
6729 					    ((control->spec_flags & M_NOTIFICATION) == 0))
6730 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6731 				}
6732 				if (control->spec_flags & M_NOTIFICATION) {
6733 					out_flags |= MSG_NOTIFICATION;
6734 				}
6735 				/* we ate up the mbuf */
6736 				if (in_flags & MSG_PEEK) {
6737 					/* just looking */
6738 					m = SCTP_BUF_NEXT(m);
6739 					copied_so_far += cp_len;
6740 				} else {
6741 					/* dispose of the mbuf */
6742 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6743 						sctp_sblog(&so->so_rcv,
6744 						   control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
6745 					}
6746 					sctp_sbfree(control, stcb, &so->so_rcv, m);
6747 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6748 						sctp_sblog(&so->so_rcv,
6749 						   control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
6750 					}
6751 					copied_so_far += cp_len;
6752 					freed_so_far += (uint32_t)cp_len;
6753 					freed_so_far += MSIZE;
6754 					atomic_subtract_int(&control->length, cp_len);
6755 					control->data = sctp_m_free(m);
6756 					m = control->data;
6757 					/* been through it all, must hold sb lock ok to null tail */
6758 					if (control->data == NULL) {
6759 #ifdef INVARIANTS
6760 #if defined(__FreeBSD__)
6761 						if ((control->end_added == 0) ||
6762 						    (TAILQ_NEXT(control, next) == NULL)) {
6763 							/* If the end is not added, OR the
6764 							 * next is NOT null we MUST have the lock.
6765 							 */
6766 							if (mtx_owned(&inp->inp_rdata_mtx) == 0) {
6767 								panic("Hmm we don't own the lock?");
6768 							}
6769 						}
6770 #endif
6771 #endif
6772 						control->tail_mbuf = NULL;
6773 #ifdef INVARIANTS
6774 						if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) {
6775 							panic("end_added, nothing left and no MSG_EOR");
6776 						}
6777 #endif
6778 					}
6779 				}
6780 			} else {
6781 				/* Do we need to trim the mbuf? */
6782 				if (control->spec_flags & M_NOTIFICATION) {
6783 					out_flags |= MSG_NOTIFICATION;
6784 				}
6785 				if ((in_flags & MSG_PEEK) == 0) {
6786 					SCTP_BUF_RESV_UF(m, cp_len);
6787 					SCTP_BUF_LEN(m) -= (int)cp_len;
6788 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6789 						sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, (int)cp_len);
6790 					}
6791 					atomic_subtract_int(&so->so_rcv.sb_cc, cp_len);
6792 					if ((control->do_not_ref_stcb == 0) &&
6793 					    stcb) {
6794 						atomic_subtract_int(&stcb->asoc.sb_cc, cp_len);
6795 					}
6796 					copied_so_far += cp_len;
6797 					freed_so_far += (uint32_t)cp_len;
6798 					freed_so_far += MSIZE;
6799 					if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6800 						sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb,
6801 							   SCTP_LOG_SBRESULT, 0);
6802 					}
6803 					atomic_subtract_int(&control->length, cp_len);
6804 				} else {
6805 					copied_so_far += cp_len;
6806 				}
6807 			}
6808 #if defined(__APPLE__)
6809 #if defined(APPLE_LEOPARD)
6810 			if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
6811 #else
6812 			if ((out_flags & MSG_EOR) || (uio_resid(uio) == 0)) {
6813 #endif
6814 #else
6815 			if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
6816 #endif
6817 				break;
6818 			}
6819 			if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
6820 			    (control->do_not_ref_stcb == 0) &&
6821 			    (freed_so_far >= rwnd_req)) {
6822 				sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6823 			}
6824 		} /* end while(m) */
6825 		/*
6826 		 * At this point we have looked at it all and we either have
6827 		 * a MSG_EOR/or read all the user wants... <OR>
6828 		 * control->length == 0.
6829 		 */
6830 		if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) {
6831 			/* we are done with this control */
6832 			if (control->length == 0) {
6833 				if (control->data) {
6834 #ifdef INVARIANTS
6835 					panic("control->data not null at read eor?");
6836 #else
6837 					SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n");
6838 					sctp_m_freem(control->data);
6839 					control->data = NULL;
6840 #endif
6841 				}
6842 			done_with_control:
6843 				if (hold_rlock == 0) {
6844 					SCTP_INP_READ_LOCK(inp);
6845 					hold_rlock = 1;
6846 				}
6847 				TAILQ_REMOVE(&inp->read_queue, control, next);
6848 				/* Add back any hiddend data */
6849 				if (control->held_length) {
6850 					held_length = 0;
6851 					control->held_length = 0;
6852 					wakeup_read_socket = 1;
6853 				}
6854 				if (control->aux_data) {
6855 					sctp_m_free (control->aux_data);
6856 					control->aux_data = NULL;
6857 				}
6858 				no_rcv_needed = control->do_not_ref_stcb;
6859 				sctp_free_remote_addr(control->whoFrom);
6860 				control->data = NULL;
6861 #ifdef INVARIANTS
6862 				if (control->on_strm_q) {
6863 					panic("About to free ctl:%p so:%p and its in %d",
6864 					      control, so, control->on_strm_q);
6865 				}
6866 #endif
6867 				sctp_free_a_readq(stcb, control);
6868 				control = NULL;
6869 				if ((freed_so_far >= rwnd_req) &&
6870 				    (no_rcv_needed == 0))
6871 					sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6872 
6873 			} else {
6874 				/*
6875 				 * The user did not read all of this
6876 				 * message, turn off the returned MSG_EOR
6877 				 * since we are leaving more behind on the
6878 				 * control to read.
6879 				 */
6880 #ifdef INVARIANTS
6881 				if (control->end_added &&
6882 				    (control->data == NULL) &&
6883 				    (control->tail_mbuf == NULL)) {
6884 					panic("Gak, control->length is corrupt?");
6885 				}
6886 #endif
6887 				no_rcv_needed = control->do_not_ref_stcb;
6888 				out_flags &= ~MSG_EOR;
6889 			}
6890 		}
6891 		if (out_flags & MSG_EOR) {
6892 			goto release;
6893 		}
6894 #if defined(__APPLE__)
6895 #if defined(APPLE_LEOPARD)
6896 		if ((uio->uio_resid == 0) ||
6897 #else
6898 		if ((uio_resid(uio) == 0) ||
6899 #endif
6900 #else
6901 		if ((uio->uio_resid == 0) ||
6902 #endif
6903 		    ((in_eeor_mode) &&
6904 		     (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))) {
6905 			goto release;
6906 		}
6907 		/*
6908 		 * If I hit here the receiver wants more and this message is
6909 		 * NOT done (pd-api). So two questions. Can we block? if not
6910 		 * we are done. Did the user NOT set MSG_WAITALL?
6911 		 */
6912 		if (block_allowed == 0) {
6913 			goto release;
6914 		}
6915 		/*
6916 		 * We need to wait for more data a few things: - We don't
6917 		 * sbunlock() so we don't get someone else reading. - We
6918 		 * must be sure to account for the case where what is added
6919 		 * is NOT to our control when we wakeup.
6920 		 */
6921 
6922 		/* Do we need to tell the transport a rwnd update might be
6923 		 * needed before we go to sleep?
6924 		 */
6925 		if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
6926 		    ((freed_so_far >= rwnd_req) &&
6927 		     (control->do_not_ref_stcb == 0) &&
6928 		     (no_rcv_needed == 0))) {
6929 			sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6930 		}
6931 	wait_some_more:
6932 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
6933 		if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
6934 			goto release;
6935 		}
6936 #else
6937 		if (so->so_state & SS_CANTRCVMORE) {
6938 			goto release;
6939 		}
6940 #endif
6941 
6942 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)
6943 			goto release;
6944 
6945 		if (hold_rlock == 1) {
6946 			SCTP_INP_READ_UNLOCK(inp);
6947 			hold_rlock = 0;
6948 		}
6949 		if (hold_sblock == 0) {
6950 			SOCKBUF_LOCK(&so->so_rcv);
6951 			hold_sblock = 1;
6952 		}
6953 		if ((copied_so_far) && (control->length == 0) &&
6954 		    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
6955 			goto release;
6956 		}
6957 #if defined(__APPLE__)
6958 		sbunlock(&so->so_rcv, 1);
6959 #endif
6960 		if (so->so_rcv.sb_cc <= control->held_length) {
6961 			error = sbwait(&so->so_rcv);
6962 			if (error) {
6963 #if defined(__FreeBSD__)
6964 				goto release;
6965 #else
6966 				goto release_unlocked;
6967 #endif
6968 			}
6969 			control->held_length = 0;
6970 		}
6971 #if defined(__APPLE__)
6972 		error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6973 #endif
6974 		if (hold_sblock) {
6975 			SOCKBUF_UNLOCK(&so->so_rcv);
6976 			hold_sblock = 0;
6977 		}
6978 		if (control->length == 0) {
6979 			/* still nothing here */
6980 			if (control->end_added == 1) {
6981 				/* he aborted, or is done i.e.did a shutdown */
6982 				out_flags |= MSG_EOR;
6983 				if (control->pdapi_aborted) {
6984 					if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
6985 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6986 
6987 					out_flags |= MSG_TRUNC;
6988 				} else {
6989 					if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
6990 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6991 				}
6992 				goto done_with_control;
6993 			}
6994 			if (so->so_rcv.sb_cc > held_length) {
6995 				control->held_length = so->so_rcv.sb_cc;
6996 				held_length = 0;
6997 			}
6998 			goto wait_some_more;
6999 		} else if (control->data == NULL) {
7000 			/* we must re-sync since data
7001 			 * is probably being added
7002 			 */
7003 			SCTP_INP_READ_LOCK(inp);
7004 			if ((control->length > 0) && (control->data == NULL)) {
7005 				/* big trouble.. we have the lock and its corrupt? */
7006 #ifdef INVARIANTS
7007 				panic ("Impossible data==NULL length !=0");
7008 #endif
7009 				out_flags |= MSG_EOR;
7010 				out_flags |= MSG_TRUNC;
7011 				control->length = 0;
7012 				SCTP_INP_READ_UNLOCK(inp);
7013 				goto done_with_control;
7014 			}
7015 			SCTP_INP_READ_UNLOCK(inp);
7016 			/* We will fall around to get more data */
7017 		}
7018 		goto get_more_data;
7019 	} else {
7020 		/*-
7021 		 * Give caller back the mbuf chain,
7022 		 * store in uio_resid the length
7023 		 */
7024 		wakeup_read_socket = 0;
7025 		if ((control->end_added == 0) ||
7026 		    (TAILQ_NEXT(control, next) == NULL)) {
7027 			/* Need to get rlock */
7028 			if (hold_rlock == 0) {
7029 				SCTP_INP_READ_LOCK(inp);
7030 				hold_rlock = 1;
7031 			}
7032 		}
7033 		if (control->end_added) {
7034 			out_flags |= MSG_EOR;
7035 			if ((control->do_not_ref_stcb == 0) &&
7036 			    (control->stcb != NULL) &&
7037 			    ((control->spec_flags & M_NOTIFICATION) == 0))
7038 				control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
7039 		}
7040 		if (control->spec_flags & M_NOTIFICATION) {
7041 			out_flags |= MSG_NOTIFICATION;
7042 		}
7043 #if defined(__APPLE__)
7044 #if defined(APPLE_LEOPARD)
7045 		uio->uio_resid = control->length;
7046 #else
7047 		uio_setresid(uio, control->length);
7048 #endif
7049 #else
7050 		uio->uio_resid = control->length;
7051 #endif
7052 		*mp = control->data;
7053 		m = control->data;
7054 		while (m) {
7055 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
7056 				sctp_sblog(&so->so_rcv,
7057 				   control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
7058 			}
7059 			sctp_sbfree(control, stcb, &so->so_rcv, m);
7060 			freed_so_far += (uint32_t)SCTP_BUF_LEN(m);
7061 			freed_so_far += MSIZE;
7062 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
7063 				sctp_sblog(&so->so_rcv,
7064 				   control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
7065 			}
7066 			m = SCTP_BUF_NEXT(m);
7067 		}
7068 		control->data = control->tail_mbuf = NULL;
7069 		control->length = 0;
7070 		if (out_flags & MSG_EOR) {
7071 			/* Done with this control */
7072 			goto done_with_control;
7073 		}
7074 	}
7075  release:
7076 	if (hold_rlock == 1) {
7077 		SCTP_INP_READ_UNLOCK(inp);
7078 		hold_rlock = 0;
7079 	}
7080 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
7081 	if (hold_sblock == 0) {
7082 		SOCKBUF_LOCK(&so->so_rcv);
7083 		hold_sblock = 1;
7084 	}
7085 #else
7086 	if (hold_sblock == 1) {
7087 		SOCKBUF_UNLOCK(&so->so_rcv);
7088 		hold_sblock = 0;
7089 	}
7090 #endif
7091 #if defined(__APPLE__)
7092 	sbunlock(&so->so_rcv, 1);
7093 #endif
7094 
7095 #if defined(__FreeBSD__)
7096 	sbunlock(&so->so_rcv);
7097 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
7098 	sockbuf_lock = 0;
7099 #endif
7100 #endif
7101 
7102  release_unlocked:
7103 	if (hold_sblock) {
7104 		SOCKBUF_UNLOCK(&so->so_rcv);
7105 		hold_sblock = 0;
7106 	}
7107 	if ((stcb) && (in_flags & MSG_PEEK) == 0) {
7108 		if ((freed_so_far >= rwnd_req) &&
7109 		    (control && (control->do_not_ref_stcb == 0)) &&
7110 		    (no_rcv_needed == 0))
7111 			sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
7112 	}
7113  out:
7114 	if (msg_flags) {
7115 		*msg_flags = out_flags;
7116 	}
7117 	if (((out_flags & MSG_EOR) == 0) &&
7118 	    ((in_flags & MSG_PEEK) == 0) &&
7119 	    (sinfo) &&
7120 	    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
7121 	     sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO))) {
7122 		struct sctp_extrcvinfo *s_extra;
7123 		s_extra = (struct sctp_extrcvinfo *)sinfo;
7124 		s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
7125 	}
7126 	if (hold_rlock == 1) {
7127 		SCTP_INP_READ_UNLOCK(inp);
7128 	}
7129 	if (hold_sblock) {
7130 		SOCKBUF_UNLOCK(&so->so_rcv);
7131 	}
7132 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
7133 	if (sockbuf_lock) {
7134 		sbunlock(&so->so_rcv);
7135 	}
7136 #endif
7137 
7138 	if (freecnt_applied) {
7139 		/*
7140 		 * The lock on the socket buffer protects us so the free
7141 		 * code will stop. But since we used the socketbuf lock and
7142 		 * the sender uses the tcb_lock to increment, we need to use
7143 		 * the atomic add to the refcnt.
7144 		 */
7145 		if (stcb == NULL) {
7146 #ifdef INVARIANTS
7147 			panic("stcb for refcnt has gone NULL?");
7148 			goto stage_left;
7149 #else
7150 			goto stage_left;
7151 #endif
7152 		}
7153 		/* Save the value back for next time */
7154 		stcb->freed_by_sorcv_sincelast = freed_so_far;
7155 		atomic_add_int(&stcb->asoc.refcnt, -1);
7156 	}
7157 	if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
7158 		if (stcb) {
7159 			sctp_misc_ints(SCTP_SORECV_DONE,
7160 				       freed_so_far,
7161 #if defined(__APPLE__)
7162 #if defined(APPLE_LEOPARD)
7163 				       ((uio) ? (slen - uio->uio_resid) : slen),
7164 #else
7165 				       ((uio) ? (slen - uio_resid(uio)) : slen),
7166 #endif
7167 #else
7168 				       (uint32_t)((uio) ? (slen - uio->uio_resid) : slen),
7169 #endif
7170 				       stcb->asoc.my_rwnd,
7171 				       so->so_rcv.sb_cc);
7172 		} else {
7173 			sctp_misc_ints(SCTP_SORECV_DONE,
7174 				       freed_so_far,
7175 #if defined(__APPLE__)
7176 #if defined(APPLE_LEOPARD)
7177 				       ((uio) ? (slen - uio->uio_resid) : slen),
7178 #else
7179 				       ((uio) ? (slen - uio_resid(uio)) : slen),
7180 #endif
7181 #else
7182 				       (uint32_t)((uio) ? (slen - uio->uio_resid) : slen),
7183 #endif
7184 				       0,
7185 				       so->so_rcv.sb_cc);
7186 		}
7187 	}
7188  stage_left:
7189 	if (wakeup_read_socket) {
7190 		sctp_sorwakeup(inp, so);
7191 	}
7192 	return (error);
7193 }
7194 
7195 
7196 #ifdef SCTP_MBUF_LOGGING
7197 struct mbuf *
7198 sctp_m_free(struct mbuf *m)
7199 {
7200 	if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
7201 		sctp_log_mb(m, SCTP_MBUF_IFREE);
7202 	}
7203 	return (m_free(m));
7204 }
7205 
7206 void
7207 sctp_m_freem(struct mbuf *mb)
7208 {
7209 	while (mb != NULL)
7210 		mb = sctp_m_free(mb);
7211 }
7212 
7213 #endif
7214 
7215 int
7216 sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
7217 {
7218 	/* Given a local address. For all associations
7219 	 * that holds the address, request a peer-set-primary.
7220 	 */
7221 	struct sctp_ifa *ifa;
7222 	struct sctp_laddr *wi;
7223 
7224 	ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
7225 	if (ifa == NULL) {
7226 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL);
7227 		return (EADDRNOTAVAIL);
7228 	}
7229 	/* Now that we have the ifa we must awaken the
7230 	 * iterator with this message.
7231 	 */
7232 	wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
7233 	if (wi == NULL) {
7234 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
7235 		return (ENOMEM);
7236 	}
7237 	/* Now incr the count and int wi structure */
7238 	SCTP_INCR_LADDR_COUNT();
7239 	memset(wi, 0, sizeof(*wi));
7240 	(void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
7241 	wi->ifa = ifa;
7242 	wi->action = SCTP_SET_PRIM_ADDR;
7243 	atomic_add_int(&ifa->refcount, 1);
7244 
7245 	/* Now add it to the work queue */
7246 	SCTP_WQ_ADDR_LOCK();
7247 	/*
7248 	 * Should this really be a tailq? As it is we will process the
7249 	 * newest first :-0
7250 	 */
7251 	LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
7252 	sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
7253 			 (struct sctp_inpcb *)NULL,
7254 			 (struct sctp_tcb *)NULL,
7255 			 (struct sctp_nets *)NULL);
7256 	SCTP_WQ_ADDR_UNLOCK();
7257 	return (0);
7258 }
7259 
7260 #if defined(__Userspace__)
7261 /* no sctp_soreceive for __Userspace__ now */
7262 #endif
7263 
7264 #if !defined(__Userspace__)
7265 int
7266 sctp_soreceive(	struct socket *so,
7267 		struct sockaddr **psa,
7268 		struct uio *uio,
7269 		struct mbuf **mp0,
7270 		struct mbuf **controlp,
7271 		int *flagsp)
7272 {
7273 	int error, fromlen;
7274 	uint8_t sockbuf[256];
7275 	struct sockaddr *from;
7276 	struct sctp_extrcvinfo sinfo;
7277 	int filling_sinfo = 1;
7278 	int flags;
7279 	struct sctp_inpcb *inp;
7280 
7281 	inp = (struct sctp_inpcb *)so->so_pcb;
7282 	/* pickup the assoc we are reading from */
7283 	if (inp == NULL) {
7284 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7285 		return (EINVAL);
7286 	}
7287 	if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT) &&
7288 	     sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
7289 	     sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) ||
7290 	    (controlp == NULL)) {
7291 		/* user does not want the sndrcv ctl */
7292 		filling_sinfo = 0;
7293 	}
7294 	if (psa) {
7295 		from = (struct sockaddr *)sockbuf;
7296 		fromlen = sizeof(sockbuf);
7297 #ifdef HAVE_SA_LEN
7298 		from->sa_len = 0;
7299 #endif
7300 	} else {
7301 		from = NULL;
7302 		fromlen = 0;
7303 	}
7304 
7305 #if defined(__APPLE__)
7306 	SCTP_SOCKET_LOCK(so, 1);
7307 #endif
7308 	if (filling_sinfo) {
7309 		memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
7310 	}
7311 	if (flagsp != NULL) {
7312 		flags = *flagsp;
7313 	} else {
7314 		flags = 0;
7315 	}
7316 	error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, &flags,
7317 	    (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
7318 	if (flagsp != NULL) {
7319 		*flagsp = flags;
7320 	}
7321 	if (controlp != NULL) {
7322 		/* copy back the sinfo in a CMSG format */
7323 		if (filling_sinfo && ((flags & MSG_NOTIFICATION) == 0)) {
7324 			*controlp = sctp_build_ctl_nchunk(inp,
7325 			                                  (struct sctp_sndrcvinfo *)&sinfo);
7326 		} else {
7327 			*controlp = NULL;
7328 		}
7329 	}
7330 	if (psa) {
7331 		/* copy back the address info */
7332 #ifdef HAVE_SA_LEN
7333 		if (from && from->sa_len) {
7334 #else
7335 		if (from) {
7336 #endif
7337 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
7338 			*psa = sodupsockaddr(from, M_NOWAIT);
7339 #else
7340 			*psa = dup_sockaddr(from, mp0 == 0);
7341 #endif
7342 		} else {
7343 			*psa = NULL;
7344 		}
7345 	}
7346 #if defined(__APPLE__)
7347 	SCTP_SOCKET_UNLOCK(so, 1);
7348 #endif
7349 	return (error);
7350 }
7351 
7352 
7353 #if (defined(__FreeBSD__) && __FreeBSD_version < 603000) || defined(__Windows__)
7354 /*
7355  * General routine to allocate a hash table with control of memory flags.
7356  * is in 7.0 and beyond for sure :-)
7357  */
7358 void *
7359 sctp_hashinit_flags(int elements, struct malloc_type *type,
7360                     u_long *hashmask, int flags)
7361 {
7362 	long hashsize;
7363 	LIST_HEAD(generic, generic) *hashtbl;
7364 	int i;
7365 
7366 
7367 	if (elements <= 0) {
7368 #ifdef INVARIANTS
7369 		panic("hashinit: bad elements");
7370 #else
7371 		SCTP_PRINTF("hashinit: bad elements?");
7372 		elements = 1;
7373 #endif
7374 	}
7375 	for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
7376 		continue;
7377 	hashsize >>= 1;
7378 	if (flags & HASH_WAITOK)
7379 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
7380 	else if (flags & HASH_NOWAIT)
7381 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_NOWAIT);
7382 	else {
7383 #ifdef INVARIANTS
7384 		panic("flag incorrect in hashinit_flags");
7385 #else
7386 		return (NULL);
7387 #endif
7388 	}
7389 
7390 	/* no memory? */
7391 	if (hashtbl == NULL)
7392 		return (NULL);
7393 
7394 	for (i = 0; i < hashsize; i++)
7395 		LIST_INIT(&hashtbl[i]);
7396 	*hashmask = hashsize - 1;
7397 	return (hashtbl);
7398 }
7399 #endif
7400 
7401 #else /*  __Userspace__ ifdef above sctp_soreceive */
7402 /*
7403  * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland.
7404  * NOTE: We don't want multiple definitions here. So sctp_hashinit_flags() above for
7405  *__FreeBSD__ must be excluded.
7406  *
7407  */
7408 
7409 void *
7410 sctp_hashinit_flags(int elements, struct malloc_type *type,
7411                     u_long *hashmask, int flags)
7412 {
7413 	long hashsize;
7414 	LIST_HEAD(generic, generic) *hashtbl;
7415 	int i;
7416 
7417 	if (elements <= 0) {
7418 		SCTP_PRINTF("hashinit: bad elements?");
7419 #ifdef INVARIANTS
7420 		return (NULL);
7421 #else
7422 		elements = 1;
7423 #endif
7424 	}
7425 	for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
7426 		continue;
7427 	hashsize >>= 1;
7428 	/*cannot use MALLOC here because it has to be declared or defined
7429 	  using MALLOC_DECLARE or MALLOC_DEFINE first. */
7430 	if (flags & HASH_WAITOK)
7431 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
7432 	else if (flags & HASH_NOWAIT)
7433 		hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
7434 	else {
7435 #ifdef INVARIANTS
7436 		SCTP_PRINTF("flag incorrect in hashinit_flags.\n");
7437 #endif
7438 		return (NULL);
7439 	}
7440 
7441 	/* no memory? */
7442 	if (hashtbl == NULL)
7443 		return (NULL);
7444 
7445 	for (i = 0; i < hashsize; i++)
7446 		LIST_INIT(&hashtbl[i]);
7447 	*hashmask = hashsize - 1;
7448 	return (hashtbl);
7449 }
7450 
7451 
7452 void
7453 sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
7454 {
7455 	LIST_HEAD(generic, generic) *hashtbl, *hp;
7456 
7457 	hashtbl = vhashtbl;
7458 	for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
7459 		if (!LIST_EMPTY(hp)) {
7460 			SCTP_PRINTF("hashdestroy: hash not empty.\n");
7461 			return;
7462 		}
7463 	FREE(hashtbl, type);
7464 }
7465 
7466 
7467 void
7468 sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
7469 {
7470 	LIST_HEAD(generic, generic) *hashtbl/*, *hp*/;
7471 	/*
7472 	LIST_ENTRY(type) *start, *temp;
7473 	 */
7474 	hashtbl = vhashtbl;
7475 	/* Apparently temp is not dynamically allocated, so attempts to
7476 	   free it results in error.
7477 	for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
7478 		if (!LIST_EMPTY(hp)) {
7479 			start = LIST_FIRST(hp);
7480 			while (start != NULL) {
7481 				temp = start;
7482 				start = start->le_next;
7483 				SCTP_PRINTF("%s: %p \n", __func__, (void *)temp);
7484 				FREE(temp, type);
7485 			}
7486 		}
7487 	 */
7488 	FREE(hashtbl, type);
7489 }
7490 
7491 
7492 #endif
7493 
7494 
7495 int
7496 sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
7497 			 int totaddr, int *error)
7498 {
7499 	int added = 0;
7500 	int i;
7501 	struct sctp_inpcb *inp;
7502 	struct sockaddr *sa;
7503 	size_t incr = 0;
7504 #ifdef INET
7505 	struct sockaddr_in *sin;
7506 #endif
7507 #ifdef INET6
7508 	struct sockaddr_in6 *sin6;
7509 #endif
7510 
7511 	sa = addr;
7512 	inp = stcb->sctp_ep;
7513 	*error = 0;
7514 	for (i = 0; i < totaddr; i++) {
7515 		switch (sa->sa_family) {
7516 #ifdef INET
7517 		case AF_INET:
7518 			incr = sizeof(struct sockaddr_in);
7519 			sin = (struct sockaddr_in *)sa;
7520 			if ((sin->sin_addr.s_addr == INADDR_ANY) ||
7521 			    (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
7522 			    IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
7523 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7524 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7525 				                      SCTP_FROM_SCTPUTIL + SCTP_LOC_7);
7526 				*error = EINVAL;
7527 				goto out_now;
7528 			}
7529 			if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7530 			                         SCTP_DONOT_SETSCOPE,
7531 			                         SCTP_ADDR_IS_CONFIRMED)) {
7532 				/* assoc gone no un-lock */
7533 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7534 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7535 				                      SCTP_FROM_SCTPUTIL + SCTP_LOC_8);
7536 				*error = ENOBUFS;
7537 				goto out_now;
7538 			}
7539 			added++;
7540 			break;
7541 #endif
7542 #ifdef INET6
7543 		case AF_INET6:
7544 			incr = sizeof(struct sockaddr_in6);
7545 			sin6 = (struct sockaddr_in6 *)sa;
7546 			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
7547 			    IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
7548 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7549 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7550 				                      SCTP_FROM_SCTPUTIL + SCTP_LOC_9);
7551 				*error = EINVAL;
7552 				goto out_now;
7553 			}
7554 			if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7555 			                         SCTP_DONOT_SETSCOPE,
7556 			                         SCTP_ADDR_IS_CONFIRMED)) {
7557 				/* assoc gone no un-lock */
7558 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7559 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7560 				                      SCTP_FROM_SCTPUTIL + SCTP_LOC_10);
7561 				*error = ENOBUFS;
7562 				goto out_now;
7563 			}
7564 			added++;
7565 			break;
7566 #endif
7567 #if defined(__Userspace__)
7568 		case AF_CONN:
7569 			incr = sizeof(struct sockaddr_conn);
7570 			if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7571 			                         SCTP_DONOT_SETSCOPE,
7572 			                         SCTP_ADDR_IS_CONFIRMED)) {
7573 				/* assoc gone no un-lock */
7574 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7575 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7576 				                      SCTP_FROM_SCTPUTIL + SCTP_LOC_11);
7577 				*error = ENOBUFS;
7578 				goto out_now;
7579 			}
7580 			added++;
7581 			break;
7582 #endif
7583 		default:
7584 			break;
7585 		}
7586 		sa = (struct sockaddr *)((caddr_t)sa + incr);
7587 	}
7588  out_now:
7589 	return (added);
7590 }
7591 
7592 int
7593 sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
7594 			  unsigned int totaddr,
7595 			  unsigned int *num_v4, unsigned int *num_v6,
7596 			  unsigned int limit)
7597 {
7598 	struct sockaddr *sa;
7599 	struct sctp_tcb *stcb;
7600 	unsigned int incr, at, i;
7601 
7602 	at = 0;
7603 	sa = addr;
7604 	*num_v6 = *num_v4 = 0;
7605 	/* account and validate addresses */
7606 	if (totaddr == 0) {
7607 		return (EINVAL);
7608 	}
7609 	for (i = 0; i < totaddr; i++) {
7610 		if (at + sizeof(struct sockaddr) > limit) {
7611 			return (EINVAL);
7612 		}
7613 		switch (sa->sa_family) {
7614 #ifdef INET
7615 		case AF_INET:
7616 			incr = (unsigned int)sizeof(struct sockaddr_in);
7617 #ifdef HAVE_SA_LEN
7618 			if (sa->sa_len != incr) {
7619 				return (EINVAL);
7620 			}
7621 #endif
7622 			(*num_v4) += 1;
7623 			break;
7624 #endif
7625 #ifdef INET6
7626 		case AF_INET6:
7627 		{
7628 			struct sockaddr_in6 *sin6;
7629 
7630 			sin6 = (struct sockaddr_in6 *)sa;
7631 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7632 				/* Must be non-mapped for connectx */
7633 				return (EINVAL);
7634 			}
7635 			incr = (unsigned int)sizeof(struct sockaddr_in6);
7636 #ifdef HAVE_SA_LEN
7637 			if (sa->sa_len != incr) {
7638 				return (EINVAL);
7639 			}
7640 #endif
7641 			(*num_v6) += 1;
7642 			break;
7643 		}
7644 #endif
7645 		default:
7646 			return (EINVAL);
7647 		}
7648 		if ((at + incr) > limit) {
7649 			return (EINVAL);
7650 		}
7651 		SCTP_INP_INCR_REF(inp);
7652 		stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
7653 		if (stcb != NULL) {
7654 			SCTP_TCB_UNLOCK(stcb);
7655 			return (EALREADY);
7656 		} else {
7657 			SCTP_INP_DECR_REF(inp);
7658 		}
7659 		at += incr;
7660 		sa = (struct sockaddr *)((caddr_t)sa + incr);
7661 	}
7662 	return (0);
7663 }
7664 
7665 /*
7666  * sctp_bindx(ADD) for one address.
7667  * assumes all arguments are valid/checked by caller.
7668  */
7669 void
7670 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
7671 		       struct sockaddr *sa, sctp_assoc_t assoc_id,
7672 		       uint32_t vrf_id, int *error, void *p)
7673 {
7674 	struct sockaddr *addr_touse;
7675 #if defined(INET) && defined(INET6)
7676 	struct sockaddr_in sin;
7677 #endif
7678 #ifdef SCTP_MVRF
7679 	int i, fnd = 0;
7680 #endif
7681 
7682 	/* see if we're bound all already! */
7683 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7684 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7685 		*error = EINVAL;
7686 		return;
7687 	}
7688 #ifdef SCTP_MVRF
7689 	/* Is the VRF one we have */
7690 	for (i = 0; i < inp->num_vrfs; i++) {
7691 		if (vrf_id == inp->m_vrf_ids[i]) {
7692 			fnd = 1;
7693 			break;
7694 		}
7695 	}
7696 	if (!fnd) {
7697 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7698 		*error = EINVAL;
7699 		return;
7700 	}
7701 #endif
7702 	addr_touse = sa;
7703 #ifdef INET6
7704 	if (sa->sa_family == AF_INET6) {
7705 #ifdef INET
7706 		struct sockaddr_in6 *sin6;
7707 
7708 #endif
7709 #ifdef HAVE_SA_LEN
7710 		if (sa->sa_len != sizeof(struct sockaddr_in6)) {
7711 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7712 			*error = EINVAL;
7713 			return;
7714 		}
7715 #endif
7716 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
7717 			/* can only bind v6 on PF_INET6 sockets */
7718 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7719 			*error = EINVAL;
7720 			return;
7721 		}
7722 #ifdef INET
7723 		sin6 = (struct sockaddr_in6 *)addr_touse;
7724 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7725 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7726 			    SCTP_IPV6_V6ONLY(inp)) {
7727 				/* can't bind v4-mapped on PF_INET sockets */
7728 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7729 				*error = EINVAL;
7730 				return;
7731 			}
7732 			in6_sin6_2_sin(&sin, sin6);
7733 			addr_touse = (struct sockaddr *)&sin;
7734 		}
7735 #endif
7736 	}
7737 #endif
7738 #ifdef INET
7739 	if (sa->sa_family == AF_INET) {
7740 #ifdef HAVE_SA_LEN
7741 		if (sa->sa_len != sizeof(struct sockaddr_in)) {
7742 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7743 			*error = EINVAL;
7744 			return;
7745 		}
7746 #endif
7747 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7748 		    SCTP_IPV6_V6ONLY(inp)) {
7749 			/* can't bind v4 on PF_INET sockets */
7750 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7751 			*error = EINVAL;
7752 			return;
7753 		}
7754 	}
7755 #endif
7756 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
7757 #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
7758 		if (p == NULL) {
7759 			/* Can't get proc for Net/Open BSD */
7760 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7761 			*error = EINVAL;
7762 			return;
7763 		}
7764 #endif
7765 		*error = sctp_inpcb_bind(so, addr_touse, NULL, p);
7766 		return;
7767 	}
7768 	/*
7769 	 * No locks required here since bind and mgmt_ep_sa
7770 	 * all do their own locking. If we do something for
7771 	 * the FIX: below we may need to lock in that case.
7772 	 */
7773 	if (assoc_id == 0) {
7774 		/* add the address */
7775 		struct sctp_inpcb *lep;
7776 		struct sockaddr_in *lsin = (struct sockaddr_in *)addr_touse;
7777 
7778 		/* validate the incoming port */
7779 		if ((lsin->sin_port != 0) &&
7780 		    (lsin->sin_port != inp->sctp_lport)) {
7781 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7782 			*error = EINVAL;
7783 			return;
7784 		} else {
7785 			/* user specified 0 port, set it to existing port */
7786 			lsin->sin_port = inp->sctp_lport;
7787 		}
7788 
7789 		lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id);
7790 		if (lep != NULL) {
7791 			/*
7792 			 * We must decrement the refcount
7793 			 * since we have the ep already and
7794 			 * are binding. No remove going on
7795 			 * here.
7796 			 */
7797 			SCTP_INP_DECR_REF(lep);
7798 		}
7799 		if (lep == inp) {
7800 			/* already bound to it.. ok */
7801 			return;
7802 		} else if (lep == NULL) {
7803 			((struct sockaddr_in *)addr_touse)->sin_port = 0;
7804 			*error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
7805 						      SCTP_ADD_IP_ADDRESS,
7806 						      vrf_id, NULL);
7807 		} else {
7808 			*error = EADDRINUSE;
7809 		}
7810 		if (*error)
7811 			return;
7812 	} else {
7813 		/*
7814 		 * FIX: decide whether we allow assoc based
7815 		 * bindx
7816 		 */
7817 	}
7818 }
7819 
7820 /*
7821  * sctp_bindx(DELETE) for one address.
7822  * assumes all arguments are valid/checked by caller.
7823  */
7824 void
7825 sctp_bindx_delete_address(struct sctp_inpcb *inp,
7826 			  struct sockaddr *sa, sctp_assoc_t assoc_id,
7827 			  uint32_t vrf_id, int *error)
7828 {
7829 	struct sockaddr *addr_touse;
7830 #if defined(INET) && defined(INET6)
7831 	struct sockaddr_in sin;
7832 #endif
7833 #ifdef SCTP_MVRF
7834 	int i, fnd = 0;
7835 #endif
7836 
7837 	/* see if we're bound all already! */
7838 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7839 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7840 		*error = EINVAL;
7841 		return;
7842 	}
7843 #ifdef SCTP_MVRF
7844 	/* Is the VRF one we have */
7845 	for (i = 0; i < inp->num_vrfs; i++) {
7846 		if (vrf_id == inp->m_vrf_ids[i]) {
7847 			fnd = 1;
7848 			break;
7849 		}
7850 	}
7851 	if (!fnd) {
7852 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7853 		*error = EINVAL;
7854 		return;
7855 	}
7856 #endif
7857 	addr_touse = sa;
7858 #ifdef INET6
7859 	if (sa->sa_family == AF_INET6) {
7860 #ifdef INET
7861 		struct sockaddr_in6 *sin6;
7862 #endif
7863 
7864 #ifdef HAVE_SA_LEN
7865 		if (sa->sa_len != sizeof(struct sockaddr_in6)) {
7866 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7867 			*error = EINVAL;
7868 			return;
7869 		}
7870 #endif
7871 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
7872 			/* can only bind v6 on PF_INET6 sockets */
7873 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7874 			*error = EINVAL;
7875 			return;
7876 		}
7877 #ifdef INET
7878 		sin6 = (struct sockaddr_in6 *)addr_touse;
7879 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7880 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7881 			    SCTP_IPV6_V6ONLY(inp)) {
7882 				/* can't bind mapped-v4 on PF_INET sockets */
7883 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7884 				*error = EINVAL;
7885 				return;
7886 			}
7887 			in6_sin6_2_sin(&sin, sin6);
7888 			addr_touse = (struct sockaddr *)&sin;
7889 		}
7890 #endif
7891 	}
7892 #endif
7893 #ifdef INET
7894 	if (sa->sa_family == AF_INET) {
7895 #ifdef HAVE_SA_LEN
7896 		if (sa->sa_len != sizeof(struct sockaddr_in)) {
7897 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7898 			*error = EINVAL;
7899 			return;
7900 		}
7901 #endif
7902 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7903 		    SCTP_IPV6_V6ONLY(inp)) {
7904 			/* can't bind v4 on PF_INET sockets */
7905 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7906 			*error = EINVAL;
7907 			return;
7908 		}
7909 	}
7910 #endif
7911 	/*
7912 	 * No lock required mgmt_ep_sa does its own locking.
7913 	 * If the FIX: below is ever changed we may need to
7914 	 * lock before calling association level binding.
7915 	 */
7916 	if (assoc_id == 0) {
7917 		/* delete the address */
7918 		*error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
7919 					      SCTP_DEL_IP_ADDRESS,
7920 					      vrf_id, NULL);
7921 	} else {
7922 		/*
7923 		 * FIX: decide whether we allow assoc based
7924 		 * bindx
7925 		 */
7926 	}
7927 }
7928 
7929 /*
7930  * returns the valid local address count for an assoc, taking into account
7931  * all scoping rules
7932  */
7933 int
7934 sctp_local_addr_count(struct sctp_tcb *stcb)
7935 {
7936 	int loopback_scope;
7937 #if defined(INET)
7938 	int ipv4_local_scope, ipv4_addr_legal;
7939 #endif
7940 #if defined (INET6)
7941 	int local_scope, site_scope, ipv6_addr_legal;
7942 #endif
7943 #if defined(__Userspace__)
7944 	int conn_addr_legal;
7945 #endif
7946 	struct sctp_vrf *vrf;
7947 	struct sctp_ifn *sctp_ifn;
7948 	struct sctp_ifa *sctp_ifa;
7949 	int count = 0;
7950 
7951 	/* Turn on all the appropriate scopes */
7952 	loopback_scope = stcb->asoc.scope.loopback_scope;
7953 #if defined(INET)
7954 	ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
7955 	ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
7956 #endif
7957 #if defined(INET6)
7958 	local_scope = stcb->asoc.scope.local_scope;
7959 	site_scope = stcb->asoc.scope.site_scope;
7960 	ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
7961 #endif
7962 #if defined(__Userspace__)
7963 	conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
7964 #endif
7965 	SCTP_IPI_ADDR_RLOCK();
7966 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
7967 	if (vrf == NULL) {
7968 		/* no vrf, no addresses */
7969 		SCTP_IPI_ADDR_RUNLOCK();
7970 		return (0);
7971 	}
7972 
7973 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7974 		/*
7975 		 * bound all case: go through all ifns on the vrf
7976 		 */
7977 		LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
7978 			if ((loopback_scope == 0) &&
7979 			    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
7980 				continue;
7981 			}
7982 			LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
7983 				if (sctp_is_addr_restricted(stcb, sctp_ifa))
7984 					continue;
7985 				switch (sctp_ifa->address.sa.sa_family) {
7986 #ifdef INET
7987 				case AF_INET:
7988 					if (ipv4_addr_legal) {
7989 						struct sockaddr_in *sin;
7990 
7991 						sin = &sctp_ifa->address.sin;
7992 						if (sin->sin_addr.s_addr == 0) {
7993 							/* skip unspecified addrs */
7994 							continue;
7995 						}
7996 #if defined(__FreeBSD__)
7997 						if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
7998 						                     &sin->sin_addr) != 0) {
7999 							continue;
8000 						}
8001 #endif
8002 						if ((ipv4_local_scope == 0) &&
8003 						    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
8004 							continue;
8005 						}
8006 						/* count this one */
8007 						count++;
8008 					} else {
8009 						continue;
8010 					}
8011 					break;
8012 #endif
8013 #ifdef INET6
8014 				case AF_INET6:
8015 					if (ipv6_addr_legal) {
8016 						struct sockaddr_in6 *sin6;
8017 
8018 #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
8019 						struct sockaddr_in6 lsa6;
8020 #endif
8021 						sin6 = &sctp_ifa->address.sin6;
8022 						if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
8023 							continue;
8024 						}
8025 #if defined(__FreeBSD__)
8026 						if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
8027 						                     &sin6->sin6_addr) != 0) {
8028 							continue;
8029 						}
8030 #endif
8031 						if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
8032 							if (local_scope == 0)
8033 								continue;
8034 #if defined(SCTP_EMBEDDED_V6_SCOPE)
8035 							if (sin6->sin6_scope_id == 0) {
8036 #ifdef SCTP_KAME
8037 								if (sa6_recoverscope(sin6) != 0)
8038 									/*
8039 									 * bad link
8040 									 * local
8041 									 * address
8042 									 */
8043 									continue;
8044 #else
8045 								lsa6 = *sin6;
8046 								if (in6_recoverscope(&lsa6,
8047 								                     &lsa6.sin6_addr,
8048 								                     NULL))
8049 									/*
8050 									 * bad link
8051 									 * local
8052 									 * address
8053 									 */
8054 									continue;
8055 								sin6 = &lsa6;
8056 #endif /* SCTP_KAME */
8057 							}
8058 #endif /* SCTP_EMBEDDED_V6_SCOPE */
8059 						}
8060 						if ((site_scope == 0) &&
8061 						    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
8062 							continue;
8063 						}
8064 						/* count this one */
8065 						count++;
8066 					}
8067 					break;
8068 #endif
8069 #if defined(__Userspace__)
8070 				case AF_CONN:
8071 					if (conn_addr_legal) {
8072 						count++;
8073 					}
8074 					break;
8075 #endif
8076 				default:
8077 					/* TSNH */
8078 					break;
8079 				}
8080 			}
8081 		}
8082 	} else {
8083 		/*
8084 		 * subset bound case
8085 		 */
8086 		struct sctp_laddr *laddr;
8087 		LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list,
8088 			     sctp_nxt_addr) {
8089 			if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
8090 				continue;
8091 			}
8092 			/* count this one */
8093 			count++;
8094 		}
8095 	}
8096 	SCTP_IPI_ADDR_RUNLOCK();
8097 	return (count);
8098 }
8099 
8100 #if defined(SCTP_LOCAL_TRACE_BUF)
8101 
8102 void
8103 sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f)
8104 {
8105 	uint32_t saveindex, newindex;
8106 
8107 #if defined(__Windows__)
8108 	if (SCTP_BASE_SYSCTL(sctp_log) == NULL) {
8109 		return;
8110 	}
8111 	do {
8112 		saveindex = SCTP_BASE_SYSCTL(sctp_log)->index;
8113 		if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8114 			newindex = 1;
8115 		} else {
8116 			newindex = saveindex + 1;
8117 		}
8118 	} while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log)->index, saveindex, newindex) == 0);
8119 	if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8120 		saveindex = 0;
8121 	}
8122 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
8123 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].subsys = subsys;
8124 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[0] = a;
8125 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[1] = b;
8126 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[2] = c;
8127 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[3] = d;
8128 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[4] = e;
8129 	SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[5] = f;
8130 #else
8131 	do {
8132 		saveindex = SCTP_BASE_SYSCTL(sctp_log).index;
8133 		if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8134 			newindex = 1;
8135 		} else {
8136 			newindex = saveindex + 1;
8137 		}
8138 	} while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log).index, saveindex, newindex) == 0);
8139 	if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8140 		saveindex = 0;
8141 	}
8142 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
8143 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].subsys = subsys;
8144 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[0] = a;
8145 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[1] = b;
8146 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[2] = c;
8147 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[3] = d;
8148 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[4] = e;
8149 	SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[5] = f;
8150 #endif
8151 }
8152 
8153 #endif
8154 #if defined(__FreeBSD__)
8155 #if __FreeBSD_version >= 800044
8156 static void
8157 sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
8158     const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED)
8159 {
8160 	struct ip *iph;
8161 #ifdef INET6
8162 	struct ip6_hdr *ip6;
8163 #endif
8164 	struct mbuf *sp, *last;
8165 	struct udphdr *uhdr;
8166 	uint16_t port;
8167 
8168 	if ((m->m_flags & M_PKTHDR) == 0) {
8169 		/* Can't handle one that is not a pkt hdr */
8170 		goto out;
8171 	}
8172 	/* Pull the src port */
8173 	iph = mtod(m, struct ip *);
8174 	uhdr = (struct udphdr *)((caddr_t)iph + off);
8175 	port = uhdr->uh_sport;
8176 	/* Split out the mbuf chain. Leave the
8177 	 * IP header in m, place the
8178 	 * rest in the sp.
8179 	 */
8180 	sp = m_split(m, off, M_NOWAIT);
8181 	if (sp == NULL) {
8182 		/* Gak, drop packet, we can't do a split */
8183 		goto out;
8184 	}
8185 	if (sp->m_pkthdr.len < sizeof(struct udphdr) + sizeof(struct sctphdr)) {
8186 		/* Gak, packet can't have an SCTP header in it - too small */
8187 		m_freem(sp);
8188 		goto out;
8189 	}
8190 	/* Now pull up the UDP header and SCTP header together */
8191 	sp = m_pullup(sp, sizeof(struct udphdr) + sizeof(struct sctphdr));
8192 	if (sp == NULL) {
8193 		/* Gak pullup failed */
8194 		goto out;
8195 	}
8196 	/* Trim out the UDP header */
8197 	m_adj(sp, sizeof(struct udphdr));
8198 
8199 	/* Now reconstruct the mbuf chain */
8200 	for (last = m; last->m_next; last = last->m_next);
8201 	last->m_next = sp;
8202 	m->m_pkthdr.len += sp->m_pkthdr.len;
8203 	/*
8204 	 * The CSUM_DATA_VALID flags indicates that the HW checked the
8205 	 * UDP checksum and it was valid.
8206 	 * Since CSUM_DATA_VALID == CSUM_SCTP_VALID this would imply that
8207 	 * the HW also verified the SCTP checksum. Therefore, clear the bit.
8208 	 */
8209 #if __FreeBSD_version > 1000049
8210 	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
8211 	        "sctp_recv_udp_tunneled_packet(): Packet of length %d received on %s with csum_flags 0x%b.\n",
8212 	        m->m_pkthdr.len,
8213 	        if_name(m->m_pkthdr.rcvif),
8214 	        (int)m->m_pkthdr.csum_flags, CSUM_BITS);
8215 #else
8216 	SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
8217 	        "sctp_recv_udp_tunneled_packet(): Packet of length %d received on %s with csum_flags 0x%x.\n",
8218 	        m->m_pkthdr.len,
8219 	        if_name(m->m_pkthdr.rcvif),
8220 	        m->m_pkthdr.csum_flags);
8221 #endif
8222 	m->m_pkthdr.csum_flags &= ~CSUM_DATA_VALID;
8223 	iph = mtod(m, struct ip *);
8224 	switch (iph->ip_v) {
8225 #ifdef INET
8226 	case IPVERSION:
8227 #if __FreeBSD_version >= 1000000
8228 		iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr));
8229 #else
8230 		iph->ip_len -= sizeof(struct udphdr);
8231 #endif
8232 		sctp_input_with_port(m, off, port);
8233 		break;
8234 #endif
8235 #ifdef INET6
8236 	case IPV6_VERSION >> 4:
8237 		ip6 = mtod(m, struct ip6_hdr *);
8238 		ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr));
8239 		sctp6_input_with_port(&m, &off, port);
8240 		break;
8241 #endif
8242 	default:
8243 		goto out;
8244 		break;
8245 	}
8246 	return;
8247  out:
8248 	m_freem(m);
8249 }
8250 #endif
8251 
8252 #if __FreeBSD_version >= 1100000
8253 #ifdef INET
8254 static void
8255 sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ctx SCTP_UNUSED)
8256 {
8257 	struct ip *outer_ip, *inner_ip;
8258 	struct sctphdr *sh;
8259 	struct icmp *icmp;
8260 	struct udphdr *udp;
8261 	struct sctp_inpcb *inp;
8262 	struct sctp_tcb *stcb;
8263 	struct sctp_nets *net;
8264 	struct sctp_init_chunk *ch;
8265 	struct sockaddr_in src, dst;
8266 	uint8_t type, code;
8267 
8268 	inner_ip = (struct ip *)vip;
8269 	icmp = (struct icmp *)((caddr_t)inner_ip -
8270 	    (sizeof(struct icmp) - sizeof(struct ip)));
8271 	outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
8272 	if (ntohs(outer_ip->ip_len) <
8273 	    sizeof(struct ip) + 8 + (inner_ip->ip_hl << 2) + sizeof(struct udphdr) + 8) {
8274 		return;
8275 	}
8276 	udp = (struct udphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
8277 	sh = (struct sctphdr *)(udp + 1);
8278 	memset(&src, 0, sizeof(struct sockaddr_in));
8279 	src.sin_family = AF_INET;
8280 #ifdef HAVE_SIN_LEN
8281 	src.sin_len = sizeof(struct sockaddr_in);
8282 #endif
8283 	src.sin_port = sh->src_port;
8284 	src.sin_addr = inner_ip->ip_src;
8285 	memset(&dst, 0, sizeof(struct sockaddr_in));
8286 	dst.sin_family = AF_INET;
8287 #ifdef HAVE_SIN_LEN
8288 	dst.sin_len = sizeof(struct sockaddr_in);
8289 #endif
8290 	dst.sin_port = sh->dest_port;
8291 	dst.sin_addr = inner_ip->ip_dst;
8292 	/*
8293 	 * 'dst' holds the dest of the packet that failed to be sent.
8294 	 * 'src' holds our local endpoint address. Thus we reverse
8295 	 * the dst and the src in the lookup.
8296 	 */
8297 	inp = NULL;
8298 	net = NULL;
8299 	stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
8300 	                                    (struct sockaddr *)&src,
8301 	                                    &inp, &net, 1,
8302 	                                    SCTP_DEFAULT_VRFID);
8303 	if ((stcb != NULL) &&
8304 	    (net != NULL) &&
8305 	    (inp != NULL)) {
8306 		/* Check the UDP port numbers */
8307 		if ((udp->uh_dport != net->port) ||
8308 		    (udp->uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) {
8309 			SCTP_TCB_UNLOCK(stcb);
8310 			return;
8311 		}
8312 		/* Check the verification tag */
8313 		if (ntohl(sh->v_tag) != 0) {
8314 			/*
8315 			 * This must be the verification tag used
8316 			 * for sending out packets. We don't
8317 			 * consider packets reflecting the
8318 			 * verification tag.
8319 			 */
8320 			if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
8321 				SCTP_TCB_UNLOCK(stcb);
8322 				return;
8323 			}
8324 		} else {
8325 			if (ntohs(outer_ip->ip_len) >=
8326 			    sizeof(struct ip) +
8327 			    8 + (inner_ip->ip_hl << 2) + 8 + 20) {
8328 				/*
8329 				 * In this case we can check if we
8330 				 * got an INIT chunk and if the
8331 				 * initiate tag matches.
8332 				 */
8333 				ch = (struct sctp_init_chunk *)(sh + 1);
8334 				if ((ch->ch.chunk_type != SCTP_INITIATION) ||
8335 				    (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
8336 					SCTP_TCB_UNLOCK(stcb);
8337 					return;
8338 				}
8339 			} else {
8340 				SCTP_TCB_UNLOCK(stcb);
8341 				return;
8342 			}
8343 		}
8344 		type = icmp->icmp_type;
8345 		code = icmp->icmp_code;
8346 		if ((type == ICMP_UNREACH) &&
8347 		    (code == ICMP_UNREACH_PORT)) {
8348 			code = ICMP_UNREACH_PROTOCOL;
8349 		}
8350 		sctp_notify(inp, stcb, net, type, code,
8351 		            ntohs(inner_ip->ip_len),
8352 		            (uint32_t)ntohs(icmp->icmp_nextmtu));
8353 #if defined(__Userspace__)
8354 		if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
8355 		    (stcb->sctp_socket != NULL)) {
8356 			struct socket *upcall_socket;
8357 
8358 			upcall_socket = stcb->sctp_socket;
8359 			SOCK_LOCK(upcall_socket);
8360 			soref(upcall_socket);
8361 			SOCK_UNLOCK(upcall_socket);
8362 			if ((upcall_socket->so_upcall != NULL) &&
8363 			    (upcall_socket->so_error != 0)) {
8364 				(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
8365 			}
8366 			ACCEPT_LOCK();
8367 			SOCK_LOCK(upcall_socket);
8368 			sorele(upcall_socket);
8369 		}
8370 #endif
8371 	} else {
8372 #if defined(__FreeBSD__) && __FreeBSD_version < 500000
8373 		/*
8374 		 * XXX must be fixed for 5.x and higher, leave for
8375 		 * 4.x
8376 		 */
8377 		if (PRC_IS_REDIRECT(cmd) && (inp != NULL)) {
8378 			in_rtchange((struct inpcb *)inp,
8379 			    inetctlerrmap[cmd]);
8380 		}
8381 #endif
8382 		if ((stcb == NULL) && (inp != NULL)) {
8383 			/* reduce ref-count */
8384 			SCTP_INP_WLOCK(inp);
8385 			SCTP_INP_DECR_REF(inp);
8386 			SCTP_INP_WUNLOCK(inp);
8387 		}
8388 		if (stcb) {
8389 			SCTP_TCB_UNLOCK(stcb);
8390 		}
8391 	}
8392 	return;
8393 }
8394 #endif
8395 
8396 #ifdef INET6
8397 static void
8398 sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx SCTP_UNUSED)
8399 {
8400 	struct ip6ctlparam *ip6cp;
8401 	struct sctp_inpcb *inp;
8402 	struct sctp_tcb *stcb;
8403 	struct sctp_nets *net;
8404 	struct sctphdr sh;
8405 	struct udphdr udp;
8406 	struct sockaddr_in6 src, dst;
8407 	uint8_t type, code;
8408 
8409 	ip6cp = (struct ip6ctlparam *)d;
8410 	/*
8411 	 * XXX: We assume that when IPV6 is non NULL, M and OFF are
8412 	 * valid.
8413 	 */
8414 	if (ip6cp->ip6c_m == NULL) {
8415 		return;
8416 	}
8417 	/* Check if we can safely examine the ports and the
8418 	 * verification tag of the SCTP common header.
8419 	 */
8420 	if (ip6cp->ip6c_m->m_pkthdr.len <
8421 	    ip6cp->ip6c_off + sizeof(struct udphdr)+ offsetof(struct sctphdr, checksum)) {
8422 		return;
8423 	}
8424 	/* Copy out the UDP header. */
8425 	memset(&udp, 0, sizeof(struct udphdr));
8426 	m_copydata(ip6cp->ip6c_m,
8427 		   ip6cp->ip6c_off,
8428 		   sizeof(struct udphdr),
8429 		   (caddr_t)&udp);
8430 	/* Copy out the port numbers and the verification tag. */
8431 	memset(&sh, 0, sizeof(struct sctphdr));
8432 	m_copydata(ip6cp->ip6c_m,
8433 		   ip6cp->ip6c_off + sizeof(struct udphdr),
8434 		   sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
8435 		   (caddr_t)&sh);
8436 	memset(&src, 0, sizeof(struct sockaddr_in6));
8437 	src.sin6_family = AF_INET6;
8438 #ifdef HAVE_SIN6_LEN
8439 	src.sin6_len = sizeof(struct sockaddr_in6);
8440 #endif
8441 	src.sin6_port = sh.src_port;
8442 	src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
8443 #if defined(__FreeBSD__)
8444 	if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
8445 		return;
8446 	}
8447 #endif
8448 	memset(&dst, 0, sizeof(struct sockaddr_in6));
8449 	dst.sin6_family = AF_INET6;
8450 #ifdef HAVE_SIN6_LEN
8451 	dst.sin6_len = sizeof(struct sockaddr_in6);
8452 #endif
8453 	dst.sin6_port = sh.dest_port;
8454 	dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
8455 #if defined(__FreeBSD__)
8456 	if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
8457 		return;
8458 	}
8459 #endif
8460 	inp = NULL;
8461 	net = NULL;
8462 	stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
8463 	                                    (struct sockaddr *)&src,
8464 	                                    &inp, &net, 1, SCTP_DEFAULT_VRFID);
8465 	if ((stcb != NULL) &&
8466 	    (net != NULL) &&
8467 	    (inp != NULL)) {
8468 		/* Check the UDP port numbers */
8469 		if ((udp.uh_dport != net->port) ||
8470 		    (udp.uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) {
8471 			SCTP_TCB_UNLOCK(stcb);
8472 			return;
8473 		}
8474 		/* Check the verification tag */
8475 		if (ntohl(sh.v_tag) != 0) {
8476 			/*
8477 			 * This must be the verification tag used for
8478 			 * sending out packets. We don't consider
8479 			 * packets reflecting the verification tag.
8480 			 */
8481 			if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
8482 				SCTP_TCB_UNLOCK(stcb);
8483 				return;
8484 			}
8485 		} else {
8486 #if defined(__FreeBSD__)
8487 			if (ip6cp->ip6c_m->m_pkthdr.len >=
8488 			    ip6cp->ip6c_off + sizeof(struct udphdr) +
8489 			                      sizeof(struct sctphdr) +
8490 			                      sizeof(struct sctp_chunkhdr) +
8491 			                      offsetof(struct sctp_init, a_rwnd)) {
8492 				/*
8493 				 * In this case we can check if we
8494 				 * got an INIT chunk and if the
8495 				 * initiate tag matches.
8496 				 */
8497 				uint32_t initiate_tag;
8498 				uint8_t chunk_type;
8499 
8500 				m_copydata(ip6cp->ip6c_m,
8501 					   ip6cp->ip6c_off +
8502 					   sizeof(struct udphdr) +
8503 					   sizeof(struct sctphdr),
8504 					   sizeof(uint8_t),
8505 					   (caddr_t)&chunk_type);
8506 				m_copydata(ip6cp->ip6c_m,
8507 					   ip6cp->ip6c_off +
8508 					   sizeof(struct udphdr) +
8509 					   sizeof(struct sctphdr) +
8510 					   sizeof(struct sctp_chunkhdr),
8511 					   sizeof(uint32_t),
8512 					   (caddr_t)&initiate_tag);
8513 				if ((chunk_type != SCTP_INITIATION) ||
8514 				    (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
8515 					SCTP_TCB_UNLOCK(stcb);
8516 					return;
8517 				}
8518 			} else {
8519 				SCTP_TCB_UNLOCK(stcb);
8520 				return;
8521 			}
8522 #else
8523 			SCTP_TCB_UNLOCK(stcb);
8524 			return;
8525 #endif
8526 		}
8527 		type = ip6cp->ip6c_icmp6->icmp6_type;
8528 		code = ip6cp->ip6c_icmp6->icmp6_code;
8529 		if ((type == ICMP6_DST_UNREACH) &&
8530 		    (code == ICMP6_DST_UNREACH_NOPORT)) {
8531 			type = ICMP6_PARAM_PROB;
8532 			code = ICMP6_PARAMPROB_NEXTHEADER;
8533 		}
8534 		sctp6_notify(inp, stcb, net, type, code,
8535 			     ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
8536 #if defined(__Userspace__)
8537 		if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
8538 		    (stcb->sctp_socket != NULL)) {
8539 			struct socket *upcall_socket;
8540 
8541 			upcall_socket = stcb->sctp_socket;
8542 			SOCK_LOCK(upcall_socket);
8543 			soref(upcall_socket);
8544 			SOCK_UNLOCK(upcall_socket);
8545 			if ((upcall_socket->so_upcall != NULL) &&
8546 			    (upcall_socket->so_error != 0)) {
8547 				(*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
8548 			}
8549 			ACCEPT_LOCK();
8550 			SOCK_LOCK(upcall_socket);
8551 			sorele(upcall_socket);
8552 		}
8553 #endif
8554 	} else {
8555 #if defined(__FreeBSD__) && __FreeBSD_version < 500000
8556 		if (PRC_IS_REDIRECT(cmd) && (inp != NULL)) {
8557 			in6_rtchange(inp, inet6ctlerrmap[cmd]);
8558 		}
8559 #endif
8560 		if ((stcb == NULL) && (inp != NULL)) {
8561 			/* reduce inp's ref-count */
8562 			SCTP_INP_WLOCK(inp);
8563 			SCTP_INP_DECR_REF(inp);
8564 			SCTP_INP_WUNLOCK(inp);
8565 		}
8566 		if (stcb) {
8567 			SCTP_TCB_UNLOCK(stcb);
8568 		}
8569 	}
8570 }
8571 #endif
8572 #endif
8573 
8574 void
8575 sctp_over_udp_stop(void)
8576 {
8577 	/*
8578 	 * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting!
8579 	 */
8580 #ifdef INET
8581 	if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) {
8582 		soclose(SCTP_BASE_INFO(udp4_tun_socket));
8583 		SCTP_BASE_INFO(udp4_tun_socket) = NULL;
8584 	}
8585 #endif
8586 #ifdef INET6
8587 	if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) {
8588 		soclose(SCTP_BASE_INFO(udp6_tun_socket));
8589 		SCTP_BASE_INFO(udp6_tun_socket) = NULL;
8590 	}
8591 #endif
8592 }
8593 
8594 int
8595 sctp_over_udp_start(void)
8596 {
8597 #if __FreeBSD_version >= 800044
8598 	uint16_t port;
8599 	int ret;
8600 #ifdef INET
8601 	struct sockaddr_in sin;
8602 #endif
8603 #ifdef INET6
8604 	struct sockaddr_in6 sin6;
8605 #endif
8606 	/*
8607 	 * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting!
8608 	 */
8609 	port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
8610 	if (ntohs(port) == 0) {
8611 		/* Must have a port set */
8612 		return (EINVAL);
8613 	}
8614 #ifdef INET
8615 	if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) {
8616 		/* Already running -- must stop first */
8617 		return (EALREADY);
8618 	}
8619 #endif
8620 #ifdef INET6
8621 	if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) {
8622 		/* Already running -- must stop first */
8623 		return (EALREADY);
8624 	}
8625 #endif
8626 #ifdef INET
8627 	if ((ret = socreate(PF_INET, &SCTP_BASE_INFO(udp4_tun_socket),
8628 	                    SOCK_DGRAM, IPPROTO_UDP,
8629 	                    curthread->td_ucred, curthread))) {
8630 		sctp_over_udp_stop();
8631 		return (ret);
8632 	}
8633 	/* Call the special UDP hook. */
8634 	if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket),
8635 	                                    sctp_recv_udp_tunneled_packet,
8636 #if __FreeBSD_version >= 1100000
8637 	                                    sctp_recv_icmp_tunneled_packet,
8638 #endif
8639 	                                    NULL))) {
8640 		sctp_over_udp_stop();
8641 		return (ret);
8642 	}
8643 	/* Ok, we have a socket, bind it to the port. */
8644 	memset(&sin, 0, sizeof(struct sockaddr_in));
8645 	sin.sin_len = sizeof(struct sockaddr_in);
8646 	sin.sin_family = AF_INET;
8647 	sin.sin_port = htons(port);
8648 	if ((ret = sobind(SCTP_BASE_INFO(udp4_tun_socket),
8649 	                  (struct sockaddr *)&sin, curthread))) {
8650 		sctp_over_udp_stop();
8651 		return (ret);
8652 	}
8653 #endif
8654 #ifdef INET6
8655 	if ((ret = socreate(PF_INET6, &SCTP_BASE_INFO(udp6_tun_socket),
8656 	                    SOCK_DGRAM, IPPROTO_UDP,
8657 	                    curthread->td_ucred, curthread))) {
8658 		sctp_over_udp_stop();
8659 		return (ret);
8660 	}
8661 	/* Call the special UDP hook. */
8662 	if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket),
8663 	                                    sctp_recv_udp_tunneled_packet,
8664 #if __FreeBSD_version >= 1100000
8665 	                                    sctp_recv_icmp6_tunneled_packet,
8666 #endif
8667 	                                    NULL))) {
8668 		sctp_over_udp_stop();
8669 		return (ret);
8670 	}
8671 	/* Ok, we have a socket, bind it to the port. */
8672 	memset(&sin6, 0, sizeof(struct sockaddr_in6));
8673 	sin6.sin6_len = sizeof(struct sockaddr_in6);
8674 	sin6.sin6_family = AF_INET6;
8675 	sin6.sin6_port = htons(port);
8676 	if ((ret = sobind(SCTP_BASE_INFO(udp6_tun_socket),
8677 	                  (struct sockaddr *)&sin6, curthread))) {
8678 		sctp_over_udp_stop();
8679 		return (ret);
8680 	}
8681 #endif
8682 	return (0);
8683 #else
8684 	return (ENOTSUP);
8685 #endif
8686 }
8687 #endif
8688 
8689 /*
8690  * sctp_min_mtu ()returns the minimum of all non-zero arguments.
8691  * If all arguments are zero, zero is returned.
8692  */
8693 uint32_t
8694 sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3)
8695 {
8696 	if (mtu1 > 0) {
8697 		if (mtu2 > 0) {
8698 			if (mtu3 > 0) {
8699 				return (min(mtu1, min(mtu2, mtu3)));
8700 			} else {
8701 				return (min(mtu1, mtu2));
8702 			}
8703 		} else {
8704 			if (mtu3 > 0) {
8705 				return (min(mtu1, mtu3));
8706 			} else {
8707 				return (mtu1);
8708 			}
8709 		}
8710 	} else {
8711 		if (mtu2 > 0) {
8712 			if (mtu3 > 0) {
8713 				return (min(mtu2, mtu3));
8714 			} else {
8715 				return (mtu2);
8716 			}
8717 		} else {
8718 			return (mtu3);
8719 		}
8720 	}
8721 }
8722 
8723 #if defined(__FreeBSD__)
8724 void
8725 sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu)
8726 {
8727 	struct in_conninfo inc;
8728 
8729 	memset(&inc, 0, sizeof(struct in_conninfo));
8730 	inc.inc_fibnum = fibnum;
8731 	switch (addr->sa.sa_family) {
8732 #ifdef INET
8733 	case AF_INET:
8734 		inc.inc_faddr = addr->sin.sin_addr;
8735 		break;
8736 #endif
8737 #ifdef INET6
8738 	case AF_INET6:
8739 		inc.inc_flags |= INC_ISIPV6;
8740 		inc.inc6_faddr = addr->sin6.sin6_addr;
8741 		break;
8742 #endif
8743 	default:
8744 		return;
8745 	}
8746 	tcp_hc_updatemtu(&inc, (u_long)mtu);
8747 }
8748 
8749 uint32_t
8750 sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum)
8751 {
8752 	struct in_conninfo inc;
8753 
8754 	memset(&inc, 0, sizeof(struct in_conninfo));
8755 	inc.inc_fibnum = fibnum;
8756 	switch (addr->sa.sa_family) {
8757 #ifdef INET
8758 	case AF_INET:
8759 		inc.inc_faddr = addr->sin.sin_addr;
8760 		break;
8761 #endif
8762 #ifdef INET6
8763 	case AF_INET6:
8764 		inc.inc_flags |= INC_ISIPV6;
8765 		inc.inc6_faddr = addr->sin6.sin6_addr;
8766 		break;
8767 #endif
8768 	default:
8769 		return (0);
8770 	}
8771 	return ((uint32_t)tcp_hc_getmtu(&inc));
8772 }
8773 #endif
8774 
8775 void
8776 sctp_set_state(struct sctp_tcb *stcb, int new_state)
8777 {
8778 #if defined(KDTRACE_HOOKS)
8779 	int old_state = stcb->asoc.state;
8780 #endif
8781 
8782 	KASSERT((new_state & ~SCTP_STATE_MASK) == 0,
8783 	        ("sctp_set_state: Can't set substate (new_state = %x)",
8784 	        new_state));
8785 	stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state;
8786 	if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) ||
8787 	    (new_state == SCTP_STATE_SHUTDOWN_SENT) ||
8788 	    (new_state == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
8789 		SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
8790 	}
8791 #if defined(KDTRACE_HOOKS)
8792 	if (((old_state & SCTP_STATE_MASK) != new_state) &&
8793 	    !(((old_state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY) &&
8794 	      (new_state == SCTP_STATE_INUSE))) {
8795 		SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
8796 	}
8797 #endif
8798 }
8799 
8800 void
8801 sctp_add_substate(struct sctp_tcb *stcb, int substate)
8802 {
8803 #if defined(KDTRACE_HOOKS)
8804 	int old_state = stcb->asoc.state;
8805 #endif
8806 
8807 	KASSERT((substate & SCTP_STATE_MASK) == 0,
8808 	        ("sctp_add_substate: Can't set state (substate = %x)",
8809 	        substate));
8810 	stcb->asoc.state |= substate;
8811 #if defined(KDTRACE_HOOKS)
8812 	if (((substate & SCTP_STATE_ABOUT_TO_BE_FREED) &&
8813 	     ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) ||
8814 	    ((substate & SCTP_STATE_SHUTDOWN_PENDING) &&
8815 	     ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) {
8816 		SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
8817 	}
8818 #endif
8819 }
8820 
8821