xref: /freebsd/sys/netinet/sctputil.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*-
2  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * a) Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  *
10  * b) Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *   the documentation and/or other materials provided with the distribution.
13  *
14  * c) Neither the name of Cisco Systems, Inc. nor the names of its
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $	 */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <netinet/sctp_os.h>
37 #include <netinet/sctp_pcb.h>
38 #include <netinet/sctputil.h>
39 #include <netinet/sctp_var.h>
40 #include <netinet/sctp_sysctl.h>
41 #ifdef INET6
42 #include <netinet6/sctp6_var.h>
43 #endif
44 #include <netinet/sctp_header.h>
45 #include <netinet/sctp_output.h>
46 #include <netinet/sctp_uio.h>
47 #include <netinet/sctp_timer.h>
48 #include <netinet/sctp_crc32.h>
49 #include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
50 #include <netinet/sctp_auth.h>
51 #include <netinet/sctp_asconf.h>
52 #include <netinet/sctp_cc_functions.h>
53 
54 #define NUMBER_OF_MTU_SIZES 18
55 
56 
57 #ifndef KTR_SCTP
58 #define KTR_SCTP KTR_SUBSYS
59 #endif
60 
61 void
62 sctp_sblog(struct sockbuf *sb,
63     struct sctp_tcb *stcb, int from, int incr)
64 {
65 	struct sctp_cwnd_log sctp_clog;
66 
67 	sctp_clog.x.sb.stcb = stcb;
68 	sctp_clog.x.sb.so_sbcc = sb->sb_cc;
69 	if (stcb)
70 		sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc;
71 	else
72 		sctp_clog.x.sb.stcb_sbcc = 0;
73 	sctp_clog.x.sb.incr = incr;
74 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
75 	    SCTP_LOG_EVENT_SB,
76 	    from,
77 	    sctp_clog.x.misc.log1,
78 	    sctp_clog.x.misc.log2,
79 	    sctp_clog.x.misc.log3,
80 	    sctp_clog.x.misc.log4);
81 }
82 
83 void
84 sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc)
85 {
86 	struct sctp_cwnd_log sctp_clog;
87 
88 	sctp_clog.x.close.inp = (void *)inp;
89 	sctp_clog.x.close.sctp_flags = inp->sctp_flags;
90 	if (stcb) {
91 		sctp_clog.x.close.stcb = (void *)stcb;
92 		sctp_clog.x.close.state = (uint16_t) stcb->asoc.state;
93 	} else {
94 		sctp_clog.x.close.stcb = 0;
95 		sctp_clog.x.close.state = 0;
96 	}
97 	sctp_clog.x.close.loc = loc;
98 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
99 	    SCTP_LOG_EVENT_CLOSE,
100 	    0,
101 	    sctp_clog.x.misc.log1,
102 	    sctp_clog.x.misc.log2,
103 	    sctp_clog.x.misc.log3,
104 	    sctp_clog.x.misc.log4);
105 }
106 
107 
108 void
109 rto_logging(struct sctp_nets *net, int from)
110 {
111 	struct sctp_cwnd_log sctp_clog;
112 
113 	sctp_clog.x.rto.net = (void *)net;
114 	sctp_clog.x.rto.rtt = net->prev_rtt;
115 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
116 	    SCTP_LOG_EVENT_RTT,
117 	    from,
118 	    sctp_clog.x.misc.log1,
119 	    sctp_clog.x.misc.log2,
120 	    sctp_clog.x.misc.log3,
121 	    sctp_clog.x.misc.log4);
122 
123 }
124 
125 void
126 sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16_t stream, int from)
127 {
128 	struct sctp_cwnd_log sctp_clog;
129 
130 	sctp_clog.x.strlog.stcb = stcb;
131 	sctp_clog.x.strlog.n_tsn = tsn;
132 	sctp_clog.x.strlog.n_sseq = sseq;
133 	sctp_clog.x.strlog.e_tsn = 0;
134 	sctp_clog.x.strlog.e_sseq = 0;
135 	sctp_clog.x.strlog.strm = stream;
136 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
137 	    SCTP_LOG_EVENT_STRM,
138 	    from,
139 	    sctp_clog.x.misc.log1,
140 	    sctp_clog.x.misc.log2,
141 	    sctp_clog.x.misc.log3,
142 	    sctp_clog.x.misc.log4);
143 
144 }
145 
146 void
147 sctp_log_nagle_event(struct sctp_tcb *stcb, int action)
148 {
149 	struct sctp_cwnd_log sctp_clog;
150 
151 	sctp_clog.x.nagle.stcb = (void *)stcb;
152 	sctp_clog.x.nagle.total_flight = stcb->asoc.total_flight;
153 	sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size;
154 	sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue;
155 	sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count;
156 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
157 	    SCTP_LOG_EVENT_NAGLE,
158 	    action,
159 	    sctp_clog.x.misc.log1,
160 	    sctp_clog.x.misc.log2,
161 	    sctp_clog.x.misc.log3,
162 	    sctp_clog.x.misc.log4);
163 }
164 
165 
166 void
167 sctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps, uint16_t dups, int from)
168 {
169 	struct sctp_cwnd_log sctp_clog;
170 
171 	sctp_clog.x.sack.cumack = cumack;
172 	sctp_clog.x.sack.oldcumack = old_cumack;
173 	sctp_clog.x.sack.tsn = tsn;
174 	sctp_clog.x.sack.numGaps = gaps;
175 	sctp_clog.x.sack.numDups = dups;
176 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
177 	    SCTP_LOG_EVENT_SACK,
178 	    from,
179 	    sctp_clog.x.misc.log1,
180 	    sctp_clog.x.misc.log2,
181 	    sctp_clog.x.misc.log3,
182 	    sctp_clog.x.misc.log4);
183 }
184 
185 void
186 sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
187 {
188 	struct sctp_cwnd_log sctp_clog;
189 
190 	sctp_clog.x.map.base = map;
191 	sctp_clog.x.map.cum = cum;
192 	sctp_clog.x.map.high = high;
193 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
194 	    SCTP_LOG_EVENT_MAP,
195 	    from,
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 }
201 
202 void
203 sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
204     int from)
205 {
206 	struct sctp_cwnd_log sctp_clog;
207 
208 	sctp_clog.x.fr.largest_tsn = biggest_tsn;
209 	sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn;
210 	sctp_clog.x.fr.tsn = tsn;
211 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
212 	    SCTP_LOG_EVENT_FR,
213 	    from,
214 	    sctp_clog.x.misc.log1,
215 	    sctp_clog.x.misc.log2,
216 	    sctp_clog.x.misc.log3,
217 	    sctp_clog.x.misc.log4);
218 
219 }
220 
221 
222 void
223 sctp_log_mb(struct mbuf *m, int from)
224 {
225 	struct sctp_cwnd_log sctp_clog;
226 
227 	sctp_clog.x.mb.mp = m;
228 	sctp_clog.x.mb.mbuf_flags = (uint8_t) (SCTP_BUF_GET_FLAGS(m));
229 	sctp_clog.x.mb.size = (uint16_t) (SCTP_BUF_LEN(m));
230 	sctp_clog.x.mb.data = SCTP_BUF_AT(m, 0);
231 	if (SCTP_BUF_IS_EXTENDED(m)) {
232 		sctp_clog.x.mb.ext = SCTP_BUF_EXTEND_BASE(m);
233 		sctp_clog.x.mb.refcnt = (uint8_t) (SCTP_BUF_EXTEND_REFCNT(m));
234 	} else {
235 		sctp_clog.x.mb.ext = 0;
236 		sctp_clog.x.mb.refcnt = 0;
237 	}
238 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
239 	    SCTP_LOG_EVENT_MBUF,
240 	    from,
241 	    sctp_clog.x.misc.log1,
242 	    sctp_clog.x.misc.log2,
243 	    sctp_clog.x.misc.log3,
244 	    sctp_clog.x.misc.log4);
245 }
246 
247 
248 void
249 sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk,
250     int from)
251 {
252 	struct sctp_cwnd_log sctp_clog;
253 
254 	if (control == NULL) {
255 		SCTP_PRINTF("Gak log of NULL?\n");
256 		return;
257 	}
258 	sctp_clog.x.strlog.stcb = control->stcb;
259 	sctp_clog.x.strlog.n_tsn = control->sinfo_tsn;
260 	sctp_clog.x.strlog.n_sseq = control->sinfo_ssn;
261 	sctp_clog.x.strlog.strm = control->sinfo_stream;
262 	if (poschk != NULL) {
263 		sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn;
264 		sctp_clog.x.strlog.e_sseq = poschk->sinfo_ssn;
265 	} else {
266 		sctp_clog.x.strlog.e_tsn = 0;
267 		sctp_clog.x.strlog.e_sseq = 0;
268 	}
269 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
270 	    SCTP_LOG_EVENT_STRM,
271 	    from,
272 	    sctp_clog.x.misc.log1,
273 	    sctp_clog.x.misc.log2,
274 	    sctp_clog.x.misc.log3,
275 	    sctp_clog.x.misc.log4);
276 
277 }
278 
279 void
280 sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
281 {
282 	struct sctp_cwnd_log sctp_clog;
283 
284 	sctp_clog.x.cwnd.net = net;
285 	if (stcb->asoc.send_queue_cnt > 255)
286 		sctp_clog.x.cwnd.cnt_in_send = 255;
287 	else
288 		sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
289 	if (stcb->asoc.stream_queue_cnt > 255)
290 		sctp_clog.x.cwnd.cnt_in_str = 255;
291 	else
292 		sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
293 
294 	if (net) {
295 		sctp_clog.x.cwnd.cwnd_new_value = net->cwnd;
296 		sctp_clog.x.cwnd.inflight = net->flight_size;
297 		sctp_clog.x.cwnd.pseudo_cumack = net->pseudo_cumack;
298 		sctp_clog.x.cwnd.meets_pseudo_cumack = net->new_pseudo_cumack;
299 		sctp_clog.x.cwnd.need_new_pseudo_cumack = net->find_pseudo_cumack;
300 	}
301 	if (SCTP_CWNDLOG_PRESEND == from) {
302 		sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd;
303 	}
304 	sctp_clog.x.cwnd.cwnd_augment = augment;
305 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
306 	    SCTP_LOG_EVENT_CWND,
307 	    from,
308 	    sctp_clog.x.misc.log1,
309 	    sctp_clog.x.misc.log2,
310 	    sctp_clog.x.misc.log3,
311 	    sctp_clog.x.misc.log4);
312 
313 }
314 
315 void
316 sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from)
317 {
318 	struct sctp_cwnd_log sctp_clog;
319 
320 	if (inp) {
321 		sctp_clog.x.lock.sock = (void *)inp->sctp_socket;
322 
323 	} else {
324 		sctp_clog.x.lock.sock = (void *)NULL;
325 	}
326 	sctp_clog.x.lock.inp = (void *)inp;
327 	if (stcb) {
328 		sctp_clog.x.lock.tcb_lock = mtx_owned(&stcb->tcb_mtx);
329 	} else {
330 		sctp_clog.x.lock.tcb_lock = SCTP_LOCK_UNKNOWN;
331 	}
332 	if (inp) {
333 		sctp_clog.x.lock.inp_lock = mtx_owned(&inp->inp_mtx);
334 		sctp_clog.x.lock.create_lock = mtx_owned(&inp->inp_create_mtx);
335 	} else {
336 		sctp_clog.x.lock.inp_lock = SCTP_LOCK_UNKNOWN;
337 		sctp_clog.x.lock.create_lock = SCTP_LOCK_UNKNOWN;
338 	}
339 	sctp_clog.x.lock.info_lock = rw_wowned(&sctppcbinfo.ipi_ep_mtx);
340 	if (inp->sctp_socket) {
341 		sctp_clog.x.lock.sock_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
342 		sctp_clog.x.lock.sockrcvbuf_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
343 		sctp_clog.x.lock.socksndbuf_lock = mtx_owned(&(inp->sctp_socket->so_snd.sb_mtx));
344 	} else {
345 		sctp_clog.x.lock.sock_lock = SCTP_LOCK_UNKNOWN;
346 		sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN;
347 		sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN;
348 	}
349 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
350 	    SCTP_LOG_LOCK_EVENT,
351 	    from,
352 	    sctp_clog.x.misc.log1,
353 	    sctp_clog.x.misc.log2,
354 	    sctp_clog.x.misc.log3,
355 	    sctp_clog.x.misc.log4);
356 
357 }
358 
359 void
360 sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from)
361 {
362 	struct sctp_cwnd_log sctp_clog;
363 
364 	sctp_clog.x.cwnd.net = net;
365 	sctp_clog.x.cwnd.cwnd_new_value = error;
366 	sctp_clog.x.cwnd.inflight = net->flight_size;
367 	sctp_clog.x.cwnd.cwnd_augment = burst;
368 	if (stcb->asoc.send_queue_cnt > 255)
369 		sctp_clog.x.cwnd.cnt_in_send = 255;
370 	else
371 		sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
372 	if (stcb->asoc.stream_queue_cnt > 255)
373 		sctp_clog.x.cwnd.cnt_in_str = 255;
374 	else
375 		sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
376 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
377 	    SCTP_LOG_EVENT_MAXBURST,
378 	    from,
379 	    sctp_clog.x.misc.log1,
380 	    sctp_clog.x.misc.log2,
381 	    sctp_clog.x.misc.log3,
382 	    sctp_clog.x.misc.log4);
383 
384 }
385 
386 void
387 sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead)
388 {
389 	struct sctp_cwnd_log sctp_clog;
390 
391 	sctp_clog.x.rwnd.rwnd = peers_rwnd;
392 	sctp_clog.x.rwnd.send_size = snd_size;
393 	sctp_clog.x.rwnd.overhead = overhead;
394 	sctp_clog.x.rwnd.new_rwnd = 0;
395 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
396 	    SCTP_LOG_EVENT_RWND,
397 	    from,
398 	    sctp_clog.x.misc.log1,
399 	    sctp_clog.x.misc.log2,
400 	    sctp_clog.x.misc.log3,
401 	    sctp_clog.x.misc.log4);
402 }
403 
404 void
405 sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint32_t overhead, uint32_t a_rwndval)
406 {
407 	struct sctp_cwnd_log sctp_clog;
408 
409 	sctp_clog.x.rwnd.rwnd = peers_rwnd;
410 	sctp_clog.x.rwnd.send_size = flight_size;
411 	sctp_clog.x.rwnd.overhead = overhead;
412 	sctp_clog.x.rwnd.new_rwnd = a_rwndval;
413 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
414 	    SCTP_LOG_EVENT_RWND,
415 	    from,
416 	    sctp_clog.x.misc.log1,
417 	    sctp_clog.x.misc.log2,
418 	    sctp_clog.x.misc.log3,
419 	    sctp_clog.x.misc.log4);
420 }
421 
422 void
423 sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt)
424 {
425 	struct sctp_cwnd_log sctp_clog;
426 
427 	sctp_clog.x.mbcnt.total_queue_size = total_oq;
428 	sctp_clog.x.mbcnt.size_change = book;
429 	sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q;
430 	sctp_clog.x.mbcnt.mbcnt_change = mbcnt;
431 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
432 	    SCTP_LOG_EVENT_MBCNT,
433 	    from,
434 	    sctp_clog.x.misc.log1,
435 	    sctp_clog.x.misc.log2,
436 	    sctp_clog.x.misc.log3,
437 	    sctp_clog.x.misc.log4);
438 
439 }
440 
441 void
442 sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
443 {
444 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
445 	    SCTP_LOG_MISC_EVENT,
446 	    from,
447 	    a, b, c, d);
448 }
449 
450 void
451 sctp_wakeup_log(struct sctp_tcb *stcb, uint32_t cumtsn, uint32_t wake_cnt, int from)
452 {
453 	struct sctp_cwnd_log sctp_clog;
454 
455 	sctp_clog.x.wake.stcb = (void *)stcb;
456 	sctp_clog.x.wake.wake_cnt = wake_cnt;
457 	sctp_clog.x.wake.flight = stcb->asoc.total_flight_count;
458 	sctp_clog.x.wake.send_q = stcb->asoc.send_queue_cnt;
459 	sctp_clog.x.wake.sent_q = stcb->asoc.sent_queue_cnt;
460 
461 	if (stcb->asoc.stream_queue_cnt < 0xff)
462 		sctp_clog.x.wake.stream_qcnt = (uint8_t) stcb->asoc.stream_queue_cnt;
463 	else
464 		sctp_clog.x.wake.stream_qcnt = 0xff;
465 
466 	if (stcb->asoc.chunks_on_out_queue < 0xff)
467 		sctp_clog.x.wake.chunks_on_oque = (uint8_t) stcb->asoc.chunks_on_out_queue;
468 	else
469 		sctp_clog.x.wake.chunks_on_oque = 0xff;
470 
471 	sctp_clog.x.wake.sctpflags = 0;
472 	/* set in the defered mode stuff */
473 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE)
474 		sctp_clog.x.wake.sctpflags |= 1;
475 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT)
476 		sctp_clog.x.wake.sctpflags |= 2;
477 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT)
478 		sctp_clog.x.wake.sctpflags |= 4;
479 	/* what about the sb */
480 	if (stcb->sctp_socket) {
481 		struct socket *so = stcb->sctp_socket;
482 
483 		sctp_clog.x.wake.sbflags = (uint8_t) ((so->so_snd.sb_flags & 0x00ff));
484 	} else {
485 		sctp_clog.x.wake.sbflags = 0xff;
486 	}
487 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
488 	    SCTP_LOG_EVENT_WAKE,
489 	    from,
490 	    sctp_clog.x.misc.log1,
491 	    sctp_clog.x.misc.log2,
492 	    sctp_clog.x.misc.log3,
493 	    sctp_clog.x.misc.log4);
494 
495 }
496 
497 void
498 sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc, int sendlen)
499 {
500 	struct sctp_cwnd_log sctp_clog;
501 
502 	sctp_clog.x.blk.onsb = asoc->total_output_queue_size;
503 	sctp_clog.x.blk.send_sent_qcnt = (uint16_t) (asoc->send_queue_cnt + asoc->sent_queue_cnt);
504 	sctp_clog.x.blk.peer_rwnd = asoc->peers_rwnd;
505 	sctp_clog.x.blk.stream_qcnt = (uint16_t) asoc->stream_queue_cnt;
506 	sctp_clog.x.blk.chunks_on_oque = (uint16_t) asoc->chunks_on_out_queue;
507 	sctp_clog.x.blk.flight_size = (uint16_t) (asoc->total_flight / 1024);
508 	sctp_clog.x.blk.sndlen = sendlen;
509 	SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
510 	    SCTP_LOG_EVENT_BLOCK,
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 
517 }
518 
519 int
520 sctp_fill_stat_log(void *optval, size_t *optsize)
521 {
522 	/* May need to fix this if ktrdump does not work */
523 	return (0);
524 }
525 
526 #ifdef SCTP_AUDITING_ENABLED
527 uint8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
528 static int sctp_audit_indx = 0;
529 
530 static
531 void
532 sctp_print_audit_report(void)
533 {
534 	int i;
535 	int cnt;
536 
537 	cnt = 0;
538 	for (i = sctp_audit_indx; i < SCTP_AUDIT_SIZE; i++) {
539 		if ((sctp_audit_data[i][0] == 0xe0) &&
540 		    (sctp_audit_data[i][1] == 0x01)) {
541 			cnt = 0;
542 			SCTP_PRINTF("\n");
543 		} else if (sctp_audit_data[i][0] == 0xf0) {
544 			cnt = 0;
545 			SCTP_PRINTF("\n");
546 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
547 		    (sctp_audit_data[i][1] == 0x01)) {
548 			SCTP_PRINTF("\n");
549 			cnt = 0;
550 		}
551 		SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
552 		    (uint32_t) sctp_audit_data[i][1]);
553 		cnt++;
554 		if ((cnt % 14) == 0)
555 			SCTP_PRINTF("\n");
556 	}
557 	for (i = 0; i < sctp_audit_indx; i++) {
558 		if ((sctp_audit_data[i][0] == 0xe0) &&
559 		    (sctp_audit_data[i][1] == 0x01)) {
560 			cnt = 0;
561 			SCTP_PRINTF("\n");
562 		} else if (sctp_audit_data[i][0] == 0xf0) {
563 			cnt = 0;
564 			SCTP_PRINTF("\n");
565 		} else if ((sctp_audit_data[i][0] == 0xc0) &&
566 		    (sctp_audit_data[i][1] == 0x01)) {
567 			SCTP_PRINTF("\n");
568 			cnt = 0;
569 		}
570 		SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
571 		    (uint32_t) sctp_audit_data[i][1]);
572 		cnt++;
573 		if ((cnt % 14) == 0)
574 			SCTP_PRINTF("\n");
575 	}
576 	SCTP_PRINTF("\n");
577 }
578 
579 void
580 sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
581     struct sctp_nets *net)
582 {
583 	int resend_cnt, tot_out, rep, tot_book_cnt;
584 	struct sctp_nets *lnet;
585 	struct sctp_tmit_chunk *chk;
586 
587 	sctp_audit_data[sctp_audit_indx][0] = 0xAA;
588 	sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
589 	sctp_audit_indx++;
590 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
591 		sctp_audit_indx = 0;
592 	}
593 	if (inp == NULL) {
594 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
595 		sctp_audit_data[sctp_audit_indx][1] = 0x01;
596 		sctp_audit_indx++;
597 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
598 			sctp_audit_indx = 0;
599 		}
600 		return;
601 	}
602 	if (stcb == NULL) {
603 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
604 		sctp_audit_data[sctp_audit_indx][1] = 0x02;
605 		sctp_audit_indx++;
606 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
607 			sctp_audit_indx = 0;
608 		}
609 		return;
610 	}
611 	sctp_audit_data[sctp_audit_indx][0] = 0xA1;
612 	sctp_audit_data[sctp_audit_indx][1] =
613 	    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
614 	sctp_audit_indx++;
615 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
616 		sctp_audit_indx = 0;
617 	}
618 	rep = 0;
619 	tot_book_cnt = 0;
620 	resend_cnt = tot_out = 0;
621 	TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
622 		if (chk->sent == SCTP_DATAGRAM_RESEND) {
623 			resend_cnt++;
624 		} else if (chk->sent < SCTP_DATAGRAM_RESEND) {
625 			tot_out += chk->book_size;
626 			tot_book_cnt++;
627 		}
628 	}
629 	if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
630 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
631 		sctp_audit_data[sctp_audit_indx][1] = 0xA1;
632 		sctp_audit_indx++;
633 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
634 			sctp_audit_indx = 0;
635 		}
636 		SCTP_PRINTF("resend_cnt:%d asoc-tot:%d\n",
637 		    resend_cnt, stcb->asoc.sent_queue_retran_cnt);
638 		rep = 1;
639 		stcb->asoc.sent_queue_retran_cnt = resend_cnt;
640 		sctp_audit_data[sctp_audit_indx][0] = 0xA2;
641 		sctp_audit_data[sctp_audit_indx][1] =
642 		    (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
643 		sctp_audit_indx++;
644 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
645 			sctp_audit_indx = 0;
646 		}
647 	}
648 	if (tot_out != stcb->asoc.total_flight) {
649 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
650 		sctp_audit_data[sctp_audit_indx][1] = 0xA2;
651 		sctp_audit_indx++;
652 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
653 			sctp_audit_indx = 0;
654 		}
655 		rep = 1;
656 		SCTP_PRINTF("tot_flt:%d asoc_tot:%d\n", tot_out,
657 		    (int)stcb->asoc.total_flight);
658 		stcb->asoc.total_flight = tot_out;
659 	}
660 	if (tot_book_cnt != stcb->asoc.total_flight_count) {
661 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
662 		sctp_audit_data[sctp_audit_indx][1] = 0xA5;
663 		sctp_audit_indx++;
664 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
665 			sctp_audit_indx = 0;
666 		}
667 		rep = 1;
668 		SCTP_PRINTF("tot_flt_book:%d\n", tot_book);
669 
670 		stcb->asoc.total_flight_count = tot_book_cnt;
671 	}
672 	tot_out = 0;
673 	TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
674 		tot_out += lnet->flight_size;
675 	}
676 	if (tot_out != stcb->asoc.total_flight) {
677 		sctp_audit_data[sctp_audit_indx][0] = 0xAF;
678 		sctp_audit_data[sctp_audit_indx][1] = 0xA3;
679 		sctp_audit_indx++;
680 		if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
681 			sctp_audit_indx = 0;
682 		}
683 		rep = 1;
684 		SCTP_PRINTF("real flight:%d net total was %d\n",
685 		    stcb->asoc.total_flight, tot_out);
686 		/* now corrective action */
687 		TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
688 
689 			tot_out = 0;
690 			TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
691 				if ((chk->whoTo == lnet) &&
692 				    (chk->sent < SCTP_DATAGRAM_RESEND)) {
693 					tot_out += chk->book_size;
694 				}
695 			}
696 			if (lnet->flight_size != tot_out) {
697 				SCTP_PRINTF("net:%x flight was %d corrected to %d\n",
698 				    (uint32_t) lnet, lnet->flight_size,
699 				    tot_out);
700 				lnet->flight_size = tot_out;
701 			}
702 		}
703 	}
704 	if (rep) {
705 		sctp_print_audit_report();
706 	}
707 }
708 
709 void
710 sctp_audit_log(uint8_t ev, uint8_t fd)
711 {
712 
713 	sctp_audit_data[sctp_audit_indx][0] = ev;
714 	sctp_audit_data[sctp_audit_indx][1] = fd;
715 	sctp_audit_indx++;
716 	if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
717 		sctp_audit_indx = 0;
718 	}
719 }
720 
721 #endif
722 
723 /*
724  * a list of sizes based on typical mtu's, used only if next hop size not
725  * returned.
726  */
727 static int sctp_mtu_sizes[] = {
728 	68,
729 	296,
730 	508,
731 	512,
732 	544,
733 	576,
734 	1006,
735 	1492,
736 	1500,
737 	1536,
738 	2002,
739 	2048,
740 	4352,
741 	4464,
742 	8166,
743 	17914,
744 	32000,
745 	65535
746 };
747 
748 void
749 sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
750 {
751 	struct sctp_association *asoc;
752 	struct sctp_nets *net;
753 
754 	asoc = &stcb->asoc;
755 
756 	(void)SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
757 	(void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
758 	(void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
759 	(void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
760 	(void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
761 	(void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
762 	TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
763 		(void)SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
764 		(void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
765 	}
766 }
767 
768 int
769 find_next_best_mtu(int totsz)
770 {
771 	int i, perfer;
772 
773 	/*
774 	 * if we are in here we must find the next best fit based on the
775 	 * size of the dg that failed to be sent.
776 	 */
777 	perfer = 0;
778 	for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) {
779 		if (totsz < sctp_mtu_sizes[i]) {
780 			perfer = i - 1;
781 			if (perfer < 0)
782 				perfer = 0;
783 			break;
784 		}
785 	}
786 	return (sctp_mtu_sizes[perfer]);
787 }
788 
789 void
790 sctp_fill_random_store(struct sctp_pcb *m)
791 {
792 	/*
793 	 * Here we use the MD5/SHA-1 to hash with our good randomNumbers and
794 	 * our counter. The result becomes our good random numbers and we
795 	 * then setup to give these out. Note that we do no locking to
796 	 * protect this. This is ok, since if competing folks call this we
797 	 * will get more gobbled gook in the random store which is what we
798 	 * want. There is a danger that two guys will use the same random
799 	 * numbers, but thats ok too since that is random as well :->
800 	 */
801 	m->store_at = 0;
802 	(void)sctp_hmac(SCTP_HMAC, (uint8_t *) m->random_numbers,
803 	    sizeof(m->random_numbers), (uint8_t *) & m->random_counter,
804 	    sizeof(m->random_counter), (uint8_t *) m->random_store);
805 	m->random_counter++;
806 }
807 
808 uint32_t
809 sctp_select_initial_TSN(struct sctp_pcb *inp)
810 {
811 	/*
812 	 * A true implementation should use random selection process to get
813 	 * the initial stream sequence number, using RFC1750 as a good
814 	 * guideline
815 	 */
816 	uint32_t x, *xp;
817 	uint8_t *p;
818 	int store_at, new_store;
819 
820 	if (inp->initial_sequence_debug != 0) {
821 		uint32_t ret;
822 
823 		ret = inp->initial_sequence_debug;
824 		inp->initial_sequence_debug++;
825 		return (ret);
826 	}
827 retry:
828 	store_at = inp->store_at;
829 	new_store = store_at + sizeof(uint32_t);
830 	if (new_store >= (SCTP_SIGNATURE_SIZE - 3)) {
831 		new_store = 0;
832 	}
833 	if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) {
834 		goto retry;
835 	}
836 	if (new_store == 0) {
837 		/* Refill the random store */
838 		sctp_fill_random_store(inp);
839 	}
840 	p = &inp->random_store[store_at];
841 	xp = (uint32_t *) p;
842 	x = *xp;
843 	return (x);
844 }
845 
846 uint32_t
847 sctp_select_a_tag(struct sctp_inpcb *inp, int save_in_twait)
848 {
849 	u_long x, not_done;
850 	struct timeval now;
851 
852 	(void)SCTP_GETTIME_TIMEVAL(&now);
853 	not_done = 1;
854 	while (not_done) {
855 		x = sctp_select_initial_TSN(&inp->sctp_ep);
856 		if (x == 0) {
857 			/* we never use 0 */
858 			continue;
859 		}
860 		if (sctp_is_vtag_good(inp, x, &now, save_in_twait)) {
861 			not_done = 0;
862 		}
863 	}
864 	return (x);
865 }
866 
867 int
868 sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
869     int for_a_init, uint32_t override_tag, uint32_t vrf_id)
870 {
871 	struct sctp_association *asoc;
872 
873 	/*
874 	 * Anything set to zero is taken care of by the allocation routine's
875 	 * bzero
876 	 */
877 
878 	/*
879 	 * Up front select what scoping to apply on addresses I tell my peer
880 	 * Not sure what to do with these right now, we will need to come up
881 	 * with a way to set them. We may need to pass them through from the
882 	 * caller in the sctp_aloc_assoc() function.
883 	 */
884 	int i;
885 
886 	asoc = &stcb->asoc;
887 	/* init all variables to a known value. */
888 	SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE);
889 	asoc->max_burst = m->sctp_ep.max_burst;
890 	asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
891 	asoc->cookie_life = m->sctp_ep.def_cookie_life;
892 	asoc->sctp_cmt_on_off = (uint8_t) sctp_cmt_on_off;
893 	/* JRS 5/21/07 - Init CMT PF variables */
894 	asoc->sctp_cmt_pf = (uint8_t) sctp_cmt_pf;
895 	asoc->sctp_frag_point = m->sctp_frag_point;
896 #ifdef INET
897 	asoc->default_tos = m->ip_inp.inp.inp_ip_tos;
898 #else
899 	asoc->default_tos = 0;
900 #endif
901 
902 #ifdef INET6
903 	asoc->default_flowlabel = ((struct in6pcb *)m)->in6p_flowinfo;
904 #else
905 	asoc->default_flowlabel = 0;
906 #endif
907 	asoc->sb_send_resv = 0;
908 	if (override_tag) {
909 		struct timeval now;
910 
911 		(void)SCTP_GETTIME_TIMEVAL(&now);
912 		if (sctp_is_in_timewait(override_tag)) {
913 			/*
914 			 * It must be in the time-wait hash, we put it there
915 			 * when we aloc one. If not the peer is playing
916 			 * games.
917 			 */
918 			asoc->my_vtag = override_tag;
919 		} else {
920 			SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
921 			panic("Huh is_in_timewait fails");
922 			return (ENOMEM);
923 		}
924 
925 	} else {
926 		asoc->my_vtag = sctp_select_a_tag(m, 1);
927 	}
928 	/* Get the nonce tags */
929 	asoc->my_vtag_nonce = sctp_select_a_tag(m, 0);
930 	asoc->peer_vtag_nonce = sctp_select_a_tag(m, 0);
931 	asoc->vrf_id = vrf_id;
932 
933 	if (sctp_is_feature_on(m, SCTP_PCB_FLAGS_DONOT_HEARTBEAT))
934 		asoc->hb_is_disabled = 1;
935 	else
936 		asoc->hb_is_disabled = 0;
937 
938 #ifdef SCTP_ASOCLOG_OF_TSNS
939 	asoc->tsn_in_at = 0;
940 	asoc->tsn_out_at = 0;
941 	asoc->tsn_in_wrapped = 0;
942 	asoc->tsn_out_wrapped = 0;
943 	asoc->cumack_log_at = 0;
944 	asoc->cumack_log_atsnt = 0;
945 #endif
946 #ifdef SCTP_FS_SPEC_LOG
947 	asoc->fs_index = 0;
948 #endif
949 	asoc->refcnt = 0;
950 	asoc->assoc_up_sent = 0;
951 	asoc->assoc_id = asoc->my_vtag;
952 	asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
953 	    sctp_select_initial_TSN(&m->sctp_ep);
954 	/* we are optimisitic here */
955 	asoc->peer_supports_pktdrop = 1;
956 
957 	asoc->sent_queue_retran_cnt = 0;
958 
959 	/* for CMT */
960 	asoc->last_net_data_came_from = NULL;
961 
962 	/* This will need to be adjusted */
963 	asoc->last_cwr_tsn = asoc->init_seq_number - 1;
964 	asoc->last_acked_seq = asoc->init_seq_number - 1;
965 	asoc->advanced_peer_ack_point = asoc->last_acked_seq;
966 	asoc->asconf_seq_in = asoc->last_acked_seq;
967 
968 	/* here we are different, we hold the next one we expect */
969 	asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
970 
971 	asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
972 	asoc->initial_rto = m->sctp_ep.initial_rto;
973 
974 	asoc->max_init_times = m->sctp_ep.max_init_times;
975 	asoc->max_send_times = m->sctp_ep.max_send_times;
976 	asoc->def_net_failure = m->sctp_ep.def_net_failure;
977 	asoc->free_chunk_cnt = 0;
978 
979 	asoc->iam_blocking = 0;
980 	/* ECN Nonce initialization */
981 	asoc->context = m->sctp_context;
982 	asoc->def_send = m->def_send;
983 	asoc->ecn_nonce_allowed = 0;
984 	asoc->receiver_nonce_sum = 1;
985 	asoc->nonce_sum_expect_base = 1;
986 	asoc->nonce_sum_check = 1;
987 	asoc->nonce_resync_tsn = 0;
988 	asoc->nonce_wait_for_ecne = 0;
989 	asoc->nonce_wait_tsn = 0;
990 	asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
991 	asoc->sack_freq = m->sctp_ep.sctp_sack_freq;
992 	asoc->pr_sctp_cnt = 0;
993 	asoc->total_output_queue_size = 0;
994 
995 	if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
996 		struct in6pcb *inp6;
997 
998 		/* Its a V6 socket */
999 		inp6 = (struct in6pcb *)m;
1000 		asoc->ipv6_addr_legal = 1;
1001 		/* Now look at the binding flag to see if V4 will be legal */
1002 		if (SCTP_IPV6_V6ONLY(inp6) == 0) {
1003 			asoc->ipv4_addr_legal = 1;
1004 		} else {
1005 			/* V4 addresses are NOT legal on the association */
1006 			asoc->ipv4_addr_legal = 0;
1007 		}
1008 	} else {
1009 		/* Its a V4 socket, no - V6 */
1010 		asoc->ipv4_addr_legal = 1;
1011 		asoc->ipv6_addr_legal = 0;
1012 	}
1013 
1014 	asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(m->sctp_socket), SCTP_MINIMAL_RWND);
1015 	asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(m->sctp_socket);
1016 
1017 	asoc->smallest_mtu = m->sctp_frag_point;
1018 #ifdef SCTP_PRINT_FOR_B_AND_M
1019 	SCTP_PRINTF("smallest_mtu init'd with asoc to :%d\n",
1020 	    asoc->smallest_mtu);
1021 #endif
1022 	asoc->minrto = m->sctp_ep.sctp_minrto;
1023 	asoc->maxrto = m->sctp_ep.sctp_maxrto;
1024 
1025 	asoc->locked_on_sending = NULL;
1026 	asoc->stream_locked_on = 0;
1027 	asoc->ecn_echo_cnt_onq = 0;
1028 	asoc->stream_locked = 0;
1029 
1030 	asoc->send_sack = 1;
1031 
1032 	LIST_INIT(&asoc->sctp_restricted_addrs);
1033 
1034 	TAILQ_INIT(&asoc->nets);
1035 	TAILQ_INIT(&asoc->pending_reply_queue);
1036 	TAILQ_INIT(&asoc->asconf_ack_sent);
1037 	/* Setup to fill the hb random cache at first HB */
1038 	asoc->hb_random_idx = 4;
1039 
1040 	asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
1041 
1042 	/*
1043 	 * JRS - Pick the default congestion control module based on the
1044 	 * sysctl.
1045 	 */
1046 	switch (m->sctp_ep.sctp_default_cc_module) {
1047 		/* JRS - Standard TCP congestion control */
1048 	case SCTP_CC_RFC2581:
1049 		{
1050 			stcb->asoc.congestion_control_module = SCTP_CC_RFC2581;
1051 			stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param;
1052 			stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_cwnd_update_after_sack;
1053 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_cwnd_update_after_fr;
1054 			stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout;
1055 			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo;
1056 			stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
1057 			stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
1058 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer;
1059 			break;
1060 		}
1061 		/* JRS - High Speed TCP congestion control (Floyd) */
1062 	case SCTP_CC_HSTCP:
1063 		{
1064 			stcb->asoc.congestion_control_module = SCTP_CC_HSTCP;
1065 			stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param;
1066 			stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_hs_cwnd_update_after_sack;
1067 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_hs_cwnd_update_after_fr;
1068 			stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout;
1069 			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo;
1070 			stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
1071 			stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
1072 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer;
1073 			break;
1074 		}
1075 		/* JRS - HTCP congestion control */
1076 	case SCTP_CC_HTCP:
1077 		{
1078 			stcb->asoc.congestion_control_module = SCTP_CC_HTCP;
1079 			stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_htcp_set_initial_cc_param;
1080 			stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_htcp_cwnd_update_after_sack;
1081 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_htcp_cwnd_update_after_fr;
1082 			stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_htcp_cwnd_update_after_timeout;
1083 			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_htcp_cwnd_update_after_ecn_echo;
1084 			stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
1085 			stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
1086 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_htcp_cwnd_update_after_fr_timer;
1087 			break;
1088 		}
1089 		/* JRS - By default, use RFC2581 */
1090 	default:
1091 		{
1092 			stcb->asoc.congestion_control_module = SCTP_CC_RFC2581;
1093 			stcb->asoc.cc_functions.sctp_set_initial_cc_param = &sctp_set_initial_cc_param;
1094 			stcb->asoc.cc_functions.sctp_cwnd_update_after_sack = &sctp_cwnd_update_after_sack;
1095 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr = &sctp_cwnd_update_after_fr;
1096 			stcb->asoc.cc_functions.sctp_cwnd_update_after_timeout = &sctp_cwnd_update_after_timeout;
1097 			stcb->asoc.cc_functions.sctp_cwnd_update_after_ecn_echo = &sctp_cwnd_update_after_ecn_echo;
1098 			stcb->asoc.cc_functions.sctp_cwnd_update_after_packet_dropped = &sctp_cwnd_update_after_packet_dropped;
1099 			stcb->asoc.cc_functions.sctp_cwnd_update_after_output = &sctp_cwnd_update_after_output;
1100 			stcb->asoc.cc_functions.sctp_cwnd_update_after_fr_timer = &sctp_cwnd_update_after_fr_timer;
1101 			break;
1102 		}
1103 	}
1104 
1105 	/*
1106 	 * Now the stream parameters, here we allocate space for all streams
1107 	 * that we request by default.
1108 	 */
1109 	asoc->streamoutcnt = asoc->pre_open_streams =
1110 	    m->sctp_ep.pre_open_stream_count;
1111 	SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
1112 	    asoc->streamoutcnt * sizeof(struct sctp_stream_out),
1113 	    SCTP_M_STRMO);
1114 	if (asoc->strmout == NULL) {
1115 		/* big trouble no memory */
1116 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1117 		return (ENOMEM);
1118 	}
1119 	for (i = 0; i < asoc->streamoutcnt; i++) {
1120 		/*
1121 		 * inbound side must be set to 0xffff, also NOTE when we get
1122 		 * the INIT-ACK back (for INIT sender) we MUST reduce the
1123 		 * count (streamoutcnt) but first check if we sent to any of
1124 		 * the upper streams that were dropped (if some were). Those
1125 		 * that were dropped must be notified to the upper layer as
1126 		 * failed to send.
1127 		 */
1128 		asoc->strmout[i].next_sequence_sent = 0x0;
1129 		TAILQ_INIT(&asoc->strmout[i].outqueue);
1130 		asoc->strmout[i].stream_no = i;
1131 		asoc->strmout[i].last_msg_incomplete = 0;
1132 		asoc->strmout[i].next_spoke.tqe_next = 0;
1133 		asoc->strmout[i].next_spoke.tqe_prev = 0;
1134 	}
1135 	/* Now the mapping array */
1136 	asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
1137 	SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1138 	    SCTP_M_MAP);
1139 	if (asoc->mapping_array == NULL) {
1140 		SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1141 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1142 		return (ENOMEM);
1143 	}
1144 	memset(asoc->mapping_array, 0, asoc->mapping_array_size);
1145 	/* Now the init of the other outqueues */
1146 	TAILQ_INIT(&asoc->free_chunks);
1147 	TAILQ_INIT(&asoc->out_wheel);
1148 	TAILQ_INIT(&asoc->control_send_queue);
1149 	TAILQ_INIT(&asoc->send_queue);
1150 	TAILQ_INIT(&asoc->sent_queue);
1151 	TAILQ_INIT(&asoc->reasmqueue);
1152 	TAILQ_INIT(&asoc->resetHead);
1153 	asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
1154 	TAILQ_INIT(&asoc->asconf_queue);
1155 	/* authentication fields */
1156 	asoc->authinfo.random = NULL;
1157 	asoc->authinfo.assoc_key = NULL;
1158 	asoc->authinfo.assoc_keyid = 0;
1159 	asoc->authinfo.recv_key = NULL;
1160 	asoc->authinfo.recv_keyid = 0;
1161 	LIST_INIT(&asoc->shared_keys);
1162 	asoc->marked_retrans = 0;
1163 	asoc->timoinit = 0;
1164 	asoc->timodata = 0;
1165 	asoc->timosack = 0;
1166 	asoc->timoshutdown = 0;
1167 	asoc->timoheartbeat = 0;
1168 	asoc->timocookie = 0;
1169 	asoc->timoshutdownack = 0;
1170 	(void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
1171 	asoc->discontinuity_time = asoc->start_time;
1172 	/*
1173 	 * sa_ignore MEMLEAK {memory is put in the assoc mapping array and
1174 	 * freed later whe the association is freed.
1175 	 */
1176 	return (0);
1177 }
1178 
1179 int
1180 sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
1181 {
1182 	/* mapping array needs to grow */
1183 	uint8_t *new_array;
1184 	uint32_t new_size;
1185 
1186 	new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
1187 	SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
1188 	if (new_array == NULL) {
1189 		/* can't get more, forget it */
1190 		SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
1191 		    new_size);
1192 		return (-1);
1193 	}
1194 	memset(new_array, 0, new_size);
1195 	memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
1196 	SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1197 	asoc->mapping_array = new_array;
1198 	asoc->mapping_array_size = new_size;
1199 	return (0);
1200 }
1201 
1202 #if defined(SCTP_USE_THREAD_BASED_ITERATOR)
1203 static void
1204 sctp_iterator_work(struct sctp_iterator *it)
1205 {
1206 	int iteration_count = 0;
1207 	int inp_skip = 0;
1208 
1209 	SCTP_ITERATOR_LOCK();
1210 	if (it->inp) {
1211 		SCTP_INP_DECR_REF(it->inp);
1212 	}
1213 	if (it->inp == NULL) {
1214 		/* iterator is complete */
1215 done_with_iterator:
1216 		SCTP_ITERATOR_UNLOCK();
1217 		if (it->function_atend != NULL) {
1218 			(*it->function_atend) (it->pointer, it->val);
1219 		}
1220 		SCTP_FREE(it, SCTP_M_ITER);
1221 		return;
1222 	}
1223 select_a_new_ep:
1224 	SCTP_INP_WLOCK(it->inp);
1225 	while (((it->pcb_flags) &&
1226 	    ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) ||
1227 	    ((it->pcb_features) &&
1228 	    ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) {
1229 		/* endpoint flags or features don't match, so keep looking */
1230 		if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1231 			SCTP_INP_WUNLOCK(it->inp);
1232 			goto done_with_iterator;
1233 		}
1234 		SCTP_INP_WUNLOCK(it->inp);
1235 		it->inp = LIST_NEXT(it->inp, sctp_list);
1236 		if (it->inp == NULL) {
1237 			goto done_with_iterator;
1238 		}
1239 		SCTP_INP_WLOCK(it->inp);
1240 	}
1241 
1242 	SCTP_INP_WUNLOCK(it->inp);
1243 	SCTP_INP_RLOCK(it->inp);
1244 
1245 	/* now go through each assoc which is in the desired state */
1246 	if (it->done_current_ep == 0) {
1247 		if (it->function_inp != NULL)
1248 			inp_skip = (*it->function_inp) (it->inp, it->pointer, it->val);
1249 		it->done_current_ep = 1;
1250 	}
1251 	if (it->stcb == NULL) {
1252 		/* run the per instance function */
1253 		it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
1254 	}
1255 	if ((inp_skip) || it->stcb == NULL) {
1256 		if (it->function_inp_end != NULL) {
1257 			inp_skip = (*it->function_inp_end) (it->inp,
1258 			    it->pointer,
1259 			    it->val);
1260 		}
1261 		SCTP_INP_RUNLOCK(it->inp);
1262 		goto no_stcb;
1263 	}
1264 	while (it->stcb) {
1265 		SCTP_TCB_LOCK(it->stcb);
1266 		if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
1267 			/* not in the right state... keep looking */
1268 			SCTP_TCB_UNLOCK(it->stcb);
1269 			goto next_assoc;
1270 		}
1271 		/* see if we have limited out the iterator loop */
1272 		iteration_count++;
1273 		if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) {
1274 			/* Pause to let others grab the lock */
1275 			atomic_add_int(&it->stcb->asoc.refcnt, 1);
1276 			SCTP_TCB_UNLOCK(it->stcb);
1277 
1278 			SCTP_INP_INCR_REF(it->inp);
1279 			SCTP_INP_RUNLOCK(it->inp);
1280 			SCTP_ITERATOR_UNLOCK();
1281 			SCTP_ITERATOR_LOCK();
1282 			SCTP_INP_RLOCK(it->inp);
1283 
1284 			SCTP_INP_DECR_REF(it->inp);
1285 			SCTP_TCB_LOCK(it->stcb);
1286 			atomic_add_int(&it->stcb->asoc.refcnt, -1);
1287 			iteration_count = 0;
1288 		}
1289 		/* run function on this one */
1290 		(*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val);
1291 
1292 		/*
1293 		 * we lie here, it really needs to have its own type but
1294 		 * first I must verify that this won't effect things :-0
1295 		 */
1296 		if (it->no_chunk_output == 0)
1297 			sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1298 
1299 		SCTP_TCB_UNLOCK(it->stcb);
1300 next_assoc:
1301 		it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1302 		if (it->stcb == NULL) {
1303 			/* Run last function */
1304 			if (it->function_inp_end != NULL) {
1305 				inp_skip = (*it->function_inp_end) (it->inp,
1306 				    it->pointer,
1307 				    it->val);
1308 			}
1309 		}
1310 	}
1311 	SCTP_INP_RUNLOCK(it->inp);
1312 no_stcb:
1313 	/* done with all assocs on this endpoint, move on to next endpoint */
1314 	it->done_current_ep = 0;
1315 	SCTP_INP_WLOCK(it->inp);
1316 	SCTP_INP_WUNLOCK(it->inp);
1317 	if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1318 		it->inp = NULL;
1319 	} else {
1320 		SCTP_INP_INFO_RLOCK();
1321 		it->inp = LIST_NEXT(it->inp, sctp_list);
1322 		SCTP_INP_INFO_RUNLOCK();
1323 	}
1324 	if (it->inp == NULL) {
1325 		goto done_with_iterator;
1326 	}
1327 	goto select_a_new_ep;
1328 }
1329 
1330 void
1331 sctp_iterator_worker(void)
1332 {
1333 	struct sctp_iterator *it = NULL;
1334 
1335 	/* This function is called with the WQ lock in place */
1336 
1337 	sctppcbinfo.iterator_running = 1;
1338 again:
1339 	it = TAILQ_FIRST(&sctppcbinfo.iteratorhead);
1340 	while (it) {
1341 		/* now lets work on this one */
1342 		TAILQ_REMOVE(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
1343 		SCTP_IPI_ITERATOR_WQ_UNLOCK();
1344 		sctp_iterator_work(it);
1345 		SCTP_IPI_ITERATOR_WQ_LOCK();
1346 		/* sa_ignore FREED_MEMORY */
1347 		it = TAILQ_FIRST(&sctppcbinfo.iteratorhead);
1348 	}
1349 	if (TAILQ_FIRST(&sctppcbinfo.iteratorhead)) {
1350 		goto again;
1351 	}
1352 	sctppcbinfo.iterator_running = 0;
1353 	return;
1354 }
1355 
1356 #endif
1357 
1358 
1359 static void
1360 sctp_handle_addr_wq(void)
1361 {
1362 	/* deal with the ADDR wq from the rtsock calls */
1363 	struct sctp_laddr *wi;
1364 	struct sctp_asconf_iterator *asc;
1365 
1366 	SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
1367 	    sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT);
1368 	if (asc == NULL) {
1369 		/* Try later, no memory */
1370 		sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
1371 		    (struct sctp_inpcb *)NULL,
1372 		    (struct sctp_tcb *)NULL,
1373 		    (struct sctp_nets *)NULL);
1374 		return;
1375 	}
1376 	LIST_INIT(&asc->list_of_work);
1377 	asc->cnt = 0;
1378 	SCTP_IPI_ITERATOR_WQ_LOCK();
1379 	wi = LIST_FIRST(&sctppcbinfo.addr_wq);
1380 	while (wi != NULL) {
1381 		LIST_REMOVE(wi, sctp_nxt_addr);
1382 		LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
1383 		asc->cnt++;
1384 		wi = LIST_FIRST(&sctppcbinfo.addr_wq);
1385 	}
1386 	SCTP_IPI_ITERATOR_WQ_UNLOCK();
1387 	if (asc->cnt == 0) {
1388 		SCTP_FREE(asc, SCTP_M_ASC_IT);
1389 	} else {
1390 		(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
1391 		    sctp_asconf_iterator_stcb,
1392 		    NULL,	/* No ep end for boundall */
1393 		    SCTP_PCB_FLAGS_BOUNDALL,
1394 		    SCTP_PCB_ANY_FEATURES,
1395 		    SCTP_ASOC_ANY_STATE,
1396 		    (void *)asc, 0,
1397 		    sctp_asconf_iterator_end, NULL, 0);
1398 	}
1399 }
1400 
1401 int retcode = 0;
1402 int cur_oerr = 0;
1403 
1404 void
1405 sctp_timeout_handler(void *t)
1406 {
1407 	struct sctp_inpcb *inp;
1408 	struct sctp_tcb *stcb;
1409 	struct sctp_nets *net;
1410 	struct sctp_timer *tmr;
1411 
1412 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1413 	struct socket *so;
1414 
1415 #endif
1416 	int did_output;
1417 	struct sctp_iterator *it = NULL;
1418 
1419 	tmr = (struct sctp_timer *)t;
1420 	inp = (struct sctp_inpcb *)tmr->ep;
1421 	stcb = (struct sctp_tcb *)tmr->tcb;
1422 	net = (struct sctp_nets *)tmr->net;
1423 	did_output = 1;
1424 
1425 #ifdef SCTP_AUDITING_ENABLED
1426 	sctp_audit_log(0xF0, (uint8_t) tmr->type);
1427 	sctp_auditing(3, inp, stcb, net);
1428 #endif
1429 
1430 	/* sanity checks... */
1431 	if (tmr->self != (void *)tmr) {
1432 		/*
1433 		 * SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n",
1434 		 * tmr);
1435 		 */
1436 		return;
1437 	}
1438 	tmr->stopped_from = 0xa001;
1439 	if (!SCTP_IS_TIMER_TYPE_VALID(tmr->type)) {
1440 		/*
1441 		 * SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n",
1442 		 * tmr->type);
1443 		 */
1444 		return;
1445 	}
1446 	tmr->stopped_from = 0xa002;
1447 	if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) {
1448 		return;
1449 	}
1450 	/* if this is an iterator timeout, get the struct and clear inp */
1451 	tmr->stopped_from = 0xa003;
1452 	if (tmr->type == SCTP_TIMER_TYPE_ITERATOR) {
1453 		it = (struct sctp_iterator *)inp;
1454 		inp = NULL;
1455 	}
1456 	if (inp) {
1457 		SCTP_INP_INCR_REF(inp);
1458 		if ((inp->sctp_socket == 0) &&
1459 		    ((tmr->type != SCTP_TIMER_TYPE_INPKILL) &&
1460 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) &&
1461 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) &&
1462 		    (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) &&
1463 		    (tmr->type != SCTP_TIMER_TYPE_ASOCKILL))
1464 		    ) {
1465 			SCTP_INP_DECR_REF(inp);
1466 			return;
1467 		}
1468 	}
1469 	tmr->stopped_from = 0xa004;
1470 	if (stcb) {
1471 		atomic_add_int(&stcb->asoc.refcnt, 1);
1472 		if (stcb->asoc.state == 0) {
1473 			atomic_add_int(&stcb->asoc.refcnt, -1);
1474 			if (inp) {
1475 				SCTP_INP_DECR_REF(inp);
1476 			}
1477 			return;
1478 		}
1479 	}
1480 	tmr->stopped_from = 0xa005;
1481 	SCTPDBG(SCTP_DEBUG_TIMER1, "Timer type %d goes off\n", tmr->type);
1482 	if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1483 		if (inp) {
1484 			SCTP_INP_DECR_REF(inp);
1485 		}
1486 		if (stcb) {
1487 			atomic_add_int(&stcb->asoc.refcnt, -1);
1488 		}
1489 		return;
1490 	}
1491 	tmr->stopped_from = 0xa006;
1492 
1493 	if (stcb) {
1494 		SCTP_TCB_LOCK(stcb);
1495 		atomic_add_int(&stcb->asoc.refcnt, -1);
1496 		if ((tmr->type != SCTP_TIMER_TYPE_ASOCKILL) &&
1497 		    ((stcb->asoc.state == 0) ||
1498 		    (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) {
1499 			SCTP_TCB_UNLOCK(stcb);
1500 			if (inp) {
1501 				SCTP_INP_DECR_REF(inp);
1502 			}
1503 			return;
1504 		}
1505 	}
1506 	/* record in stopped what t-o occured */
1507 	tmr->stopped_from = tmr->type;
1508 
1509 	/* mark as being serviced now */
1510 	if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
1511 		/*
1512 		 * Callout has been rescheduled.
1513 		 */
1514 		goto get_out;
1515 	}
1516 	if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1517 		/*
1518 		 * Not active, so no action.
1519 		 */
1520 		goto get_out;
1521 	}
1522 	SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);
1523 
1524 	/* call the handler for the appropriate timer type */
1525 	switch (tmr->type) {
1526 	case SCTP_TIMER_TYPE_ZERO_COPY:
1527 		if (inp == NULL) {
1528 			break;
1529 		}
1530 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) {
1531 			SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket);
1532 		}
1533 		break;
1534 	case SCTP_TIMER_TYPE_ZCOPY_SENDQ:
1535 		if (inp == NULL) {
1536 			break;
1537 		}
1538 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) {
1539 			SCTP_ZERO_COPY_SENDQ_EVENT(inp, inp->sctp_socket);
1540 		}
1541 		break;
1542 	case SCTP_TIMER_TYPE_ADDR_WQ:
1543 		sctp_handle_addr_wq();
1544 		break;
1545 	case SCTP_TIMER_TYPE_ITERATOR:
1546 		SCTP_STAT_INCR(sctps_timoiterator);
1547 		sctp_iterator_timer(it);
1548 		break;
1549 	case SCTP_TIMER_TYPE_SEND:
1550 		if ((stcb == NULL) || (inp == NULL)) {
1551 			break;
1552 		}
1553 		SCTP_STAT_INCR(sctps_timodata);
1554 		stcb->asoc.timodata++;
1555 		stcb->asoc.num_send_timers_up--;
1556 		if (stcb->asoc.num_send_timers_up < 0) {
1557 			stcb->asoc.num_send_timers_up = 0;
1558 		}
1559 		SCTP_TCB_LOCK_ASSERT(stcb);
1560 		cur_oerr = stcb->asoc.overall_error_count;
1561 		retcode = sctp_t3rxt_timer(inp, stcb, net);
1562 		if (retcode) {
1563 			/* no need to unlock on tcb its gone */
1564 
1565 			goto out_decr;
1566 		}
1567 		SCTP_TCB_LOCK_ASSERT(stcb);
1568 #ifdef SCTP_AUDITING_ENABLED
1569 		sctp_auditing(4, inp, stcb, net);
1570 #endif
1571 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1572 		if ((stcb->asoc.num_send_timers_up == 0) &&
1573 		    (stcb->asoc.sent_queue_cnt > 0)
1574 		    ) {
1575 			struct sctp_tmit_chunk *chk;
1576 
1577 			/*
1578 			 * safeguard. If there on some on the sent queue
1579 			 * somewhere but no timers running something is
1580 			 * wrong... so we start a timer on the first chunk
1581 			 * on the send queue on whatever net it is sent to.
1582 			 */
1583 			chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
1584 			sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb,
1585 			    chk->whoTo);
1586 		}
1587 		break;
1588 	case SCTP_TIMER_TYPE_INIT:
1589 		if ((stcb == NULL) || (inp == NULL)) {
1590 			break;
1591 		}
1592 		SCTP_STAT_INCR(sctps_timoinit);
1593 		stcb->asoc.timoinit++;
1594 		if (sctp_t1init_timer(inp, stcb, net)) {
1595 			/* no need to unlock on tcb its gone */
1596 			goto out_decr;
1597 		}
1598 		/* We do output but not here */
1599 		did_output = 0;
1600 		break;
1601 	case SCTP_TIMER_TYPE_RECV:
1602 		if ((stcb == NULL) || (inp == NULL)) {
1603 			break;
1604 		} {
1605 			int abort_flag;
1606 
1607 			SCTP_STAT_INCR(sctps_timosack);
1608 			stcb->asoc.timosack++;
1609 			if (stcb->asoc.cumulative_tsn != stcb->asoc.highest_tsn_inside_map)
1610 				sctp_sack_check(stcb, 0, 0, &abort_flag);
1611 			sctp_send_sack(stcb);
1612 		}
1613 #ifdef SCTP_AUDITING_ENABLED
1614 		sctp_auditing(4, inp, stcb, net);
1615 #endif
1616 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED);
1617 		break;
1618 	case SCTP_TIMER_TYPE_SHUTDOWN:
1619 		if ((stcb == NULL) || (inp == NULL)) {
1620 			break;
1621 		}
1622 		if (sctp_shutdown_timer(inp, stcb, net)) {
1623 			/* no need to unlock on tcb its gone */
1624 			goto out_decr;
1625 		}
1626 		SCTP_STAT_INCR(sctps_timoshutdown);
1627 		stcb->asoc.timoshutdown++;
1628 #ifdef SCTP_AUDITING_ENABLED
1629 		sctp_auditing(4, inp, stcb, net);
1630 #endif
1631 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_NOT_LOCKED);
1632 		break;
1633 	case SCTP_TIMER_TYPE_HEARTBEAT:
1634 		{
1635 			struct sctp_nets *lnet;
1636 			int cnt_of_unconf = 0;
1637 
1638 			if ((stcb == NULL) || (inp == NULL)) {
1639 				break;
1640 			}
1641 			SCTP_STAT_INCR(sctps_timoheartbeat);
1642 			stcb->asoc.timoheartbeat++;
1643 			TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
1644 				if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1645 				    (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
1646 					cnt_of_unconf++;
1647 				}
1648 			}
1649 			if (cnt_of_unconf == 0) {
1650 				if (sctp_heartbeat_timer(inp, stcb, lnet,
1651 				    cnt_of_unconf)) {
1652 					/* no need to unlock on tcb its gone */
1653 					goto out_decr;
1654 				}
1655 			}
1656 #ifdef SCTP_AUDITING_ENABLED
1657 			sctp_auditing(4, inp, stcb, lnet);
1658 #endif
1659 			sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT,
1660 			    stcb->sctp_ep, stcb, lnet);
1661 			sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED);
1662 		}
1663 		break;
1664 	case SCTP_TIMER_TYPE_COOKIE:
1665 		if ((stcb == NULL) || (inp == NULL)) {
1666 			break;
1667 		}
1668 		if (sctp_cookie_timer(inp, stcb, net)) {
1669 			/* no need to unlock on tcb its gone */
1670 			goto out_decr;
1671 		}
1672 		SCTP_STAT_INCR(sctps_timocookie);
1673 		stcb->asoc.timocookie++;
1674 #ifdef SCTP_AUDITING_ENABLED
1675 		sctp_auditing(4, inp, stcb, net);
1676 #endif
1677 		/*
1678 		 * We consider T3 and Cookie timer pretty much the same with
1679 		 * respect to where from in chunk_output.
1680 		 */
1681 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1682 		break;
1683 	case SCTP_TIMER_TYPE_NEWCOOKIE:
1684 		{
1685 			struct timeval tv;
1686 			int i, secret;
1687 
1688 			if (inp == NULL) {
1689 				break;
1690 			}
1691 			SCTP_STAT_INCR(sctps_timosecret);
1692 			(void)SCTP_GETTIME_TIMEVAL(&tv);
1693 			SCTP_INP_WLOCK(inp);
1694 			inp->sctp_ep.time_of_secret_change = tv.tv_sec;
1695 			inp->sctp_ep.last_secret_number =
1696 			    inp->sctp_ep.current_secret_number;
1697 			inp->sctp_ep.current_secret_number++;
1698 			if (inp->sctp_ep.current_secret_number >=
1699 			    SCTP_HOW_MANY_SECRETS) {
1700 				inp->sctp_ep.current_secret_number = 0;
1701 			}
1702 			secret = (int)inp->sctp_ep.current_secret_number;
1703 			for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
1704 				inp->sctp_ep.secret_key[secret][i] =
1705 				    sctp_select_initial_TSN(&inp->sctp_ep);
1706 			}
1707 			SCTP_INP_WUNLOCK(inp);
1708 			sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net);
1709 		}
1710 		did_output = 0;
1711 		break;
1712 	case SCTP_TIMER_TYPE_PATHMTURAISE:
1713 		if ((stcb == NULL) || (inp == NULL)) {
1714 			break;
1715 		}
1716 		SCTP_STAT_INCR(sctps_timopathmtu);
1717 		sctp_pathmtu_timer(inp, stcb, net);
1718 		did_output = 0;
1719 		break;
1720 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
1721 		if ((stcb == NULL) || (inp == NULL)) {
1722 			break;
1723 		}
1724 		if (sctp_shutdownack_timer(inp, stcb, net)) {
1725 			/* no need to unlock on tcb its gone */
1726 			goto out_decr;
1727 		}
1728 		SCTP_STAT_INCR(sctps_timoshutdownack);
1729 		stcb->asoc.timoshutdownack++;
1730 #ifdef SCTP_AUDITING_ENABLED
1731 		sctp_auditing(4, inp, stcb, net);
1732 #endif
1733 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_ACK_TMR, SCTP_SO_NOT_LOCKED);
1734 		break;
1735 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
1736 		if ((stcb == NULL) || (inp == NULL)) {
1737 			break;
1738 		}
1739 		SCTP_STAT_INCR(sctps_timoshutdownguard);
1740 		sctp_abort_an_association(inp, stcb,
1741 		    SCTP_SHUTDOWN_GUARD_EXPIRES, NULL, SCTP_SO_NOT_LOCKED);
1742 		/* no need to unlock on tcb its gone */
1743 		goto out_decr;
1744 
1745 	case SCTP_TIMER_TYPE_STRRESET:
1746 		if ((stcb == NULL) || (inp == NULL)) {
1747 			break;
1748 		}
1749 		if (sctp_strreset_timer(inp, stcb, net)) {
1750 			/* no need to unlock on tcb its gone */
1751 			goto out_decr;
1752 		}
1753 		SCTP_STAT_INCR(sctps_timostrmrst);
1754 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_TMR, SCTP_SO_NOT_LOCKED);
1755 		break;
1756 	case SCTP_TIMER_TYPE_EARLYFR:
1757 		/* Need to do FR of things for net */
1758 		if ((stcb == NULL) || (inp == NULL)) {
1759 			break;
1760 		}
1761 		SCTP_STAT_INCR(sctps_timoearlyfr);
1762 		sctp_early_fr_timer(inp, stcb, net);
1763 		break;
1764 	case SCTP_TIMER_TYPE_ASCONF:
1765 		if ((stcb == NULL) || (inp == NULL)) {
1766 			break;
1767 		}
1768 		if (sctp_asconf_timer(inp, stcb, net)) {
1769 			/* no need to unlock on tcb its gone */
1770 			goto out_decr;
1771 		}
1772 		SCTP_STAT_INCR(sctps_timoasconf);
1773 #ifdef SCTP_AUDITING_ENABLED
1774 		sctp_auditing(4, inp, stcb, net);
1775 #endif
1776 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_ASCONF_TMR, SCTP_SO_NOT_LOCKED);
1777 		break;
1778 	case SCTP_TIMER_TYPE_PRIM_DELETED:
1779 		if ((stcb == NULL) || (inp == NULL)) {
1780 			break;
1781 		}
1782 		sctp_delete_prim_timer(inp, stcb, net);
1783 		SCTP_STAT_INCR(sctps_timodelprim);
1784 		break;
1785 
1786 	case SCTP_TIMER_TYPE_AUTOCLOSE:
1787 		if ((stcb == NULL) || (inp == NULL)) {
1788 			break;
1789 		}
1790 		SCTP_STAT_INCR(sctps_timoautoclose);
1791 		sctp_autoclose_timer(inp, stcb, net);
1792 		sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED);
1793 		did_output = 0;
1794 		break;
1795 	case SCTP_TIMER_TYPE_ASOCKILL:
1796 		if ((stcb == NULL) || (inp == NULL)) {
1797 			break;
1798 		}
1799 		SCTP_STAT_INCR(sctps_timoassockill);
1800 		/* Can we free it yet? */
1801 		SCTP_INP_DECR_REF(inp);
1802 		sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
1803 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1804 		so = SCTP_INP_SO(inp);
1805 		atomic_add_int(&stcb->asoc.refcnt, 1);
1806 		SCTP_TCB_UNLOCK(stcb);
1807 		SCTP_SOCKET_LOCK(so, 1);
1808 		SCTP_TCB_LOCK(stcb);
1809 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
1810 #endif
1811 		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
1812 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1813 		SCTP_SOCKET_UNLOCK(so, 1);
1814 #endif
1815 		/*
1816 		 * free asoc, always unlocks (or destroy's) so prevent
1817 		 * duplicate unlock or unlock of a free mtx :-0
1818 		 */
1819 		stcb = NULL;
1820 		goto out_no_decr;
1821 	case SCTP_TIMER_TYPE_INPKILL:
1822 		SCTP_STAT_INCR(sctps_timoinpkill);
1823 		if (inp == NULL) {
1824 			break;
1825 		}
1826 		/*
1827 		 * special case, take away our increment since WE are the
1828 		 * killer
1829 		 */
1830 		SCTP_INP_DECR_REF(inp);
1831 		sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
1832 		sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
1833 		    SCTP_CALLED_DIRECTLY_NOCMPSET);
1834 		goto out_no_decr;
1835 	default:
1836 		SCTPDBG(SCTP_DEBUG_TIMER1, "sctp_timeout_handler:unknown timer %d\n",
1837 		    tmr->type);
1838 		break;
1839 	};
1840 #ifdef SCTP_AUDITING_ENABLED
1841 	sctp_audit_log(0xF1, (uint8_t) tmr->type);
1842 	if (inp)
1843 		sctp_auditing(5, inp, stcb, net);
1844 #endif
1845 	if ((did_output) && stcb) {
1846 		/*
1847 		 * Now we need to clean up the control chunk chain if an
1848 		 * ECNE is on it. It must be marked as UNSENT again so next
1849 		 * call will continue to send it until such time that we get
1850 		 * a CWR, to remove it. It is, however, less likely that we
1851 		 * will find a ecn echo on the chain though.
1852 		 */
1853 		sctp_fix_ecn_echo(&stcb->asoc);
1854 	}
1855 get_out:
1856 	if (stcb) {
1857 		SCTP_TCB_UNLOCK(stcb);
1858 	}
1859 out_decr:
1860 	if (inp) {
1861 		SCTP_INP_DECR_REF(inp);
1862 	}
1863 out_no_decr:
1864 	SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n",
1865 	    tmr->type);
1866 	if (inp) {
1867 	}
1868 }
1869 
1870 void
1871 sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1872     struct sctp_nets *net)
1873 {
1874 	int to_ticks;
1875 	struct sctp_timer *tmr;
1876 
1877 	if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL))
1878 		return;
1879 
1880 	to_ticks = 0;
1881 
1882 	tmr = NULL;
1883 	if (stcb) {
1884 		SCTP_TCB_LOCK_ASSERT(stcb);
1885 	}
1886 	switch (t_type) {
1887 	case SCTP_TIMER_TYPE_ZERO_COPY:
1888 		tmr = &inp->sctp_ep.zero_copy_timer;
1889 		to_ticks = SCTP_ZERO_COPY_TICK_DELAY;
1890 		break;
1891 	case SCTP_TIMER_TYPE_ZCOPY_SENDQ:
1892 		tmr = &inp->sctp_ep.zero_copy_sendq_timer;
1893 		to_ticks = SCTP_ZERO_COPY_SENDQ_TICK_DELAY;
1894 		break;
1895 	case SCTP_TIMER_TYPE_ADDR_WQ:
1896 		/* Only 1 tick away :-) */
1897 		tmr = &sctppcbinfo.addr_wq_timer;
1898 		to_ticks = SCTP_ADDRESS_TICK_DELAY;
1899 		break;
1900 	case SCTP_TIMER_TYPE_ITERATOR:
1901 		{
1902 			struct sctp_iterator *it;
1903 
1904 			it = (struct sctp_iterator *)inp;
1905 			tmr = &it->tmr;
1906 			to_ticks = SCTP_ITERATOR_TICKS;
1907 		}
1908 		break;
1909 	case SCTP_TIMER_TYPE_SEND:
1910 		/* Here we use the RTO timer */
1911 		{
1912 			int rto_val;
1913 
1914 			if ((stcb == NULL) || (net == NULL)) {
1915 				return;
1916 			}
1917 			tmr = &net->rxt_timer;
1918 			if (net->RTO == 0) {
1919 				rto_val = stcb->asoc.initial_rto;
1920 			} else {
1921 				rto_val = net->RTO;
1922 			}
1923 			to_ticks = MSEC_TO_TICKS(rto_val);
1924 		}
1925 		break;
1926 	case SCTP_TIMER_TYPE_INIT:
1927 		/*
1928 		 * Here we use the INIT timer default usually about 1
1929 		 * minute.
1930 		 */
1931 		if ((stcb == NULL) || (net == NULL)) {
1932 			return;
1933 		}
1934 		tmr = &net->rxt_timer;
1935 		if (net->RTO == 0) {
1936 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1937 		} else {
1938 			to_ticks = MSEC_TO_TICKS(net->RTO);
1939 		}
1940 		break;
1941 	case SCTP_TIMER_TYPE_RECV:
1942 		/*
1943 		 * Here we use the Delayed-Ack timer value from the inp
1944 		 * ususually about 200ms.
1945 		 */
1946 		if (stcb == NULL) {
1947 			return;
1948 		}
1949 		tmr = &stcb->asoc.dack_timer;
1950 		to_ticks = MSEC_TO_TICKS(stcb->asoc.delayed_ack);
1951 		break;
1952 	case SCTP_TIMER_TYPE_SHUTDOWN:
1953 		/* Here we use the RTO of the destination. */
1954 		if ((stcb == NULL) || (net == NULL)) {
1955 			return;
1956 		}
1957 		if (net->RTO == 0) {
1958 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1959 		} else {
1960 			to_ticks = MSEC_TO_TICKS(net->RTO);
1961 		}
1962 		tmr = &net->rxt_timer;
1963 		break;
1964 	case SCTP_TIMER_TYPE_HEARTBEAT:
1965 		/*
1966 		 * the net is used here so that we can add in the RTO. Even
1967 		 * though we use a different timer. We also add the HB timer
1968 		 * PLUS a random jitter.
1969 		 */
1970 		if ((inp == NULL) || (stcb == NULL)) {
1971 			return;
1972 		} else {
1973 			uint32_t rndval;
1974 			uint8_t this_random;
1975 			int cnt_of_unconf = 0;
1976 			struct sctp_nets *lnet;
1977 
1978 			TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
1979 				if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1980 				    (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
1981 					cnt_of_unconf++;
1982 				}
1983 			}
1984 			if (cnt_of_unconf) {
1985 				net = lnet = NULL;
1986 				(void)sctp_heartbeat_timer(inp, stcb, lnet, cnt_of_unconf);
1987 			}
1988 			if (stcb->asoc.hb_random_idx > 3) {
1989 				rndval = sctp_select_initial_TSN(&inp->sctp_ep);
1990 				memcpy(stcb->asoc.hb_random_values, &rndval,
1991 				    sizeof(stcb->asoc.hb_random_values));
1992 				stcb->asoc.hb_random_idx = 0;
1993 			}
1994 			this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
1995 			stcb->asoc.hb_random_idx++;
1996 			stcb->asoc.hb_ect_randombit = 0;
1997 			/*
1998 			 * this_random will be 0 - 256 ms RTO is in ms.
1999 			 */
2000 			if ((stcb->asoc.hb_is_disabled) &&
2001 			    (cnt_of_unconf == 0)) {
2002 				return;
2003 			}
2004 			if (net) {
2005 				int delay;
2006 
2007 				delay = stcb->asoc.heart_beat_delay;
2008 				TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
2009 					if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
2010 					    ((lnet->dest_state & SCTP_ADDR_OUT_OF_SCOPE) == 0) &&
2011 					    (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
2012 						delay = 0;
2013 					}
2014 				}
2015 				if (net->RTO == 0) {
2016 					/* Never been checked */
2017 					to_ticks = this_random + stcb->asoc.initial_rto + delay;
2018 				} else {
2019 					/* set rto_val to the ms */
2020 					to_ticks = delay + net->RTO + this_random;
2021 				}
2022 			} else {
2023 				if (cnt_of_unconf) {
2024 					to_ticks = this_random + stcb->asoc.initial_rto;
2025 				} else {
2026 					to_ticks = stcb->asoc.heart_beat_delay + this_random + stcb->asoc.initial_rto;
2027 				}
2028 			}
2029 			/*
2030 			 * Now we must convert the to_ticks that are now in
2031 			 * ms to ticks.
2032 			 */
2033 			to_ticks = MSEC_TO_TICKS(to_ticks);
2034 			tmr = &stcb->asoc.hb_timer;
2035 		}
2036 		break;
2037 	case SCTP_TIMER_TYPE_COOKIE:
2038 		/*
2039 		 * Here we can use the RTO timer from the network since one
2040 		 * RTT was compelete. If a retran happened then we will be
2041 		 * using the RTO initial value.
2042 		 */
2043 		if ((stcb == NULL) || (net == NULL)) {
2044 			return;
2045 		}
2046 		if (net->RTO == 0) {
2047 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
2048 		} else {
2049 			to_ticks = MSEC_TO_TICKS(net->RTO);
2050 		}
2051 		tmr = &net->rxt_timer;
2052 		break;
2053 	case SCTP_TIMER_TYPE_NEWCOOKIE:
2054 		/*
2055 		 * nothing needed but the endpoint here ususually about 60
2056 		 * minutes.
2057 		 */
2058 		if (inp == NULL) {
2059 			return;
2060 		}
2061 		tmr = &inp->sctp_ep.signature_change;
2062 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
2063 		break;
2064 	case SCTP_TIMER_TYPE_ASOCKILL:
2065 		if (stcb == NULL) {
2066 			return;
2067 		}
2068 		tmr = &stcb->asoc.strreset_timer;
2069 		to_ticks = MSEC_TO_TICKS(SCTP_ASOC_KILL_TIMEOUT);
2070 		break;
2071 	case SCTP_TIMER_TYPE_INPKILL:
2072 		/*
2073 		 * The inp is setup to die. We re-use the signature_chage
2074 		 * timer since that has stopped and we are in the GONE
2075 		 * state.
2076 		 */
2077 		if (inp == NULL) {
2078 			return;
2079 		}
2080 		tmr = &inp->sctp_ep.signature_change;
2081 		to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT);
2082 		break;
2083 	case SCTP_TIMER_TYPE_PATHMTURAISE:
2084 		/*
2085 		 * Here we use the value found in the EP for PMTU ususually
2086 		 * about 10 minutes.
2087 		 */
2088 		if ((stcb == NULL) || (inp == NULL)) {
2089 			return;
2090 		}
2091 		if (net == NULL) {
2092 			return;
2093 		}
2094 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
2095 		tmr = &net->pmtu_timer;
2096 		break;
2097 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
2098 		/* Here we use the RTO of the destination */
2099 		if ((stcb == NULL) || (net == NULL)) {
2100 			return;
2101 		}
2102 		if (net->RTO == 0) {
2103 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
2104 		} else {
2105 			to_ticks = MSEC_TO_TICKS(net->RTO);
2106 		}
2107 		tmr = &net->rxt_timer;
2108 		break;
2109 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2110 		/*
2111 		 * Here we use the endpoints shutdown guard timer usually
2112 		 * about 3 minutes.
2113 		 */
2114 		if ((inp == NULL) || (stcb == NULL)) {
2115 			return;
2116 		}
2117 		to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
2118 		tmr = &stcb->asoc.shut_guard_timer;
2119 		break;
2120 	case SCTP_TIMER_TYPE_STRRESET:
2121 		/*
2122 		 * Here the timer comes from the stcb but its value is from
2123 		 * the net's RTO.
2124 		 */
2125 		if ((stcb == NULL) || (net == NULL)) {
2126 			return;
2127 		}
2128 		if (net->RTO == 0) {
2129 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
2130 		} else {
2131 			to_ticks = MSEC_TO_TICKS(net->RTO);
2132 		}
2133 		tmr = &stcb->asoc.strreset_timer;
2134 		break;
2135 
2136 	case SCTP_TIMER_TYPE_EARLYFR:
2137 		{
2138 			unsigned int msec;
2139 
2140 			if ((stcb == NULL) || (net == NULL)) {
2141 				return;
2142 			}
2143 			if (net->flight_size > net->cwnd) {
2144 				/* no need to start */
2145 				return;
2146 			}
2147 			SCTP_STAT_INCR(sctps_earlyfrstart);
2148 			if (net->lastsa == 0) {
2149 				/* Hmm no rtt estimate yet? */
2150 				msec = stcb->asoc.initial_rto >> 2;
2151 			} else {
2152 				msec = ((net->lastsa >> 2) + net->lastsv) >> 1;
2153 			}
2154 			if (msec < sctp_early_fr_msec) {
2155 				msec = sctp_early_fr_msec;
2156 				if (msec < SCTP_MINFR_MSEC_FLOOR) {
2157 					msec = SCTP_MINFR_MSEC_FLOOR;
2158 				}
2159 			}
2160 			to_ticks = MSEC_TO_TICKS(msec);
2161 			tmr = &net->fr_timer;
2162 		}
2163 		break;
2164 	case SCTP_TIMER_TYPE_ASCONF:
2165 		/*
2166 		 * Here the timer comes from the stcb but its value is from
2167 		 * the net's RTO.
2168 		 */
2169 		if ((stcb == NULL) || (net == NULL)) {
2170 			return;
2171 		}
2172 		if (net->RTO == 0) {
2173 			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
2174 		} else {
2175 			to_ticks = MSEC_TO_TICKS(net->RTO);
2176 		}
2177 		tmr = &stcb->asoc.asconf_timer;
2178 		break;
2179 	case SCTP_TIMER_TYPE_PRIM_DELETED:
2180 		if ((stcb == NULL) || (net != NULL)) {
2181 			return;
2182 		}
2183 		to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
2184 		tmr = &stcb->asoc.delete_prim_timer;
2185 		break;
2186 	case SCTP_TIMER_TYPE_AUTOCLOSE:
2187 		if (stcb == NULL) {
2188 			return;
2189 		}
2190 		if (stcb->asoc.sctp_autoclose_ticks == 0) {
2191 			/*
2192 			 * Really an error since stcb is NOT set to
2193 			 * autoclose
2194 			 */
2195 			return;
2196 		}
2197 		to_ticks = stcb->asoc.sctp_autoclose_ticks;
2198 		tmr = &stcb->asoc.autoclose_timer;
2199 		break;
2200 	default:
2201 		SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n",
2202 		    __FUNCTION__, t_type);
2203 		return;
2204 		break;
2205 	};
2206 	if ((to_ticks <= 0) || (tmr == NULL)) {
2207 		SCTPDBG(SCTP_DEBUG_TIMER1, "%s: %d:software error to_ticks:%d tmr:%p not set ??\n",
2208 		    __FUNCTION__, t_type, to_ticks, tmr);
2209 		return;
2210 	}
2211 	if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
2212 		/*
2213 		 * we do NOT allow you to have it already running. if it is
2214 		 * we leave the current one up unchanged
2215 		 */
2216 		return;
2217 	}
2218 	/* At this point we can proceed */
2219 	if (t_type == SCTP_TIMER_TYPE_SEND) {
2220 		stcb->asoc.num_send_timers_up++;
2221 	}
2222 	tmr->stopped_from = 0;
2223 	tmr->type = t_type;
2224 	tmr->ep = (void *)inp;
2225 	tmr->tcb = (void *)stcb;
2226 	tmr->net = (void *)net;
2227 	tmr->self = (void *)tmr;
2228 	tmr->ticks = sctp_get_tick_count();
2229 	(void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
2230 	return;
2231 }
2232 
2233 void
2234 sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2235     struct sctp_nets *net, uint32_t from)
2236 {
2237 	struct sctp_timer *tmr;
2238 
2239 	if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) &&
2240 	    (inp == NULL))
2241 		return;
2242 
2243 	tmr = NULL;
2244 	if (stcb) {
2245 		SCTP_TCB_LOCK_ASSERT(stcb);
2246 	}
2247 	switch (t_type) {
2248 	case SCTP_TIMER_TYPE_ZERO_COPY:
2249 		tmr = &inp->sctp_ep.zero_copy_timer;
2250 		break;
2251 	case SCTP_TIMER_TYPE_ZCOPY_SENDQ:
2252 		tmr = &inp->sctp_ep.zero_copy_sendq_timer;
2253 		break;
2254 	case SCTP_TIMER_TYPE_ADDR_WQ:
2255 		tmr = &sctppcbinfo.addr_wq_timer;
2256 		break;
2257 	case SCTP_TIMER_TYPE_EARLYFR:
2258 		if ((stcb == NULL) || (net == NULL)) {
2259 			return;
2260 		}
2261 		tmr = &net->fr_timer;
2262 		SCTP_STAT_INCR(sctps_earlyfrstop);
2263 		break;
2264 	case SCTP_TIMER_TYPE_ITERATOR:
2265 		{
2266 			struct sctp_iterator *it;
2267 
2268 			it = (struct sctp_iterator *)inp;
2269 			tmr = &it->tmr;
2270 		}
2271 		break;
2272 	case SCTP_TIMER_TYPE_SEND:
2273 		if ((stcb == NULL) || (net == NULL)) {
2274 			return;
2275 		}
2276 		tmr = &net->rxt_timer;
2277 		break;
2278 	case SCTP_TIMER_TYPE_INIT:
2279 		if ((stcb == NULL) || (net == NULL)) {
2280 			return;
2281 		}
2282 		tmr = &net->rxt_timer;
2283 		break;
2284 	case SCTP_TIMER_TYPE_RECV:
2285 		if (stcb == NULL) {
2286 			return;
2287 		}
2288 		tmr = &stcb->asoc.dack_timer;
2289 		break;
2290 	case SCTP_TIMER_TYPE_SHUTDOWN:
2291 		if ((stcb == NULL) || (net == NULL)) {
2292 			return;
2293 		}
2294 		tmr = &net->rxt_timer;
2295 		break;
2296 	case SCTP_TIMER_TYPE_HEARTBEAT:
2297 		if (stcb == NULL) {
2298 			return;
2299 		}
2300 		tmr = &stcb->asoc.hb_timer;
2301 		break;
2302 	case SCTP_TIMER_TYPE_COOKIE:
2303 		if ((stcb == NULL) || (net == NULL)) {
2304 			return;
2305 		}
2306 		tmr = &net->rxt_timer;
2307 		break;
2308 	case SCTP_TIMER_TYPE_NEWCOOKIE:
2309 		/* nothing needed but the endpoint here */
2310 		tmr = &inp->sctp_ep.signature_change;
2311 		/*
2312 		 * We re-use the newcookie timer for the INP kill timer. We
2313 		 * must assure that we do not kill it by accident.
2314 		 */
2315 		break;
2316 	case SCTP_TIMER_TYPE_ASOCKILL:
2317 		/*
2318 		 * Stop the asoc kill timer.
2319 		 */
2320 		if (stcb == NULL) {
2321 			return;
2322 		}
2323 		tmr = &stcb->asoc.strreset_timer;
2324 		break;
2325 
2326 	case SCTP_TIMER_TYPE_INPKILL:
2327 		/*
2328 		 * The inp is setup to die. We re-use the signature_chage
2329 		 * timer since that has stopped and we are in the GONE
2330 		 * state.
2331 		 */
2332 		tmr = &inp->sctp_ep.signature_change;
2333 		break;
2334 	case SCTP_TIMER_TYPE_PATHMTURAISE:
2335 		if ((stcb == NULL) || (net == NULL)) {
2336 			return;
2337 		}
2338 		tmr = &net->pmtu_timer;
2339 		break;
2340 	case SCTP_TIMER_TYPE_SHUTDOWNACK:
2341 		if ((stcb == NULL) || (net == NULL)) {
2342 			return;
2343 		}
2344 		tmr = &net->rxt_timer;
2345 		break;
2346 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2347 		if (stcb == NULL) {
2348 			return;
2349 		}
2350 		tmr = &stcb->asoc.shut_guard_timer;
2351 		break;
2352 	case SCTP_TIMER_TYPE_STRRESET:
2353 		if (stcb == NULL) {
2354 			return;
2355 		}
2356 		tmr = &stcb->asoc.strreset_timer;
2357 		break;
2358 	case SCTP_TIMER_TYPE_ASCONF:
2359 		if (stcb == NULL) {
2360 			return;
2361 		}
2362 		tmr = &stcb->asoc.asconf_timer;
2363 		break;
2364 	case SCTP_TIMER_TYPE_PRIM_DELETED:
2365 		if (stcb == NULL) {
2366 			return;
2367 		}
2368 		tmr = &stcb->asoc.delete_prim_timer;
2369 		break;
2370 	case SCTP_TIMER_TYPE_AUTOCLOSE:
2371 		if (stcb == NULL) {
2372 			return;
2373 		}
2374 		tmr = &stcb->asoc.autoclose_timer;
2375 		break;
2376 	default:
2377 		SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n",
2378 		    __FUNCTION__, t_type);
2379 		break;
2380 	};
2381 	if (tmr == NULL) {
2382 		return;
2383 	}
2384 	if ((tmr->type != t_type) && tmr->type) {
2385 		/*
2386 		 * Ok we have a timer that is under joint use. Cookie timer
2387 		 * per chance with the SEND timer. We therefore are NOT
2388 		 * running the timer that the caller wants stopped.  So just
2389 		 * return.
2390 		 */
2391 		return;
2392 	}
2393 	if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) {
2394 		stcb->asoc.num_send_timers_up--;
2395 		if (stcb->asoc.num_send_timers_up < 0) {
2396 			stcb->asoc.num_send_timers_up = 0;
2397 		}
2398 	}
2399 	tmr->self = NULL;
2400 	tmr->stopped_from = from;
2401 	(void)SCTP_OS_TIMER_STOP(&tmr->timer);
2402 	return;
2403 }
2404 
2405 #ifdef SCTP_USE_ADLER32
2406 static uint32_t
2407 update_adler32(uint32_t adler, uint8_t * buf, int32_t len)
2408 {
2409 	uint32_t s1 = adler & 0xffff;
2410 	uint32_t s2 = (adler >> 16) & 0xffff;
2411 	int n;
2412 
2413 	for (n = 0; n < len; n++, buf++) {
2414 		/* s1 = (s1 + buf[n]) % BASE */
2415 		/* first we add */
2416 		s1 = (s1 + *buf);
2417 		/*
2418 		 * now if we need to, we do a mod by subtracting. It seems a
2419 		 * bit faster since I really will only ever do one subtract
2420 		 * at the MOST, since buf[n] is a max of 255.
2421 		 */
2422 		if (s1 >= SCTP_ADLER32_BASE) {
2423 			s1 -= SCTP_ADLER32_BASE;
2424 		}
2425 		/* s2 = (s2 + s1) % BASE */
2426 		/* first we add */
2427 		s2 = (s2 + s1);
2428 		/*
2429 		 * again, it is more efficent (it seems) to subtract since
2430 		 * the most s2 will ever be is (BASE-1 + BASE-1) in the
2431 		 * worse case. This would then be (2 * BASE) - 2, which will
2432 		 * still only do one subtract. On Intel this is much better
2433 		 * to do this way and avoid the divide. Have not -pg'd on
2434 		 * sparc.
2435 		 */
2436 		if (s2 >= SCTP_ADLER32_BASE) {
2437 			s2 -= SCTP_ADLER32_BASE;
2438 		}
2439 	}
2440 	/* Return the adler32 of the bytes buf[0..len-1] */
2441 	return ((s2 << 16) + s1);
2442 }
2443 
2444 #endif
2445 
2446 
2447 uint32_t
2448 sctp_calculate_len(struct mbuf *m)
2449 {
2450 	uint32_t tlen = 0;
2451 	struct mbuf *at;
2452 
2453 	at = m;
2454 	while (at) {
2455 		tlen += SCTP_BUF_LEN(at);
2456 		at = SCTP_BUF_NEXT(at);
2457 	}
2458 	return (tlen);
2459 }
2460 
2461 #if defined(SCTP_WITH_NO_CSUM)
2462 
2463 uint32_t
2464 sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
2465 {
2466 	/*
2467 	 * given a mbuf chain with a packetheader offset by 'offset'
2468 	 * pointing at a sctphdr (with csum set to 0) go through the chain
2469 	 * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
2470 	 * has a side bonus as it will calculate the total length of the
2471 	 * mbuf chain. Note: if offset is greater than the total mbuf
2472 	 * length, checksum=1, pktlen=0 is returned (ie. no real error code)
2473 	 */
2474 	if (pktlen == NULL)
2475 		return (0);
2476 	*pktlen = sctp_calculate_len(m);
2477 	return (0);
2478 }
2479 
2480 #elif defined(SCTP_USE_INCHKSUM)
2481 
2482 #include <machine/in_cksum.h>
2483 
2484 uint32_t
2485 sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
2486 {
2487 	/*
2488 	 * given a mbuf chain with a packetheader offset by 'offset'
2489 	 * pointing at a sctphdr (with csum set to 0) go through the chain
2490 	 * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
2491 	 * has a side bonus as it will calculate the total length of the
2492 	 * mbuf chain. Note: if offset is greater than the total mbuf
2493 	 * length, checksum=1, pktlen=0 is returned (ie. no real error code)
2494 	 */
2495 	int32_t tlen = 0;
2496 	struct mbuf *at;
2497 	uint32_t the_sum, retsum;
2498 
2499 	at = m;
2500 	while (at) {
2501 		tlen += SCTP_BUF_LEN(at);
2502 		at = SCTP_BUF_NEXT(at);
2503 	}
2504 	the_sum = (uint32_t) (in_cksum_skip(m, tlen, offset));
2505 	if (pktlen != NULL)
2506 		*pktlen = (tlen - offset);
2507 	retsum = htons(the_sum);
2508 	return (the_sum);
2509 }
2510 
2511 #else
2512 
2513 uint32_t
2514 sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
2515 {
2516 	/*
2517 	 * given a mbuf chain with a packetheader offset by 'offset'
2518 	 * pointing at a sctphdr (with csum set to 0) go through the chain
2519 	 * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
2520 	 * has a side bonus as it will calculate the total length of the
2521 	 * mbuf chain. Note: if offset is greater than the total mbuf
2522 	 * length, checksum=1, pktlen=0 is returned (ie. no real error code)
2523 	 */
2524 	int32_t tlen = 0;
2525 
2526 #ifdef SCTP_USE_ADLER32
2527 	uint32_t base = 1L;
2528 
2529 #else
2530 	uint32_t base = 0xffffffff;
2531 
2532 #endif
2533 	struct mbuf *at;
2534 
2535 	at = m;
2536 	/* find the correct mbuf and offset into mbuf */
2537 	while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
2538 		offset -= SCTP_BUF_LEN(at);	/* update remaining offset
2539 						 * left */
2540 		at = SCTP_BUF_NEXT(at);
2541 	}
2542 	while (at != NULL) {
2543 		if ((SCTP_BUF_LEN(at) - offset) > 0) {
2544 #ifdef SCTP_USE_ADLER32
2545 			base = update_adler32(base,
2546 			    (unsigned char *)(SCTP_BUF_AT(at, offset)),
2547 			    (unsigned int)(SCTP_BUF_LEN(at) - offset));
2548 #else
2549 			if ((SCTP_BUF_LEN(at) - offset) < 4) {
2550 				/* Use old method if less than 4 bytes */
2551 				base = old_update_crc32(base,
2552 				    (unsigned char *)(SCTP_BUF_AT(at, offset)),
2553 				    (unsigned int)(SCTP_BUF_LEN(at) - offset));
2554 			} else {
2555 				base = update_crc32(base,
2556 				    (unsigned char *)(SCTP_BUF_AT(at, offset)),
2557 				    (unsigned int)(SCTP_BUF_LEN(at) - offset));
2558 			}
2559 #endif
2560 			tlen += SCTP_BUF_LEN(at) - offset;
2561 			/* we only offset once into the first mbuf */
2562 		}
2563 		if (offset) {
2564 			if (offset < (uint32_t) SCTP_BUF_LEN(at))
2565 				offset = 0;
2566 			else
2567 				offset -= SCTP_BUF_LEN(at);
2568 		}
2569 		at = SCTP_BUF_NEXT(at);
2570 	}
2571 	if (pktlen != NULL) {
2572 		*pktlen = tlen;
2573 	}
2574 #ifdef SCTP_USE_ADLER32
2575 	/* Adler32 */
2576 	base = htonl(base);
2577 #else
2578 	/* CRC-32c */
2579 	base = sctp_csum_finalize(base);
2580 #endif
2581 	return (base);
2582 }
2583 
2584 
2585 #endif
2586 
2587 void
2588 sctp_mtu_size_reset(struct sctp_inpcb *inp,
2589     struct sctp_association *asoc, uint32_t mtu)
2590 {
2591 	/*
2592 	 * Reset the P-MTU size on this association, this involves changing
2593 	 * the asoc MTU, going through ANY chunk+overhead larger than mtu to
2594 	 * allow the DF flag to be cleared.
2595 	 */
2596 	struct sctp_tmit_chunk *chk;
2597 	unsigned int eff_mtu, ovh;
2598 
2599 #ifdef SCTP_PRINT_FOR_B_AND_M
2600 	SCTP_PRINTF("sctp_mtu_size_reset(%p, asoc:%p mtu:%d\n",
2601 	    inp, asoc, mtu);
2602 #endif
2603 	asoc->smallest_mtu = mtu;
2604 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2605 		ovh = SCTP_MIN_OVERHEAD;
2606 	} else {
2607 		ovh = SCTP_MIN_V4_OVERHEAD;
2608 	}
2609 	eff_mtu = mtu - ovh;
2610 	TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
2611 
2612 		if (chk->send_size > eff_mtu) {
2613 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
2614 		}
2615 	}
2616 	TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
2617 		if (chk->send_size > eff_mtu) {
2618 			chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
2619 		}
2620 	}
2621 }
2622 
2623 
2624 /*
2625  * given an association and starting time of the current RTT period return
2626  * RTO in number of msecs net should point to the current network
2627  */
2628 uint32_t
2629 sctp_calculate_rto(struct sctp_tcb *stcb,
2630     struct sctp_association *asoc,
2631     struct sctp_nets *net,
2632     struct timeval *told,
2633     int safe)
2634 {
2635 	/*-
2636 	 * given an association and the starting time of the current RTT
2637 	 * period (in value1/value2) return RTO in number of msecs.
2638 	 */
2639 	int calc_time = 0;
2640 	int o_calctime;
2641 	uint32_t new_rto = 0;
2642 	int first_measure = 0;
2643 	struct timeval now, then, *old;
2644 
2645 	/* Copy it out for sparc64 */
2646 	if (safe == sctp_align_unsafe_makecopy) {
2647 		old = &then;
2648 		memcpy(&then, told, sizeof(struct timeval));
2649 	} else if (safe == sctp_align_safe_nocopy) {
2650 		old = told;
2651 	} else {
2652 		/* error */
2653 		SCTP_PRINTF("Huh, bad rto calc call\n");
2654 		return (0);
2655 	}
2656 	/************************/
2657 	/* 1. calculate new RTT */
2658 	/************************/
2659 	/* get the current time */
2660 	(void)SCTP_GETTIME_TIMEVAL(&now);
2661 	/* compute the RTT value */
2662 	if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
2663 		calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
2664 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
2665 			calc_time += (((u_long)now.tv_usec -
2666 			    (u_long)old->tv_usec) / 1000);
2667 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
2668 			/* Borrow 1,000ms from current calculation */
2669 			calc_time -= 1000;
2670 			/* Add in the slop over */
2671 			calc_time += ((int)now.tv_usec / 1000);
2672 			/* Add in the pre-second ms's */
2673 			calc_time += (((int)1000000 - (int)old->tv_usec) / 1000);
2674 		}
2675 	} else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
2676 		if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
2677 			calc_time = ((u_long)now.tv_usec -
2678 			    (u_long)old->tv_usec) / 1000;
2679 		} else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
2680 			/* impossible .. garbage in nothing out */
2681 			goto calc_rto;
2682 		} else if ((u_long)now.tv_usec == (u_long)old->tv_usec) {
2683 			/*
2684 			 * We have to have 1 usec :-D this must be the
2685 			 * loopback.
2686 			 */
2687 			calc_time = 1;
2688 		} else {
2689 			/* impossible .. garbage in nothing out */
2690 			goto calc_rto;
2691 		}
2692 	} else {
2693 		/* Clock wrapped? */
2694 		goto calc_rto;
2695 	}
2696 	/***************************/
2697 	/* 2. update RTTVAR & SRTT */
2698 	/***************************/
2699 	o_calctime = calc_time;
2700 	/* this is Van Jacobson's integer version */
2701 	if (net->RTO_measured) {
2702 		calc_time -= (net->lastsa >> SCTP_RTT_SHIFT);	/* take away 1/8th when
2703 								 * shift=3 */
2704 		if (sctp_logging_level & SCTP_RTTVAR_LOGGING_ENABLE) {
2705 			rto_logging(net, SCTP_LOG_RTTVAR);
2706 		}
2707 		net->prev_rtt = o_calctime;
2708 		net->lastsa += calc_time;	/* add 7/8th into sa when
2709 						 * shift=3 */
2710 		if (calc_time < 0) {
2711 			calc_time = -calc_time;
2712 		}
2713 		calc_time -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);	/* take away 1/4 when
2714 									 * VAR shift=2 */
2715 		net->lastsv += calc_time;
2716 		if (net->lastsv == 0) {
2717 			net->lastsv = SCTP_CLOCK_GRANULARITY;
2718 		}
2719 	} else {
2720 		/* First RTO measurment */
2721 		net->RTO_measured = 1;
2722 		net->lastsa = calc_time << SCTP_RTT_SHIFT;	/* Multiply by 8 when
2723 								 * shift=3 */
2724 		net->lastsv = calc_time;
2725 		if (net->lastsv == 0) {
2726 			net->lastsv = SCTP_CLOCK_GRANULARITY;
2727 		}
2728 		first_measure = 1;
2729 		net->prev_rtt = o_calctime;
2730 		if (sctp_logging_level & SCTP_RTTVAR_LOGGING_ENABLE) {
2731 			rto_logging(net, SCTP_LOG_INITIAL_RTT);
2732 		}
2733 	}
2734 calc_rto:
2735 	new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
2736 	if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
2737 	    (stcb->asoc.sat_network_lockout == 0)) {
2738 		stcb->asoc.sat_network = 1;
2739 	} else if ((!first_measure) && stcb->asoc.sat_network) {
2740 		stcb->asoc.sat_network = 0;
2741 		stcb->asoc.sat_network_lockout = 1;
2742 	}
2743 	/* bound it, per C6/C7 in Section 5.3.1 */
2744 	if (new_rto < stcb->asoc.minrto) {
2745 		new_rto = stcb->asoc.minrto;
2746 	}
2747 	if (new_rto > stcb->asoc.maxrto) {
2748 		new_rto = stcb->asoc.maxrto;
2749 	}
2750 	/* we are now returning the RTO */
2751 	return (new_rto);
2752 }
2753 
2754 /*
2755  * return a pointer to a contiguous piece of data from the given mbuf chain
2756  * starting at 'off' for 'len' bytes.  If the desired piece spans more than
2757  * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size
2758  * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain.
2759  */
2760 caddr_t
2761 sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr)
2762 {
2763 	uint32_t count;
2764 	uint8_t *ptr;
2765 
2766 	ptr = in_ptr;
2767 	if ((off < 0) || (len <= 0))
2768 		return (NULL);
2769 
2770 	/* find the desired start location */
2771 	while ((m != NULL) && (off > 0)) {
2772 		if (off < SCTP_BUF_LEN(m))
2773 			break;
2774 		off -= SCTP_BUF_LEN(m);
2775 		m = SCTP_BUF_NEXT(m);
2776 	}
2777 	if (m == NULL)
2778 		return (NULL);
2779 
2780 	/* is the current mbuf large enough (eg. contiguous)? */
2781 	if ((SCTP_BUF_LEN(m) - off) >= len) {
2782 		return (mtod(m, caddr_t)+off);
2783 	} else {
2784 		/* else, it spans more than one mbuf, so save a temp copy... */
2785 		while ((m != NULL) && (len > 0)) {
2786 			count = min(SCTP_BUF_LEN(m) - off, len);
2787 			bcopy(mtod(m, caddr_t)+off, ptr, count);
2788 			len -= count;
2789 			ptr += count;
2790 			off = 0;
2791 			m = SCTP_BUF_NEXT(m);
2792 		}
2793 		if ((m == NULL) && (len > 0))
2794 			return (NULL);
2795 		else
2796 			return ((caddr_t)in_ptr);
2797 	}
2798 }
2799 
2800 
2801 
2802 struct sctp_paramhdr *
2803 sctp_get_next_param(struct mbuf *m,
2804     int offset,
2805     struct sctp_paramhdr *pull,
2806     int pull_limit)
2807 {
2808 	/* This just provides a typed signature to Peter's Pull routine */
2809 	return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
2810 	    (uint8_t *) pull));
2811 }
2812 
2813 
2814 int
2815 sctp_add_pad_tombuf(struct mbuf *m, int padlen)
2816 {
2817 	/*
2818 	 * add padlen bytes of 0 filled padding to the end of the mbuf. If
2819 	 * padlen is > 3 this routine will fail.
2820 	 */
2821 	uint8_t *dp;
2822 	int i;
2823 
2824 	if (padlen > 3) {
2825 		SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
2826 		return (ENOBUFS);
2827 	}
2828 	if (padlen <= M_TRAILINGSPACE(m)) {
2829 		/*
2830 		 * The easy way. We hope the majority of the time we hit
2831 		 * here :)
2832 		 */
2833 		dp = (uint8_t *) (mtod(m, caddr_t)+SCTP_BUF_LEN(m));
2834 		SCTP_BUF_LEN(m) += padlen;
2835 	} else {
2836 		/* Hard way we must grow the mbuf */
2837 		struct mbuf *tmp;
2838 
2839 		tmp = sctp_get_mbuf_for_msg(padlen, 0, M_DONTWAIT, 1, MT_DATA);
2840 		if (tmp == NULL) {
2841 			/* Out of space GAK! we are in big trouble. */
2842 			SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
2843 			return (ENOSPC);
2844 		}
2845 		/* setup and insert in middle */
2846 		SCTP_BUF_LEN(tmp) = padlen;
2847 		SCTP_BUF_NEXT(tmp) = NULL;
2848 		SCTP_BUF_NEXT(m) = tmp;
2849 		dp = mtod(tmp, uint8_t *);
2850 	}
2851 	/* zero out the pad */
2852 	for (i = 0; i < padlen; i++) {
2853 		*dp = 0;
2854 		dp++;
2855 	}
2856 	return (0);
2857 }
2858 
2859 int
2860 sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
2861 {
2862 	/* find the last mbuf in chain and pad it */
2863 	struct mbuf *m_at;
2864 
2865 	m_at = m;
2866 	if (last_mbuf) {
2867 		return (sctp_add_pad_tombuf(last_mbuf, padval));
2868 	} else {
2869 		while (m_at) {
2870 			if (SCTP_BUF_NEXT(m_at) == NULL) {
2871 				return (sctp_add_pad_tombuf(m_at, padval));
2872 			}
2873 			m_at = SCTP_BUF_NEXT(m_at);
2874 		}
2875 	}
2876 	SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
2877 	return (EFAULT);
2878 }
2879 
2880 int sctp_asoc_change_wake = 0;
2881 
2882 static void
2883 sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
2884     uint32_t error, void *data, int so_locked
2885 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
2886     SCTP_UNUSED
2887 #endif
2888 )
2889 {
2890 	struct mbuf *m_notify;
2891 	struct sctp_assoc_change *sac;
2892 	struct sctp_queued_to_read *control;
2893 
2894 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2895 	struct socket *so;
2896 
2897 #endif
2898 
2899 	/*
2900 	 * First if we are are going down dump everything we can to the
2901 	 * socket rcv queue.
2902 	 */
2903 
2904 	if ((stcb == NULL) ||
2905 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
2906 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
2907 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)
2908 	    ) {
2909 		/* If the socket is gone we are out of here */
2910 		return;
2911 	}
2912 	/*
2913 	 * For TCP model AND UDP connected sockets we will send an error up
2914 	 * when an ABORT comes in.
2915 	 */
2916 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2917 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
2918 	    ((event == SCTP_COMM_LOST) || (event == SCTP_CANT_STR_ASSOC))) {
2919 		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
2920 			SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
2921 			stcb->sctp_socket->so_error = ECONNREFUSED;
2922 		} else {
2923 			SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
2924 			stcb->sctp_socket->so_error = ECONNRESET;
2925 		}
2926 		/* Wake ANY sleepers */
2927 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2928 		so = SCTP_INP_SO(stcb->sctp_ep);
2929 		if (!so_locked) {
2930 			atomic_add_int(&stcb->asoc.refcnt, 1);
2931 			SCTP_TCB_UNLOCK(stcb);
2932 			SCTP_SOCKET_LOCK(so, 1);
2933 			SCTP_TCB_LOCK(stcb);
2934 			atomic_subtract_int(&stcb->asoc.refcnt, 1);
2935 			if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2936 				SCTP_SOCKET_UNLOCK(so, 1);
2937 				return;
2938 			}
2939 		}
2940 #endif
2941 		sorwakeup(stcb->sctp_socket);
2942 		sowwakeup(stcb->sctp_socket);
2943 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2944 		if (!so_locked) {
2945 			SCTP_SOCKET_UNLOCK(so, 1);
2946 		}
2947 #endif
2948 		sctp_asoc_change_wake++;
2949 	}
2950 	if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
2951 		/* event not enabled */
2952 		return;
2953 	}
2954 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_change), 0, M_DONTWAIT, 1, MT_DATA);
2955 	if (m_notify == NULL)
2956 		/* no space left */
2957 		return;
2958 	SCTP_BUF_LEN(m_notify) = 0;
2959 
2960 	sac = mtod(m_notify, struct sctp_assoc_change *);
2961 	sac->sac_type = SCTP_ASSOC_CHANGE;
2962 	sac->sac_flags = 0;
2963 	sac->sac_length = sizeof(struct sctp_assoc_change);
2964 	sac->sac_state = event;
2965 	sac->sac_error = error;
2966 	/* XXX verify these stream counts */
2967 	sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
2968 	sac->sac_inbound_streams = stcb->asoc.streamincnt;
2969 	sac->sac_assoc_id = sctp_get_associd(stcb);
2970 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_change);
2971 	SCTP_BUF_NEXT(m_notify) = NULL;
2972 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
2973 	    0, 0, 0, 0, 0, 0,
2974 	    m_notify);
2975 	if (control == NULL) {
2976 		/* no memory */
2977 		sctp_m_freem(m_notify);
2978 		return;
2979 	}
2980 	control->length = SCTP_BUF_LEN(m_notify);
2981 	/* not that we need this */
2982 	control->tail_mbuf = m_notify;
2983 	control->spec_flags = M_NOTIFICATION;
2984 	sctp_add_to_readq(stcb->sctp_ep, stcb,
2985 	    control,
2986 	    &stcb->sctp_socket->so_rcv, 1, so_locked);
2987 	if (event == SCTP_COMM_LOST) {
2988 		/* Wake up any sleeper */
2989 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2990 		so = SCTP_INP_SO(stcb->sctp_ep);
2991 		if (!so_locked) {
2992 			atomic_add_int(&stcb->asoc.refcnt, 1);
2993 			SCTP_TCB_UNLOCK(stcb);
2994 			SCTP_SOCKET_LOCK(so, 1);
2995 			SCTP_TCB_LOCK(stcb);
2996 			atomic_subtract_int(&stcb->asoc.refcnt, 1);
2997 			if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2998 				SCTP_SOCKET_UNLOCK(so, 1);
2999 				return;
3000 			}
3001 		}
3002 #endif
3003 		sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
3004 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3005 		if (!so_locked) {
3006 			SCTP_SOCKET_UNLOCK(so, 1);
3007 		}
3008 #endif
3009 	}
3010 }
3011 
3012 static void
3013 sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
3014     struct sockaddr *sa, uint32_t error)
3015 {
3016 	struct mbuf *m_notify;
3017 	struct sctp_paddr_change *spc;
3018 	struct sctp_queued_to_read *control;
3019 
3020 	if ((stcb == NULL) || (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVPADDREVNT)))
3021 		/* event not enabled */
3022 		return;
3023 
3024 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_DONTWAIT, 1, MT_DATA);
3025 	if (m_notify == NULL)
3026 		return;
3027 	SCTP_BUF_LEN(m_notify) = 0;
3028 	spc = mtod(m_notify, struct sctp_paddr_change *);
3029 	spc->spc_type = SCTP_PEER_ADDR_CHANGE;
3030 	spc->spc_flags = 0;
3031 	spc->spc_length = sizeof(struct sctp_paddr_change);
3032 	if (sa->sa_family == AF_INET) {
3033 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3034 	} else {
3035 		struct sockaddr_in6 *sin6;
3036 
3037 		memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
3038 
3039 		sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
3040 		if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3041 			if (sin6->sin6_scope_id == 0) {
3042 				/* recover scope_id for user */
3043 				(void)sa6_recoverscope(sin6);
3044 			} else {
3045 				/* clear embedded scope_id for user */
3046 				in6_clearscope(&sin6->sin6_addr);
3047 			}
3048 		}
3049 	}
3050 	spc->spc_state = state;
3051 	spc->spc_error = error;
3052 	spc->spc_assoc_id = sctp_get_associd(stcb);
3053 
3054 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change);
3055 	SCTP_BUF_NEXT(m_notify) = NULL;
3056 
3057 	/* append to socket */
3058 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3059 	    0, 0, 0, 0, 0, 0,
3060 	    m_notify);
3061 	if (control == NULL) {
3062 		/* no memory */
3063 		sctp_m_freem(m_notify);
3064 		return;
3065 	}
3066 	control->length = SCTP_BUF_LEN(m_notify);
3067 	control->spec_flags = M_NOTIFICATION;
3068 	/* not that we need this */
3069 	control->tail_mbuf = m_notify;
3070 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3071 	    control,
3072 	    &stcb->sctp_socket->so_rcv, 1, SCTP_SO_NOT_LOCKED);
3073 }
3074 
3075 
3076 static void
3077 sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
3078     struct sctp_tmit_chunk *chk, int so_locked
3079 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3080     SCTP_UNUSED
3081 #endif
3082 )
3083 {
3084 	struct mbuf *m_notify;
3085 	struct sctp_send_failed *ssf;
3086 	struct sctp_queued_to_read *control;
3087 	int length;
3088 
3089 	if ((stcb == NULL) || (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)))
3090 		/* event not enabled */
3091 		return;
3092 
3093 	length = sizeof(struct sctp_send_failed) + chk->send_size;
3094 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
3095 	if (m_notify == NULL)
3096 		/* no space left */
3097 		return;
3098 	SCTP_BUF_LEN(m_notify) = 0;
3099 	ssf = mtod(m_notify, struct sctp_send_failed *);
3100 	ssf->ssf_type = SCTP_SEND_FAILED;
3101 	if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
3102 		ssf->ssf_flags = SCTP_DATA_UNSENT;
3103 	else
3104 		ssf->ssf_flags = SCTP_DATA_SENT;
3105 	ssf->ssf_length = length;
3106 	ssf->ssf_error = error;
3107 	/* not exactly what the user sent in, but should be close :) */
3108 	bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
3109 	ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
3110 	ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
3111 	ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
3112 	ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
3113 	ssf->ssf_info.sinfo_context = chk->rec.data.context;
3114 	ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3115 	ssf->ssf_assoc_id = sctp_get_associd(stcb);
3116 	SCTP_BUF_NEXT(m_notify) = chk->data;
3117 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
3118 
3119 	/* Steal off the mbuf */
3120 	chk->data = NULL;
3121 	/*
3122 	 * For this case, we check the actual socket buffer, since the assoc
3123 	 * is going away we don't want to overfill the socket buffer for a
3124 	 * non-reader
3125 	 */
3126 	if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3127 		sctp_m_freem(m_notify);
3128 		return;
3129 	}
3130 	/* append to socket */
3131 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3132 	    0, 0, 0, 0, 0, 0,
3133 	    m_notify);
3134 	if (control == NULL) {
3135 		/* no memory */
3136 		sctp_m_freem(m_notify);
3137 		return;
3138 	}
3139 	control->spec_flags = M_NOTIFICATION;
3140 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3141 	    control,
3142 	    &stcb->sctp_socket->so_rcv, 1, so_locked);
3143 }
3144 
3145 
3146 static void
3147 sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
3148     struct sctp_stream_queue_pending *sp, int so_locked
3149 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3150     SCTP_UNUSED
3151 #endif
3152 )
3153 {
3154 	struct mbuf *m_notify;
3155 	struct sctp_send_failed *ssf;
3156 	struct sctp_queued_to_read *control;
3157 	int length;
3158 
3159 	if ((stcb == NULL) || (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)))
3160 		/* event not enabled */
3161 		return;
3162 
3163 	length = sizeof(struct sctp_send_failed) + sp->length;
3164 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
3165 	if (m_notify == NULL)
3166 		/* no space left */
3167 		return;
3168 	SCTP_BUF_LEN(m_notify) = 0;
3169 	ssf = mtod(m_notify, struct sctp_send_failed *);
3170 	ssf->ssf_type = SCTP_SEND_FAILED;
3171 	if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
3172 		ssf->ssf_flags = SCTP_DATA_UNSENT;
3173 	else
3174 		ssf->ssf_flags = SCTP_DATA_SENT;
3175 	ssf->ssf_length = length;
3176 	ssf->ssf_error = error;
3177 	/* not exactly what the user sent in, but should be close :) */
3178 	bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
3179 	ssf->ssf_info.sinfo_stream = sp->stream;
3180 	ssf->ssf_info.sinfo_ssn = sp->strseq;
3181 	ssf->ssf_info.sinfo_flags = sp->sinfo_flags;
3182 	ssf->ssf_info.sinfo_ppid = sp->ppid;
3183 	ssf->ssf_info.sinfo_context = sp->context;
3184 	ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3185 	ssf->ssf_assoc_id = sctp_get_associd(stcb);
3186 	SCTP_BUF_NEXT(m_notify) = sp->data;
3187 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
3188 
3189 	/* Steal off the mbuf */
3190 	sp->data = NULL;
3191 	/*
3192 	 * For this case, we check the actual socket buffer, since the assoc
3193 	 * is going away we don't want to overfill the socket buffer for a
3194 	 * non-reader
3195 	 */
3196 	if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3197 		sctp_m_freem(m_notify);
3198 		return;
3199 	}
3200 	/* append to socket */
3201 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3202 	    0, 0, 0, 0, 0, 0,
3203 	    m_notify);
3204 	if (control == NULL) {
3205 		/* no memory */
3206 		sctp_m_freem(m_notify);
3207 		return;
3208 	}
3209 	control->spec_flags = M_NOTIFICATION;
3210 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3211 	    control,
3212 	    &stcb->sctp_socket->so_rcv, 1, so_locked);
3213 }
3214 
3215 
3216 
3217 static void
3218 sctp_notify_adaptation_layer(struct sctp_tcb *stcb,
3219     uint32_t error)
3220 {
3221 	struct mbuf *m_notify;
3222 	struct sctp_adaptation_event *sai;
3223 	struct sctp_queued_to_read *control;
3224 
3225 	if ((stcb == NULL) || (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_ADAPTATIONEVNT)))
3226 		/* event not enabled */
3227 		return;
3228 
3229 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_DONTWAIT, 1, MT_DATA);
3230 	if (m_notify == NULL)
3231 		/* no space left */
3232 		return;
3233 	SCTP_BUF_LEN(m_notify) = 0;
3234 	sai = mtod(m_notify, struct sctp_adaptation_event *);
3235 	sai->sai_type = SCTP_ADAPTATION_INDICATION;
3236 	sai->sai_flags = 0;
3237 	sai->sai_length = sizeof(struct sctp_adaptation_event);
3238 	sai->sai_adaptation_ind = stcb->asoc.peers_adaptation;
3239 	sai->sai_assoc_id = sctp_get_associd(stcb);
3240 
3241 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event);
3242 	SCTP_BUF_NEXT(m_notify) = NULL;
3243 
3244 	/* append to socket */
3245 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3246 	    0, 0, 0, 0, 0, 0,
3247 	    m_notify);
3248 	if (control == NULL) {
3249 		/* no memory */
3250 		sctp_m_freem(m_notify);
3251 		return;
3252 	}
3253 	control->length = SCTP_BUF_LEN(m_notify);
3254 	control->spec_flags = M_NOTIFICATION;
3255 	/* not that we need this */
3256 	control->tail_mbuf = m_notify;
3257 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3258 	    control,
3259 	    &stcb->sctp_socket->so_rcv, 1, SCTP_SO_NOT_LOCKED);
3260 }
3261 
3262 /* This always must be called with the read-queue LOCKED in the INP */
3263 void
3264 sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
3265     int nolock, uint32_t val)
3266 {
3267 	struct mbuf *m_notify;
3268 	struct sctp_pdapi_event *pdapi;
3269 	struct sctp_queued_to_read *control;
3270 	struct sockbuf *sb;
3271 
3272 	if ((stcb == NULL) || (stcb->sctp_socket == NULL) ||
3273 	    sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_PDAPIEVNT))
3274 		/* event not enabled */
3275 		return;
3276 
3277 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_DONTWAIT, 1, MT_DATA);
3278 	if (m_notify == NULL)
3279 		/* no space left */
3280 		return;
3281 	SCTP_BUF_LEN(m_notify) = 0;
3282 	pdapi = mtod(m_notify, struct sctp_pdapi_event *);
3283 	pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
3284 	pdapi->pdapi_flags = 0;
3285 	pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
3286 	pdapi->pdapi_indication = error;
3287 	pdapi->pdapi_stream = (val >> 16);
3288 	pdapi->pdapi_seq = (val & 0x0000ffff);
3289 	pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
3290 
3291 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
3292 	SCTP_BUF_NEXT(m_notify) = NULL;
3293 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3294 	    0, 0, 0, 0, 0, 0,
3295 	    m_notify);
3296 	if (control == NULL) {
3297 		/* no memory */
3298 		sctp_m_freem(m_notify);
3299 		return;
3300 	}
3301 	control->spec_flags = M_NOTIFICATION;
3302 	control->length = SCTP_BUF_LEN(m_notify);
3303 	/* not that we need this */
3304 	control->tail_mbuf = m_notify;
3305 	control->held_length = 0;
3306 	control->length = 0;
3307 	if (nolock == 0) {
3308 		SCTP_INP_READ_LOCK(stcb->sctp_ep);
3309 	}
3310 	sb = &stcb->sctp_socket->so_rcv;
3311 	if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
3312 		sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify));
3313 	}
3314 	sctp_sballoc(stcb, sb, m_notify);
3315 	if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
3316 		sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
3317 	}
3318 	atomic_add_int(&control->length, SCTP_BUF_LEN(m_notify));
3319 	control->end_added = 1;
3320 	if (stcb->asoc.control_pdapi)
3321 		TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next);
3322 	else {
3323 		/* we really should not see this case */
3324 		TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next);
3325 	}
3326 	if (nolock == 0) {
3327 		SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
3328 	}
3329 	if (stcb->sctp_ep && stcb->sctp_socket) {
3330 		/* This should always be the case */
3331 		sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
3332 	}
3333 }
3334 
3335 static void
3336 sctp_notify_shutdown_event(struct sctp_tcb *stcb)
3337 {
3338 	struct mbuf *m_notify;
3339 	struct sctp_shutdown_event *sse;
3340 	struct sctp_queued_to_read *control;
3341 
3342 	/*
3343 	 * For TCP model AND UDP connected sockets we will send an error up
3344 	 * when an SHUTDOWN completes
3345 	 */
3346 	if (stcb == NULL) {
3347 		return;
3348 	}
3349 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3350 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
3351 		/* mark socket closed for read/write and wakeup! */
3352 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3353 		struct socket *so;
3354 
3355 		so = SCTP_INP_SO(stcb->sctp_ep);
3356 		atomic_add_int(&stcb->asoc.refcnt, 1);
3357 		SCTP_TCB_UNLOCK(stcb);
3358 		SCTP_SOCKET_LOCK(so, 1);
3359 		SCTP_TCB_LOCK(stcb);
3360 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
3361 		if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3362 			SCTP_SOCKET_UNLOCK(so, 1);
3363 			return;
3364 		}
3365 #endif
3366 		socantsendmore(stcb->sctp_socket);
3367 		socantrcvmore(stcb->sctp_socket);
3368 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3369 		SCTP_SOCKET_UNLOCK(so, 1);
3370 #endif
3371 	}
3372 	if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
3373 		/* event not enabled */
3374 		return;
3375 
3376 	m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_DONTWAIT, 1, MT_DATA);
3377 	if (m_notify == NULL)
3378 		/* no space left */
3379 		return;
3380 	sse = mtod(m_notify, struct sctp_shutdown_event *);
3381 	sse->sse_type = SCTP_SHUTDOWN_EVENT;
3382 	sse->sse_flags = 0;
3383 	sse->sse_length = sizeof(struct sctp_shutdown_event);
3384 	sse->sse_assoc_id = sctp_get_associd(stcb);
3385 
3386 	SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event);
3387 	SCTP_BUF_NEXT(m_notify) = NULL;
3388 
3389 	/* append to socket */
3390 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3391 	    0, 0, 0, 0, 0, 0,
3392 	    m_notify);
3393 	if (control == NULL) {
3394 		/* no memory */
3395 		sctp_m_freem(m_notify);
3396 		return;
3397 	}
3398 	control->spec_flags = M_NOTIFICATION;
3399 	control->length = SCTP_BUF_LEN(m_notify);
3400 	/* not that we need this */
3401 	control->tail_mbuf = m_notify;
3402 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3403 	    control,
3404 	    &stcb->sctp_socket->so_rcv, 1, SCTP_SO_NOT_LOCKED);
3405 }
3406 
3407 static void
3408 sctp_notify_stream_reset(struct sctp_tcb *stcb,
3409     int number_entries, uint16_t * list, int flag)
3410 {
3411 	struct mbuf *m_notify;
3412 	struct sctp_queued_to_read *control;
3413 	struct sctp_stream_reset_event *strreset;
3414 	int len;
3415 
3416 	if (stcb == NULL) {
3417 		return;
3418 	}
3419 	if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
3420 		/* event not enabled */
3421 		return;
3422 
3423 	m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
3424 	if (m_notify == NULL)
3425 		/* no space left */
3426 		return;
3427 	SCTP_BUF_LEN(m_notify) = 0;
3428 	len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
3429 	if (len > M_TRAILINGSPACE(m_notify)) {
3430 		/* never enough room */
3431 		sctp_m_freem(m_notify);
3432 		return;
3433 	}
3434 	strreset = mtod(m_notify, struct sctp_stream_reset_event *);
3435 	strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
3436 	if (number_entries == 0) {
3437 		strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
3438 	} else {
3439 		strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
3440 	}
3441 	strreset->strreset_length = len;
3442 	strreset->strreset_assoc_id = sctp_get_associd(stcb);
3443 	if (number_entries) {
3444 		int i;
3445 
3446 		for (i = 0; i < number_entries; i++) {
3447 			strreset->strreset_list[i] = ntohs(list[i]);
3448 		}
3449 	}
3450 	SCTP_BUF_LEN(m_notify) = len;
3451 	SCTP_BUF_NEXT(m_notify) = NULL;
3452 	if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3453 		/* no space */
3454 		sctp_m_freem(m_notify);
3455 		return;
3456 	}
3457 	/* append to socket */
3458 	control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3459 	    0, 0, 0, 0, 0, 0,
3460 	    m_notify);
3461 	if (control == NULL) {
3462 		/* no memory */
3463 		sctp_m_freem(m_notify);
3464 		return;
3465 	}
3466 	control->spec_flags = M_NOTIFICATION;
3467 	control->length = SCTP_BUF_LEN(m_notify);
3468 	/* not that we need this */
3469 	control->tail_mbuf = m_notify;
3470 	sctp_add_to_readq(stcb->sctp_ep, stcb,
3471 	    control,
3472 	    &stcb->sctp_socket->so_rcv, 1, SCTP_SO_NOT_LOCKED);
3473 }
3474 
3475 
3476 void
3477 sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
3478     uint32_t error, void *data, int so_locked
3479 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3480     SCTP_UNUSED
3481 #endif
3482 )
3483 {
3484 	if (stcb == NULL) {
3485 		/* unlikely but */
3486 		return;
3487 	}
3488 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
3489 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
3490 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)
3491 	    ) {
3492 		/* No notifications up when we are in a no socket state */
3493 		return;
3494 	}
3495 	if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3496 		/* Can't send up to a closed socket any notifications */
3497 		return;
3498 	}
3499 	if (stcb && ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
3500 	    (stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED))) {
3501 		if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
3502 		    (notification == SCTP_NOTIFY_INTERFACE_UP) ||
3503 		    (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
3504 			/* Don't report these in front states */
3505 			return;
3506 		}
3507 	}
3508 	switch (notification) {
3509 	case SCTP_NOTIFY_ASSOC_UP:
3510 		if (stcb->asoc.assoc_up_sent == 0) {
3511 			sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, so_locked);
3512 			stcb->asoc.assoc_up_sent = 1;
3513 		}
3514 		if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
3515 			sctp_notify_adaptation_layer(stcb, error);
3516 		}
3517 		break;
3518 	case SCTP_NOTIFY_ASSOC_DOWN:
3519 		sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, so_locked);
3520 		break;
3521 	case SCTP_NOTIFY_INTERFACE_DOWN:
3522 		{
3523 			struct sctp_nets *net;
3524 
3525 			net = (struct sctp_nets *)data;
3526 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
3527 			    (struct sockaddr *)&net->ro._l_addr, error);
3528 			break;
3529 		}
3530 	case SCTP_NOTIFY_INTERFACE_UP:
3531 		{
3532 			struct sctp_nets *net;
3533 
3534 			net = (struct sctp_nets *)data;
3535 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
3536 			    (struct sockaddr *)&net->ro._l_addr, error);
3537 			break;
3538 		}
3539 	case SCTP_NOTIFY_INTERFACE_CONFIRMED:
3540 		{
3541 			struct sctp_nets *net;
3542 
3543 			net = (struct sctp_nets *)data;
3544 			sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
3545 			    (struct sockaddr *)&net->ro._l_addr, error);
3546 			break;
3547 		}
3548 	case SCTP_NOTIFY_SPECIAL_SP_FAIL:
3549 		sctp_notify_send_failed2(stcb, error,
3550 		    (struct sctp_stream_queue_pending *)data, so_locked);
3551 		break;
3552 	case SCTP_NOTIFY_DG_FAIL:
3553 		sctp_notify_send_failed(stcb, error,
3554 		    (struct sctp_tmit_chunk *)data, so_locked);
3555 		break;
3556 	case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
3557 		{
3558 			uint32_t val;
3559 
3560 			val = *((uint32_t *) data);
3561 
3562 			sctp_notify_partial_delivery_indication(stcb, error, 0, val);
3563 		}
3564 		break;
3565 	case SCTP_NOTIFY_STRDATA_ERR:
3566 		break;
3567 	case SCTP_NOTIFY_ASSOC_ABORTED:
3568 		if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
3569 		    ((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
3570 			sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, NULL, so_locked);
3571 		} else {
3572 			sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, NULL, so_locked);
3573 		}
3574 		break;
3575 	case SCTP_NOTIFY_PEER_OPENED_STREAM:
3576 		break;
3577 	case SCTP_NOTIFY_STREAM_OPENED_OK:
3578 		break;
3579 	case SCTP_NOTIFY_ASSOC_RESTART:
3580 		sctp_notify_assoc_change(SCTP_RESTART, stcb, error, data, so_locked);
3581 		break;
3582 	case SCTP_NOTIFY_HB_RESP:
3583 		break;
3584 	case SCTP_NOTIFY_STR_RESET_SEND:
3585 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STRRESET_OUTBOUND_STR);
3586 		break;
3587 	case SCTP_NOTIFY_STR_RESET_RECV:
3588 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STRRESET_INBOUND_STR);
3589 		break;
3590 	case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
3591 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), (SCTP_STRRESET_OUTBOUND_STR | SCTP_STRRESET_FAILED));
3592 		break;
3593 
3594 	case SCTP_NOTIFY_STR_RESET_FAILED_IN:
3595 		sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), (SCTP_STRRESET_INBOUND_STR | SCTP_STRRESET_FAILED));
3596 		break;
3597 
3598 	case SCTP_NOTIFY_ASCONF_ADD_IP:
3599 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
3600 		    error);
3601 		break;
3602 	case SCTP_NOTIFY_ASCONF_DELETE_IP:
3603 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
3604 		    error);
3605 		break;
3606 	case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
3607 		sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
3608 		    error);
3609 		break;
3610 	case SCTP_NOTIFY_ASCONF_SUCCESS:
3611 		break;
3612 	case SCTP_NOTIFY_ASCONF_FAILED:
3613 		break;
3614 	case SCTP_NOTIFY_PEER_SHUTDOWN:
3615 		sctp_notify_shutdown_event(stcb);
3616 		break;
3617 	case SCTP_NOTIFY_AUTH_NEW_KEY:
3618 		sctp_notify_authentication(stcb, SCTP_AUTH_NEWKEY, error,
3619 		    (uint16_t) (uintptr_t) data);
3620 		break;
3621 #if 0
3622 	case SCTP_NOTIFY_AUTH_KEY_CONFLICT:
3623 		sctp_notify_authentication(stcb, SCTP_AUTH_KEY_CONFLICT,
3624 		    error, (uint16_t) (uintptr_t) data);
3625 		break;
3626 #endif				/* not yet? remove? */
3627 
3628 
3629 	default:
3630 		SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n",
3631 		    __FUNCTION__, notification, notification);
3632 		break;
3633 	}			/* end switch */
3634 }
3635 
3636 void
3637 sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
3638 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3639     SCTP_UNUSED
3640 #endif
3641 )
3642 {
3643 	struct sctp_association *asoc;
3644 	struct sctp_stream_out *outs;
3645 	struct sctp_tmit_chunk *chk;
3646 	struct sctp_stream_queue_pending *sp;
3647 	int i;
3648 
3649 	asoc = &stcb->asoc;
3650 
3651 	if (stcb == NULL) {
3652 		return;
3653 	}
3654 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
3655 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
3656 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
3657 		return;
3658 	}
3659 	/* now through all the gunk freeing chunks */
3660 	if (holds_lock == 0) {
3661 		SCTP_TCB_SEND_LOCK(stcb);
3662 	}
3663 	/* sent queue SHOULD be empty */
3664 	if (!TAILQ_EMPTY(&asoc->sent_queue)) {
3665 		chk = TAILQ_FIRST(&asoc->sent_queue);
3666 		while (chk) {
3667 			TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
3668 			asoc->sent_queue_cnt--;
3669 			if (chk->data) {
3670 				/*
3671 				 * trim off the sctp chunk header(it should
3672 				 * be there)
3673 				 */
3674 				if (chk->send_size >= sizeof(struct sctp_data_chunk)) {
3675 					m_adj(chk->data, sizeof(struct sctp_data_chunk));
3676 					sctp_mbuf_crush(chk->data);
3677 					chk->send_size -= sizeof(struct sctp_data_chunk);
3678 				}
3679 			}
3680 			sctp_free_bufspace(stcb, asoc, chk, 1);
3681 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
3682 			    SCTP_NOTIFY_DATAGRAM_SENT, chk, so_locked);
3683 			if (chk->data) {
3684 				sctp_m_freem(chk->data);
3685 				chk->data = NULL;
3686 			}
3687 			sctp_free_a_chunk(stcb, chk);
3688 			/* sa_ignore FREED_MEMORY */
3689 			chk = TAILQ_FIRST(&asoc->sent_queue);
3690 		}
3691 	}
3692 	/* pending send queue SHOULD be empty */
3693 	if (!TAILQ_EMPTY(&asoc->send_queue)) {
3694 		chk = TAILQ_FIRST(&asoc->send_queue);
3695 		while (chk) {
3696 			TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
3697 			asoc->send_queue_cnt--;
3698 			if (chk->data) {
3699 				/*
3700 				 * trim off the sctp chunk header(it should
3701 				 * be there)
3702 				 */
3703 				if (chk->send_size >= sizeof(struct sctp_data_chunk)) {
3704 					m_adj(chk->data, sizeof(struct sctp_data_chunk));
3705 					sctp_mbuf_crush(chk->data);
3706 					chk->send_size -= sizeof(struct sctp_data_chunk);
3707 				}
3708 			}
3709 			sctp_free_bufspace(stcb, asoc, chk, 1);
3710 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk, so_locked);
3711 			if (chk->data) {
3712 				sctp_m_freem(chk->data);
3713 				chk->data = NULL;
3714 			}
3715 			sctp_free_a_chunk(stcb, chk);
3716 			/* sa_ignore FREED_MEMORY */
3717 			chk = TAILQ_FIRST(&asoc->send_queue);
3718 		}
3719 	}
3720 	for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
3721 		/* For each stream */
3722 		outs = &stcb->asoc.strmout[i];
3723 		/* clean up any sends there */
3724 		stcb->asoc.locked_on_sending = NULL;
3725 		sp = TAILQ_FIRST(&outs->outqueue);
3726 		while (sp) {
3727 			stcb->asoc.stream_queue_cnt--;
3728 			TAILQ_REMOVE(&outs->outqueue, sp, next);
3729 			sctp_free_spbufspace(stcb, asoc, sp);
3730 			sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
3731 			    SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp, so_locked);
3732 			if (sp->data) {
3733 				sctp_m_freem(sp->data);
3734 				sp->data = NULL;
3735 			}
3736 			if (sp->net)
3737 				sctp_free_remote_addr(sp->net);
3738 			sp->net = NULL;
3739 			/* Free the chunk */
3740 			sctp_free_a_strmoq(stcb, sp);
3741 			/* sa_ignore FREED_MEMORY */
3742 			sp = TAILQ_FIRST(&outs->outqueue);
3743 		}
3744 	}
3745 
3746 	if (holds_lock == 0) {
3747 		SCTP_TCB_SEND_UNLOCK(stcb);
3748 	}
3749 }
3750 
3751 void
3752 sctp_abort_notification(struct sctp_tcb *stcb, int error, int so_locked
3753 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3754     SCTP_UNUSED
3755 #endif
3756 )
3757 {
3758 
3759 	if (stcb == NULL) {
3760 		return;
3761 	}
3762 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
3763 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
3764 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
3765 		return;
3766 	}
3767 	/* Tell them we lost the asoc */
3768 	sctp_report_all_outbound(stcb, 1, so_locked);
3769 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
3770 	    ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
3771 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
3772 		stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
3773 	}
3774 	sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL, so_locked);
3775 }
3776 
3777 void
3778 sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
3779     struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err,
3780     uint32_t vrf_id)
3781 {
3782 	uint32_t vtag;
3783 
3784 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3785 	struct socket *so;
3786 
3787 #endif
3788 
3789 	vtag = 0;
3790 	if (stcb != NULL) {
3791 		/* We have a TCB to abort, send notification too */
3792 		vtag = stcb->asoc.peer_vtag;
3793 		sctp_abort_notification(stcb, 0, SCTP_SO_NOT_LOCKED);
3794 		/* get the assoc vrf id and table id */
3795 		vrf_id = stcb->asoc.vrf_id;
3796 		stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
3797 	}
3798 	sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id);
3799 	if (stcb != NULL) {
3800 		/* Ok, now lets free it */
3801 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3802 		so = SCTP_INP_SO(inp);
3803 		atomic_add_int(&stcb->asoc.refcnt, 1);
3804 		SCTP_TCB_UNLOCK(stcb);
3805 		SCTP_SOCKET_LOCK(so, 1);
3806 		SCTP_TCB_LOCK(stcb);
3807 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
3808 #endif
3809 		(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
3810 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3811 		SCTP_SOCKET_UNLOCK(so, 1);
3812 #endif
3813 	} else {
3814 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
3815 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
3816 				sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
3817 				    SCTP_CALLED_DIRECTLY_NOCMPSET);
3818 			}
3819 		}
3820 	}
3821 }
3822 
3823 #ifdef SCTP_ASOCLOG_OF_TSNS
3824 void
3825 sctp_print_out_track_log(struct sctp_tcb *stcb)
3826 {
3827 #ifdef NOSIY_PRINTS
3828 	int i;
3829 
3830 	SCTP_PRINTF("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code);
3831 	SCTP_PRINTF("IN bound TSN log-aaa\n");
3832 	if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) {
3833 		SCTP_PRINTF("None rcvd\n");
3834 		goto none_in;
3835 	}
3836 	if (stcb->asoc.tsn_in_wrapped) {
3837 		for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) {
3838 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
3839 			    stcb->asoc.in_tsnlog[i].tsn,
3840 			    stcb->asoc.in_tsnlog[i].strm,
3841 			    stcb->asoc.in_tsnlog[i].seq,
3842 			    stcb->asoc.in_tsnlog[i].flgs,
3843 			    stcb->asoc.in_tsnlog[i].sz);
3844 		}
3845 	}
3846 	if (stcb->asoc.tsn_in_at) {
3847 		for (i = 0; i < stcb->asoc.tsn_in_at; i++) {
3848 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
3849 			    stcb->asoc.in_tsnlog[i].tsn,
3850 			    stcb->asoc.in_tsnlog[i].strm,
3851 			    stcb->asoc.in_tsnlog[i].seq,
3852 			    stcb->asoc.in_tsnlog[i].flgs,
3853 			    stcb->asoc.in_tsnlog[i].sz);
3854 		}
3855 	}
3856 none_in:
3857 	SCTP_PRINTF("OUT bound TSN log-aaa\n");
3858 	if ((stcb->asoc.tsn_out_at == 0) &&
3859 	    (stcb->asoc.tsn_out_wrapped == 0)) {
3860 		SCTP_PRINTF("None sent\n");
3861 	}
3862 	if (stcb->asoc.tsn_out_wrapped) {
3863 		for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) {
3864 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
3865 			    stcb->asoc.out_tsnlog[i].tsn,
3866 			    stcb->asoc.out_tsnlog[i].strm,
3867 			    stcb->asoc.out_tsnlog[i].seq,
3868 			    stcb->asoc.out_tsnlog[i].flgs,
3869 			    stcb->asoc.out_tsnlog[i].sz);
3870 		}
3871 	}
3872 	if (stcb->asoc.tsn_out_at) {
3873 		for (i = 0; i < stcb->asoc.tsn_out_at; i++) {
3874 			SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
3875 			    stcb->asoc.out_tsnlog[i].tsn,
3876 			    stcb->asoc.out_tsnlog[i].strm,
3877 			    stcb->asoc.out_tsnlog[i].seq,
3878 			    stcb->asoc.out_tsnlog[i].flgs,
3879 			    stcb->asoc.out_tsnlog[i].sz);
3880 		}
3881 	}
3882 #endif
3883 }
3884 
3885 #endif
3886 
3887 void
3888 sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
3889     int error, struct mbuf *op_err,
3890     int so_locked
3891 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3892     SCTP_UNUSED
3893 #endif
3894 )
3895 {
3896 	uint32_t vtag;
3897 
3898 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3899 	struct socket *so;
3900 
3901 #endif
3902 
3903 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3904 	so = SCTP_INP_SO(inp);
3905 #endif
3906 	if (stcb == NULL) {
3907 		/* Got to have a TCB */
3908 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
3909 			if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
3910 				sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
3911 				    SCTP_CALLED_DIRECTLY_NOCMPSET);
3912 			}
3913 		}
3914 		return;
3915 	} else {
3916 		stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
3917 	}
3918 	vtag = stcb->asoc.peer_vtag;
3919 	/* notify the ulp */
3920 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
3921 		sctp_abort_notification(stcb, error, so_locked);
3922 	/* notify the peer */
3923 #if defined(SCTP_PANIC_ON_ABORT)
3924 	panic("aborting an association");
3925 #endif
3926 	sctp_send_abort_tcb(stcb, op_err, so_locked);
3927 	SCTP_STAT_INCR_COUNTER32(sctps_aborted);
3928 	if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
3929 	    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
3930 		SCTP_STAT_DECR_GAUGE32(sctps_currestab);
3931 	}
3932 	/* now free the asoc */
3933 #ifdef SCTP_ASOCLOG_OF_TSNS
3934 	sctp_print_out_track_log(stcb);
3935 #endif
3936 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3937 	if (!so_locked) {
3938 		atomic_add_int(&stcb->asoc.refcnt, 1);
3939 		SCTP_TCB_UNLOCK(stcb);
3940 		SCTP_SOCKET_LOCK(so, 1);
3941 		SCTP_TCB_LOCK(stcb);
3942 		atomic_subtract_int(&stcb->asoc.refcnt, 1);
3943 	}
3944 #endif
3945 	(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
3946 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3947 	if (!so_locked) {
3948 		SCTP_SOCKET_UNLOCK(so, 1);
3949 	}
3950 #endif
3951 }
3952 
3953 void
3954 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
3955     struct sctp_inpcb *inp, struct mbuf *op_err, uint32_t vrf_id)
3956 {
3957 	struct sctp_chunkhdr *ch, chunk_buf;
3958 	unsigned int chk_length;
3959 
3960 	SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
3961 	/* Generate a TO address for future reference */
3962 	if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
3963 		if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
3964 			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
3965 			    SCTP_CALLED_DIRECTLY_NOCMPSET);
3966 		}
3967 	}
3968 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
3969 	    sizeof(*ch), (uint8_t *) & chunk_buf);
3970 	while (ch != NULL) {
3971 		chk_length = ntohs(ch->chunk_length);
3972 		if (chk_length < sizeof(*ch)) {
3973 			/* break to abort land */
3974 			break;
3975 		}
3976 		switch (ch->chunk_type) {
3977 		case SCTP_COOKIE_ECHO:
3978 			/* We hit here only if the assoc is being freed */
3979 			return;
3980 		case SCTP_PACKET_DROPPED:
3981 			/* we don't respond to pkt-dropped */
3982 			return;
3983 		case SCTP_ABORT_ASSOCIATION:
3984 			/* we don't respond with an ABORT to an ABORT */
3985 			return;
3986 		case SCTP_SHUTDOWN_COMPLETE:
3987 			/*
3988 			 * we ignore it since we are not waiting for it and
3989 			 * peer is gone
3990 			 */
3991 			return;
3992 		case SCTP_SHUTDOWN_ACK:
3993 			sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id);
3994 			return;
3995 		default:
3996 			break;
3997 		}
3998 		offset += SCTP_SIZE32(chk_length);
3999 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4000 		    sizeof(*ch), (uint8_t *) & chunk_buf);
4001 	}
4002 	sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id);
4003 }
4004 
4005 /*
4006  * check the inbound datagram to make sure there is not an abort inside it,
4007  * if there is return 1, else return 0.
4008  */
4009 int
4010 sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t * vtagfill)
4011 {
4012 	struct sctp_chunkhdr *ch;
4013 	struct sctp_init_chunk *init_chk, chunk_buf;
4014 	int offset;
4015 	unsigned int chk_length;
4016 
4017 	offset = iphlen + sizeof(struct sctphdr);
4018 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
4019 	    (uint8_t *) & chunk_buf);
4020 	while (ch != NULL) {
4021 		chk_length = ntohs(ch->chunk_length);
4022 		if (chk_length < sizeof(*ch)) {
4023 			/* packet is probably corrupt */
4024 			break;
4025 		}
4026 		/* we seem to be ok, is it an abort? */
4027 		if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
4028 			/* yep, tell them */
4029 			return (1);
4030 		}
4031 		if (ch->chunk_type == SCTP_INITIATION) {
4032 			/* need to update the Vtag */
4033 			init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
4034 			    offset, sizeof(*init_chk), (uint8_t *) & chunk_buf);
4035 			if (init_chk != NULL) {
4036 				*vtagfill = ntohl(init_chk->init.initiate_tag);
4037 			}
4038 		}
4039 		/* Nope, move to the next chunk */
4040 		offset += SCTP_SIZE32(chk_length);
4041 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4042 		    sizeof(*ch), (uint8_t *) & chunk_buf);
4043 	}
4044 	return (0);
4045 }
4046 
4047 /*
4048  * currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id
4049  * set (i.e. it's 0) so, create this function to compare link local scopes
4050  */
4051 uint32_t
4052 sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2)
4053 {
4054 	struct sockaddr_in6 a, b;
4055 
4056 	/* save copies */
4057 	a = *addr1;
4058 	b = *addr2;
4059 
4060 	if (a.sin6_scope_id == 0)
4061 		if (sa6_recoverscope(&a)) {
4062 			/* can't get scope, so can't match */
4063 			return (0);
4064 		}
4065 	if (b.sin6_scope_id == 0)
4066 		if (sa6_recoverscope(&b)) {
4067 			/* can't get scope, so can't match */
4068 			return (0);
4069 		}
4070 	if (a.sin6_scope_id != b.sin6_scope_id)
4071 		return (0);
4072 
4073 	return (1);
4074 }
4075 
4076 /*
4077  * returns a sockaddr_in6 with embedded scope recovered and removed
4078  */
4079 struct sockaddr_in6 *
4080 sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
4081 {
4082 	/* check and strip embedded scope junk */
4083 	if (addr->sin6_family == AF_INET6) {
4084 		if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
4085 			if (addr->sin6_scope_id == 0) {
4086 				*store = *addr;
4087 				if (!sa6_recoverscope(store)) {
4088 					/* use the recovered scope */
4089 					addr = store;
4090 				}
4091 			} else {
4092 				/* else, return the original "to" addr */
4093 				in6_clearscope(&addr->sin6_addr);
4094 			}
4095 		}
4096 	}
4097 	return (addr);
4098 }
4099 
4100 /*
4101  * are the two addresses the same?  currently a "scopeless" check returns: 1
4102  * if same, 0 if not
4103  */
4104 int
4105 sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
4106 {
4107 
4108 	/* must be valid */
4109 	if (sa1 == NULL || sa2 == NULL)
4110 		return (0);
4111 
4112 	/* must be the same family */
4113 	if (sa1->sa_family != sa2->sa_family)
4114 		return (0);
4115 
4116 	if (sa1->sa_family == AF_INET6) {
4117 		/* IPv6 addresses */
4118 		struct sockaddr_in6 *sin6_1, *sin6_2;
4119 
4120 		sin6_1 = (struct sockaddr_in6 *)sa1;
4121 		sin6_2 = (struct sockaddr_in6 *)sa2;
4122 		return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
4123 		    &sin6_2->sin6_addr));
4124 	} else if (sa1->sa_family == AF_INET) {
4125 		/* IPv4 addresses */
4126 		struct sockaddr_in *sin_1, *sin_2;
4127 
4128 		sin_1 = (struct sockaddr_in *)sa1;
4129 		sin_2 = (struct sockaddr_in *)sa2;
4130 		return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
4131 	} else {
4132 		/* we don't do these... */
4133 		return (0);
4134 	}
4135 }
4136 
4137 void
4138 sctp_print_address(struct sockaddr *sa)
4139 {
4140 	char ip6buf[INET6_ADDRSTRLEN];
4141 
4142 	ip6buf[0] = 0;
4143 	if (sa->sa_family == AF_INET6) {
4144 		struct sockaddr_in6 *sin6;
4145 
4146 		sin6 = (struct sockaddr_in6 *)sa;
4147 		SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
4148 		    ip6_sprintf(ip6buf, &sin6->sin6_addr),
4149 		    ntohs(sin6->sin6_port),
4150 		    sin6->sin6_scope_id);
4151 	} else if (sa->sa_family == AF_INET) {
4152 		struct sockaddr_in *sin;
4153 		unsigned char *p;
4154 
4155 		sin = (struct sockaddr_in *)sa;
4156 		p = (unsigned char *)&sin->sin_addr;
4157 		SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n",
4158 		    p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
4159 	} else {
4160 		SCTP_PRINTF("?\n");
4161 	}
4162 }
4163 
4164 void
4165 sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
4166 {
4167 	if (iph->ip_v == IPVERSION) {
4168 		struct sockaddr_in lsa, fsa;
4169 
4170 		bzero(&lsa, sizeof(lsa));
4171 		lsa.sin_len = sizeof(lsa);
4172 		lsa.sin_family = AF_INET;
4173 		lsa.sin_addr = iph->ip_src;
4174 		lsa.sin_port = sh->src_port;
4175 		bzero(&fsa, sizeof(fsa));
4176 		fsa.sin_len = sizeof(fsa);
4177 		fsa.sin_family = AF_INET;
4178 		fsa.sin_addr = iph->ip_dst;
4179 		fsa.sin_port = sh->dest_port;
4180 		SCTP_PRINTF("src: ");
4181 		sctp_print_address((struct sockaddr *)&lsa);
4182 		SCTP_PRINTF("dest: ");
4183 		sctp_print_address((struct sockaddr *)&fsa);
4184 	} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
4185 		struct ip6_hdr *ip6;
4186 		struct sockaddr_in6 lsa6, fsa6;
4187 
4188 		ip6 = (struct ip6_hdr *)iph;
4189 		bzero(&lsa6, sizeof(lsa6));
4190 		lsa6.sin6_len = sizeof(lsa6);
4191 		lsa6.sin6_family = AF_INET6;
4192 		lsa6.sin6_addr = ip6->ip6_src;
4193 		lsa6.sin6_port = sh->src_port;
4194 		bzero(&fsa6, sizeof(fsa6));
4195 		fsa6.sin6_len = sizeof(fsa6);
4196 		fsa6.sin6_family = AF_INET6;
4197 		fsa6.sin6_addr = ip6->ip6_dst;
4198 		fsa6.sin6_port = sh->dest_port;
4199 		SCTP_PRINTF("src: ");
4200 		sctp_print_address((struct sockaddr *)&lsa6);
4201 		SCTP_PRINTF("dest: ");
4202 		sctp_print_address((struct sockaddr *)&fsa6);
4203 	}
4204 }
4205 
4206 void
4207 sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
4208     struct sctp_inpcb *new_inp,
4209     struct sctp_tcb *stcb,
4210     int waitflags)
4211 {
4212 	/*
4213 	 * go through our old INP and pull off any control structures that
4214 	 * belong to stcb and move then to the new inp.
4215 	 */
4216 	struct socket *old_so, *new_so;
4217 	struct sctp_queued_to_read *control, *nctl;
4218 	struct sctp_readhead tmp_queue;
4219 	struct mbuf *m;
4220 	int error = 0;
4221 
4222 	old_so = old_inp->sctp_socket;
4223 	new_so = new_inp->sctp_socket;
4224 	TAILQ_INIT(&tmp_queue);
4225 	error = sblock(&old_so->so_rcv, waitflags);
4226 	if (error) {
4227 		/*
4228 		 * Gak, can't get sblock, we have a problem. data will be
4229 		 * left stranded.. and we don't dare look at it since the
4230 		 * other thread may be reading something. Oh well, its a
4231 		 * screwed up app that does a peeloff OR a accept while
4232 		 * reading from the main socket... actually its only the
4233 		 * peeloff() case, since I think read will fail on a
4234 		 * listening socket..
4235 		 */
4236 		return;
4237 	}
4238 	/* lock the socket buffers */
4239 	SCTP_INP_READ_LOCK(old_inp);
4240 	control = TAILQ_FIRST(&old_inp->read_queue);
4241 	/* Pull off all for out target stcb */
4242 	while (control) {
4243 		nctl = TAILQ_NEXT(control, next);
4244 		if (control->stcb == stcb) {
4245 			/* remove it we want it */
4246 			TAILQ_REMOVE(&old_inp->read_queue, control, next);
4247 			TAILQ_INSERT_TAIL(&tmp_queue, control, next);
4248 			m = control->data;
4249 			while (m) {
4250 				if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4251 					sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
4252 				}
4253 				sctp_sbfree(control, stcb, &old_so->so_rcv, m);
4254 				if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4255 					sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
4256 				}
4257 				m = SCTP_BUF_NEXT(m);
4258 			}
4259 		}
4260 		control = nctl;
4261 	}
4262 	SCTP_INP_READ_UNLOCK(old_inp);
4263 	/* Remove the sb-lock on the old socket */
4264 
4265 	sbunlock(&old_so->so_rcv);
4266 	/* Now we move them over to the new socket buffer */
4267 	control = TAILQ_FIRST(&tmp_queue);
4268 	SCTP_INP_READ_LOCK(new_inp);
4269 	while (control) {
4270 		nctl = TAILQ_NEXT(control, next);
4271 		TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next);
4272 		m = control->data;
4273 		while (m) {
4274 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4275 				sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
4276 			}
4277 			sctp_sballoc(stcb, &new_so->so_rcv, m);
4278 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4279 				sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
4280 			}
4281 			m = SCTP_BUF_NEXT(m);
4282 		}
4283 		control = nctl;
4284 	}
4285 	SCTP_INP_READ_UNLOCK(new_inp);
4286 }
4287 
4288 
4289 void
4290 sctp_add_to_readq(struct sctp_inpcb *inp,
4291     struct sctp_tcb *stcb,
4292     struct sctp_queued_to_read *control,
4293     struct sockbuf *sb,
4294     int end,
4295     int so_locked
4296 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4297     SCTP_UNUSED
4298 #endif
4299 )
4300 {
4301 	/*
4302 	 * Here we must place the control on the end of the socket read
4303 	 * queue AND increment sb_cc so that select will work properly on
4304 	 * read.
4305 	 */
4306 	struct mbuf *m, *prev = NULL;
4307 
4308 	if (inp == NULL) {
4309 		/* Gak, TSNH!! */
4310 #ifdef INVARIANTS
4311 		panic("Gak, inp NULL on add_to_readq");
4312 #endif
4313 		return;
4314 	}
4315 	SCTP_INP_READ_LOCK(inp);
4316 	if (!(control->spec_flags & M_NOTIFICATION)) {
4317 		atomic_add_int(&inp->total_recvs, 1);
4318 		if (!control->do_not_ref_stcb) {
4319 			atomic_add_int(&stcb->total_recvs, 1);
4320 		}
4321 	}
4322 	m = control->data;
4323 	control->held_length = 0;
4324 	control->length = 0;
4325 	while (m) {
4326 		if (SCTP_BUF_LEN(m) == 0) {
4327 			/* Skip mbufs with NO length */
4328 			if (prev == NULL) {
4329 				/* First one */
4330 				control->data = sctp_m_free(m);
4331 				m = control->data;
4332 			} else {
4333 				SCTP_BUF_NEXT(prev) = sctp_m_free(m);
4334 				m = SCTP_BUF_NEXT(prev);
4335 			}
4336 			if (m == NULL) {
4337 				control->tail_mbuf = prev;;
4338 			}
4339 			continue;
4340 		}
4341 		prev = m;
4342 		if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4343 			sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
4344 		}
4345 		sctp_sballoc(stcb, sb, m);
4346 		if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4347 			sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
4348 		}
4349 		atomic_add_int(&control->length, SCTP_BUF_LEN(m));
4350 		m = SCTP_BUF_NEXT(m);
4351 	}
4352 	if (prev != NULL) {
4353 		control->tail_mbuf = prev;
4354 	} else {
4355 		/* Everything got collapsed out?? */
4356 		return;
4357 	}
4358 	if (end) {
4359 		control->end_added = 1;
4360 	}
4361 	TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
4362 	SCTP_INP_READ_UNLOCK(inp);
4363 	if (inp && inp->sctp_socket) {
4364 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) {
4365 			SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket);
4366 		} else {
4367 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4368 			struct socket *so;
4369 
4370 			so = SCTP_INP_SO(inp);
4371 			if (!so_locked) {
4372 				atomic_add_int(&stcb->asoc.refcnt, 1);
4373 				SCTP_TCB_UNLOCK(stcb);
4374 				SCTP_SOCKET_LOCK(so, 1);
4375 				SCTP_TCB_LOCK(stcb);
4376 				atomic_subtract_int(&stcb->asoc.refcnt, 1);
4377 				if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
4378 					SCTP_SOCKET_UNLOCK(so, 1);
4379 					return;
4380 				}
4381 			}
4382 #endif
4383 			sctp_sorwakeup(inp, inp->sctp_socket);
4384 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4385 			if (!so_locked) {
4386 				SCTP_SOCKET_UNLOCK(so, 1);
4387 			}
4388 #endif
4389 		}
4390 	}
4391 }
4392 
4393 
4394 int
4395 sctp_append_to_readq(struct sctp_inpcb *inp,
4396     struct sctp_tcb *stcb,
4397     struct sctp_queued_to_read *control,
4398     struct mbuf *m,
4399     int end,
4400     int ctls_cumack,
4401     struct sockbuf *sb)
4402 {
4403 	/*
4404 	 * A partial delivery API event is underway. OR we are appending on
4405 	 * the reassembly queue.
4406 	 *
4407 	 * If PDAPI this means we need to add m to the end of the data.
4408 	 * Increase the length in the control AND increment the sb_cc.
4409 	 * Otherwise sb is NULL and all we need to do is put it at the end
4410 	 * of the mbuf chain.
4411 	 */
4412 	int len = 0;
4413 	struct mbuf *mm, *tail = NULL, *prev = NULL;
4414 
4415 	if (inp) {
4416 		SCTP_INP_READ_LOCK(inp);
4417 	}
4418 	if (control == NULL) {
4419 get_out:
4420 		if (inp) {
4421 			SCTP_INP_READ_UNLOCK(inp);
4422 		}
4423 		return (-1);
4424 	}
4425 	if (control->end_added) {
4426 		/* huh this one is complete? */
4427 		goto get_out;
4428 	}
4429 	mm = m;
4430 	if (mm == NULL) {
4431 		goto get_out;
4432 	}
4433 	while (mm) {
4434 		if (SCTP_BUF_LEN(mm) == 0) {
4435 			/* Skip mbufs with NO lenght */
4436 			if (prev == NULL) {
4437 				/* First one */
4438 				m = sctp_m_free(mm);
4439 				mm = m;
4440 			} else {
4441 				SCTP_BUF_NEXT(prev) = sctp_m_free(mm);
4442 				mm = SCTP_BUF_NEXT(prev);
4443 			}
4444 			continue;
4445 		}
4446 		prev = mm;
4447 		len += SCTP_BUF_LEN(mm);
4448 		if (sb) {
4449 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4450 				sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(mm));
4451 			}
4452 			sctp_sballoc(stcb, sb, mm);
4453 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
4454 				sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
4455 			}
4456 		}
4457 		mm = SCTP_BUF_NEXT(mm);
4458 	}
4459 	if (prev) {
4460 		tail = prev;
4461 	} else {
4462 		/* Really there should always be a prev */
4463 		if (m == NULL) {
4464 			/* Huh nothing left? */
4465 #ifdef INVARIANTS
4466 			panic("Nothing left to add?");
4467 #else
4468 			goto get_out;
4469 #endif
4470 		}
4471 		tail = m;
4472 	}
4473 	if (control->tail_mbuf) {
4474 		/* append */
4475 		SCTP_BUF_NEXT(control->tail_mbuf) = m;
4476 		control->tail_mbuf = tail;
4477 	} else {
4478 		/* nothing there */
4479 #ifdef INVARIANTS
4480 		if (control->data != NULL) {
4481 			panic("This should NOT happen");
4482 		}
4483 #endif
4484 		control->data = m;
4485 		control->tail_mbuf = tail;
4486 	}
4487 	atomic_add_int(&control->length, len);
4488 	if (end) {
4489 		/* message is complete */
4490 		if (stcb && (control == stcb->asoc.control_pdapi)) {
4491 			stcb->asoc.control_pdapi = NULL;
4492 		}
4493 		control->held_length = 0;
4494 		control->end_added = 1;
4495 	}
4496 	if (stcb == NULL) {
4497 		control->do_not_ref_stcb = 1;
4498 	}
4499 	/*
4500 	 * When we are appending in partial delivery, the cum-ack is used
4501 	 * for the actual pd-api highest tsn on this mbuf. The true cum-ack
4502 	 * is populated in the outbound sinfo structure from the true cumack
4503 	 * if the association exists...
4504 	 */
4505 	control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack;
4506 	if (inp) {
4507 		SCTP_INP_READ_UNLOCK(inp);
4508 	}
4509 	if (inp && inp->sctp_socket) {
4510 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) {
4511 			SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket);
4512 		} else {
4513 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4514 			struct socket *so;
4515 
4516 			so = SCTP_INP_SO(inp);
4517 			atomic_add_int(&stcb->asoc.refcnt, 1);
4518 			SCTP_TCB_UNLOCK(stcb);
4519 			SCTP_SOCKET_LOCK(so, 1);
4520 			SCTP_TCB_LOCK(stcb);
4521 			atomic_subtract_int(&stcb->asoc.refcnt, 1);
4522 			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
4523 				SCTP_SOCKET_UNLOCK(so, 1);
4524 				return (0);
4525 			}
4526 #endif
4527 			sctp_sorwakeup(inp, inp->sctp_socket);
4528 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4529 			SCTP_SOCKET_UNLOCK(so, 1);
4530 #endif
4531 		}
4532 	}
4533 	return (0);
4534 }
4535 
4536 
4537 
4538 /*************HOLD THIS COMMENT FOR PATCH FILE OF
4539  *************ALTERNATE ROUTING CODE
4540  */
4541 
4542 /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
4543  *************ALTERNATE ROUTING CODE
4544  */
4545 
4546 struct mbuf *
4547 sctp_generate_invmanparam(int err)
4548 {
4549 	/* Return a MBUF with a invalid mandatory parameter */
4550 	struct mbuf *m;
4551 
4552 	m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_DONTWAIT, 1, MT_DATA);
4553 	if (m) {
4554 		struct sctp_paramhdr *ph;
4555 
4556 		SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
4557 		ph = mtod(m, struct sctp_paramhdr *);
4558 		ph->param_length = htons(sizeof(struct sctp_paramhdr));
4559 		ph->param_type = htons(err);
4560 	}
4561 	return (m);
4562 }
4563 
4564 #ifdef SCTP_MBCNT_LOGGING
4565 void
4566 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
4567     struct sctp_tmit_chunk *tp1, int chk_cnt)
4568 {
4569 	if (tp1->data == NULL) {
4570 		return;
4571 	}
4572 	asoc->chunks_on_out_queue -= chk_cnt;
4573 	if (sctp_logging_level & SCTP_MBCNT_LOGGING_ENABLE) {
4574 		sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
4575 		    asoc->total_output_queue_size,
4576 		    tp1->book_size,
4577 		    0,
4578 		    tp1->mbcnt);
4579 	}
4580 	if (asoc->total_output_queue_size >= tp1->book_size) {
4581 		atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size);
4582 	} else {
4583 		asoc->total_output_queue_size = 0;
4584 	}
4585 
4586 	if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) ||
4587 	    ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) {
4588 		if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
4589 			stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
4590 		} else {
4591 			stcb->sctp_socket->so_snd.sb_cc = 0;
4592 
4593 		}
4594 	}
4595 }
4596 
4597 #endif
4598 
4599 int
4600 sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
4601     int reason, struct sctpchunk_listhead *queue, int so_locked
4602 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4603     SCTP_UNUSED
4604 #endif
4605 )
4606 {
4607 	int ret_sz = 0;
4608 	int notdone;
4609 	uint8_t foundeom = 0;
4610 
4611 	do {
4612 		ret_sz += tp1->book_size;
4613 		tp1->sent = SCTP_FORWARD_TSN_SKIP;
4614 		if (tp1->data) {
4615 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4616 			struct socket *so;
4617 
4618 #endif
4619 			sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
4620 			sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, SCTP_SO_NOT_LOCKED);
4621 			sctp_m_freem(tp1->data);
4622 			tp1->data = NULL;
4623 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4624 			so = SCTP_INP_SO(stcb->sctp_ep);
4625 			if (!so_locked) {
4626 				atomic_add_int(&stcb->asoc.refcnt, 1);
4627 				SCTP_TCB_UNLOCK(stcb);
4628 				SCTP_SOCKET_LOCK(so, 1);
4629 				SCTP_TCB_LOCK(stcb);
4630 				atomic_subtract_int(&stcb->asoc.refcnt, 1);
4631 				if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
4632 					/*
4633 					 * assoc was freed while we were
4634 					 * unlocked
4635 					 */
4636 					SCTP_SOCKET_UNLOCK(so, 1);
4637 					return (ret_sz);
4638 				}
4639 			}
4640 #endif
4641 			sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
4642 #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4643 			if (!so_locked) {
4644 				SCTP_SOCKET_UNLOCK(so, 1);
4645 			}
4646 #endif
4647 		}
4648 		if (PR_SCTP_BUF_ENABLED(tp1->flags)) {
4649 			stcb->asoc.sent_queue_cnt_removeable--;
4650 		}
4651 		if (queue == &stcb->asoc.send_queue) {
4652 			TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
4653 			/* on to the sent queue */
4654 			TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
4655 			    sctp_next);
4656 			stcb->asoc.sent_queue_cnt++;
4657 		}
4658 		if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
4659 		    SCTP_DATA_NOT_FRAG) {
4660 			/* not frag'ed we ae done   */
4661 			notdone = 0;
4662 			foundeom = 1;
4663 		} else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
4664 			/* end of frag, we are done */
4665 			notdone = 0;
4666 			foundeom = 1;
4667 		} else {
4668 			/*
4669 			 * Its a begin or middle piece, we must mark all of
4670 			 * it
4671 			 */
4672 			notdone = 1;
4673 			tp1 = TAILQ_NEXT(tp1, sctp_next);
4674 		}
4675 	} while (tp1 && notdone);
4676 	if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
4677 		/*
4678 		 * The multi-part message was scattered across the send and
4679 		 * sent queue.
4680 		 */
4681 		tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
4682 		/*
4683 		 * recurse throught the send_queue too, starting at the
4684 		 * beginning.
4685 		 */
4686 		if (tp1) {
4687 			ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
4688 			    &stcb->asoc.send_queue, so_locked);
4689 		} else {
4690 			SCTP_PRINTF("hmm, nothing on the send queue and no EOM?\n");
4691 		}
4692 	}
4693 	return (ret_sz);
4694 }
4695 
4696 /*
4697  * checks to see if the given address, sa, is one that is currently known by
4698  * the kernel note: can't distinguish the same address on multiple interfaces
4699  * and doesn't handle multiple addresses with different zone/scope id's note:
4700  * ifa_ifwithaddr() compares the entire sockaddr struct
4701  */
4702 struct sctp_ifa *
4703 sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
4704     int holds_lock)
4705 {
4706 	struct sctp_laddr *laddr;
4707 
4708 	if (holds_lock == 0) {
4709 		SCTP_INP_RLOCK(inp);
4710 	}
4711 	LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
4712 		if (laddr->ifa == NULL)
4713 			continue;
4714 		if (addr->sa_family != laddr->ifa->address.sa.sa_family)
4715 			continue;
4716 		if (addr->sa_family == AF_INET) {
4717 			if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
4718 			    laddr->ifa->address.sin.sin_addr.s_addr) {
4719 				/* found him. */
4720 				if (holds_lock == 0) {
4721 					SCTP_INP_RUNLOCK(inp);
4722 				}
4723 				return (laddr->ifa);
4724 				break;
4725 			}
4726 		} else if (addr->sa_family == AF_INET6) {
4727 			if (SCTP6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr,
4728 			    &laddr->ifa->address.sin6.sin6_addr)) {
4729 				/* found him. */
4730 				if (holds_lock == 0) {
4731 					SCTP_INP_RUNLOCK(inp);
4732 				}
4733 				return (laddr->ifa);
4734 				break;
4735 			}
4736 		}
4737 	}
4738 	if (holds_lock == 0) {
4739 		SCTP_INP_RUNLOCK(inp);
4740 	}
4741 	return (NULL);
4742 }
4743 
4744 uint32_t
4745 sctp_get_ifa_hash_val(struct sockaddr *addr)
4746 {
4747 	if (addr->sa_family == AF_INET) {
4748 		struct sockaddr_in *sin;
4749 
4750 		sin = (struct sockaddr_in *)addr;
4751 		return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16));
4752 	} else if (addr->sa_family == AF_INET6) {
4753 		struct sockaddr_in6 *sin6;
4754 		uint32_t hash_of_addr;
4755 
4756 		sin6 = (struct sockaddr_in6 *)addr;
4757 		hash_of_addr = (sin6->sin6_addr.s6_addr32[0] +
4758 		    sin6->sin6_addr.s6_addr32[1] +
4759 		    sin6->sin6_addr.s6_addr32[2] +
4760 		    sin6->sin6_addr.s6_addr32[3]);
4761 		hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16));
4762 		return (hash_of_addr);
4763 	}
4764 	return (0);
4765 }
4766 
4767 struct sctp_ifa *
4768 sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
4769 {
4770 	struct sctp_ifa *sctp_ifap;
4771 	struct sctp_vrf *vrf;
4772 	struct sctp_ifalist *hash_head;
4773 	uint32_t hash_of_addr;
4774 
4775 	if (holds_lock == 0)
4776 		SCTP_IPI_ADDR_RLOCK();
4777 
4778 	vrf = sctp_find_vrf(vrf_id);
4779 	if (vrf == NULL) {
4780 		if (holds_lock == 0)
4781 			SCTP_IPI_ADDR_RUNLOCK();
4782 		return (NULL);
4783 	}
4784 	hash_of_addr = sctp_get_ifa_hash_val(addr);
4785 
4786 	hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
4787 	if (hash_head == NULL) {
4788 		SCTP_PRINTF("hash_of_addr:%x mask:%x table:%x - ",
4789 		    hash_of_addr, (uint32_t) vrf->vrf_addr_hashmark,
4790 		    (uint32_t) (hash_of_addr & vrf->vrf_addr_hashmark));
4791 		sctp_print_address(addr);
4792 		SCTP_PRINTF("No such bucket for address\n");
4793 		if (holds_lock == 0)
4794 			SCTP_IPI_ADDR_RUNLOCK();
4795 
4796 		return (NULL);
4797 	}
4798 	LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
4799 		if (sctp_ifap == NULL) {
4800 			panic("Huh LIST_FOREACH corrupt");
4801 		}
4802 		if (addr->sa_family != sctp_ifap->address.sa.sa_family)
4803 			continue;
4804 		if (addr->sa_family == AF_INET) {
4805 			if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
4806 			    sctp_ifap->address.sin.sin_addr.s_addr) {
4807 				/* found him. */
4808 				if (holds_lock == 0)
4809 					SCTP_IPI_ADDR_RUNLOCK();
4810 				return (sctp_ifap);
4811 				break;
4812 			}
4813 		} else if (addr->sa_family == AF_INET6) {
4814 			if (SCTP6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr,
4815 			    &sctp_ifap->address.sin6.sin6_addr)) {
4816 				/* found him. */
4817 				if (holds_lock == 0)
4818 					SCTP_IPI_ADDR_RUNLOCK();
4819 				return (sctp_ifap);
4820 				break;
4821 			}
4822 		}
4823 	}
4824 	if (holds_lock == 0)
4825 		SCTP_IPI_ADDR_RUNLOCK();
4826 	return (NULL);
4827 }
4828 
4829 static void
4830 sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t * freed_so_far, int hold_rlock,
4831     uint32_t rwnd_req)
4832 {
4833 	/* User pulled some data, do we need a rwnd update? */
4834 	int r_unlocked = 0;
4835 	uint32_t dif, rwnd;
4836 	struct socket *so = NULL;
4837 
4838 	if (stcb == NULL)
4839 		return;
4840 
4841 	atomic_add_int(&stcb->asoc.refcnt, 1);
4842 
4843 	if (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED |
4844 	    SCTP_STATE_SHUTDOWN_RECEIVED |
4845 	    SCTP_STATE_SHUTDOWN_ACK_SENT)) {
4846 		/* Pre-check If we are freeing no update */
4847 		goto no_lock;
4848 	}
4849 	SCTP_INP_INCR_REF(stcb->sctp_ep);
4850 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4851 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
4852 		goto out;
4853 	}
4854 	so = stcb->sctp_socket;
4855 	if (so == NULL) {
4856 		goto out;
4857 	}
4858 	atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far);
4859 	/* Have you have freed enough to look */
4860 	*freed_so_far = 0;
4861 	/* Yep, its worth a look and the lock overhead */
4862 
4863 	/* Figure out what the rwnd would be */
4864 	rwnd = sctp_calc_rwnd(stcb, &stcb->asoc);
4865 	if (rwnd >= stcb->asoc.my_last_reported_rwnd) {
4866 		dif = rwnd - stcb->asoc.my_last_reported_rwnd;
4867 	} else {
4868 		dif = 0;
4869 	}
4870 	if (dif >= rwnd_req) {
4871 		if (hold_rlock) {
4872 			SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
4873 			r_unlocked = 1;
4874 		}
4875 		if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4876 			/*
4877 			 * One last check before we allow the guy possibly
4878 			 * to get in. There is a race, where the guy has not
4879 			 * reached the gate. In that case
4880 			 */
4881 			goto out;
4882 		}
4883 		SCTP_TCB_LOCK(stcb);
4884 		if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4885 			/* No reports here */
4886 			SCTP_TCB_UNLOCK(stcb);
4887 			goto out;
4888 		}
4889 		SCTP_STAT_INCR(sctps_wu_sacks_sent);
4890 		sctp_send_sack(stcb);
4891 		sctp_chunk_output(stcb->sctp_ep, stcb,
4892 		    SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
4893 		/* make sure no timer is running */
4894 		sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
4895 		SCTP_TCB_UNLOCK(stcb);
4896 	} else {
4897 		/* Update how much we have pending */
4898 		stcb->freed_by_sorcv_sincelast = dif;
4899 	}
4900 out:
4901 	if (so && r_unlocked && hold_rlock) {
4902 		SCTP_INP_READ_LOCK(stcb->sctp_ep);
4903 	}
4904 	SCTP_INP_DECR_REF(stcb->sctp_ep);
4905 no_lock:
4906 	atomic_add_int(&stcb->asoc.refcnt, -1);
4907 	return;
4908 }
4909 
4910 int
4911 sctp_sorecvmsg(struct socket *so,
4912     struct uio *uio,
4913     struct mbuf **mp,
4914     struct sockaddr *from,
4915     int fromlen,
4916     int *msg_flags,
4917     struct sctp_sndrcvinfo *sinfo,
4918     int filling_sinfo)
4919 {
4920 	/*
4921 	 * MSG flags we will look at MSG_DONTWAIT - non-blocking IO.
4922 	 * MSG_PEEK - Look don't touch :-D (only valid with OUT mbuf copy
4923 	 * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ??
4924 	 * On the way out we may send out any combination of:
4925 	 * MSG_NOTIFICATION MSG_EOR
4926 	 *
4927 	 */
4928 	struct sctp_inpcb *inp = NULL;
4929 	int my_len = 0;
4930 	int cp_len = 0, error = 0;
4931 	struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL;
4932 	struct mbuf *m = NULL, *embuf = NULL;
4933 	struct sctp_tcb *stcb = NULL;
4934 	int wakeup_read_socket = 0;
4935 	int freecnt_applied = 0;
4936 	int out_flags = 0, in_flags = 0;
4937 	int block_allowed = 1;
4938 	uint32_t freed_so_far = 0;
4939 	uint32_t copied_so_far = 0;
4940 	int in_eeor_mode = 0;
4941 	int no_rcv_needed = 0;
4942 	uint32_t rwnd_req = 0;
4943 	int hold_sblock = 0;
4944 	int hold_rlock = 0;
4945 	int slen = 0;
4946 	uint32_t held_length = 0;
4947 	int sockbuf_lock = 0;
4948 
4949 	if (uio == NULL) {
4950 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
4951 		return (EINVAL);
4952 	}
4953 	if (msg_flags) {
4954 		in_flags = *msg_flags;
4955 		if (in_flags & MSG_PEEK)
4956 			SCTP_STAT_INCR(sctps_read_peeks);
4957 	} else {
4958 		in_flags = 0;
4959 	}
4960 	slen = uio->uio_resid;
4961 
4962 	/* Pull in and set up our int flags */
4963 	if (in_flags & MSG_OOB) {
4964 		/* Out of band's NOT supported */
4965 		return (EOPNOTSUPP);
4966 	}
4967 	if ((in_flags & MSG_PEEK) && (mp != NULL)) {
4968 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
4969 		return (EINVAL);
4970 	}
4971 	if ((in_flags & (MSG_DONTWAIT
4972 	    | MSG_NBIO
4973 	    )) ||
4974 	    SCTP_SO_IS_NBIO(so)) {
4975 		block_allowed = 0;
4976 	}
4977 	/* setup the endpoint */
4978 	inp = (struct sctp_inpcb *)so->so_pcb;
4979 	if (inp == NULL) {
4980 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
4981 		return (EFAULT);
4982 	}
4983 	rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
4984 	/* Must be at least a MTU's worth */
4985 	if (rwnd_req < SCTP_MIN_RWND)
4986 		rwnd_req = SCTP_MIN_RWND;
4987 	in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
4988 	if (sctp_logging_level & SCTP_RECV_RWND_LOGGING_ENABLE) {
4989 		sctp_misc_ints(SCTP_SORECV_ENTER,
4990 		    rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid);
4991 	}
4992 	if (sctp_logging_level & SCTP_RECV_RWND_LOGGING_ENABLE) {
4993 		sctp_misc_ints(SCTP_SORECV_ENTERPL,
4994 		    rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid);
4995 	}
4996 	error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0));
4997 	sockbuf_lock = 1;
4998 	if (error) {
4999 		goto release_unlocked;
5000 	}
5001 restart:
5002 
5003 
5004 restart_nosblocks:
5005 	if (hold_sblock == 0) {
5006 		SOCKBUF_LOCK(&so->so_rcv);
5007 		hold_sblock = 1;
5008 	}
5009 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
5010 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
5011 		goto out;
5012 	}
5013 	if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
5014 		if (so->so_error) {
5015 			error = so->so_error;
5016 			if ((in_flags & MSG_PEEK) == 0)
5017 				so->so_error = 0;
5018 			goto out;
5019 		} else {
5020 			if (so->so_rcv.sb_cc == 0) {
5021 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
5022 				/* indicate EOF */
5023 				error = 0;
5024 				goto out;
5025 			}
5026 		}
5027 	}
5028 	if ((so->so_rcv.sb_cc <= held_length) && block_allowed) {
5029 		/* we need to wait for data */
5030 		if ((so->so_rcv.sb_cc == 0) &&
5031 		    ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
5032 		    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
5033 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) {
5034 				/*
5035 				 * For active open side clear flags for
5036 				 * re-use passive open is blocked by
5037 				 * connect.
5038 				 */
5039 				if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) {
5040 					/*
5041 					 * You were aborted, passive side
5042 					 * always hits here
5043 					 */
5044 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
5045 					error = ECONNRESET;
5046 					/*
5047 					 * You get this once if you are
5048 					 * active open side
5049 					 */
5050 					if (!(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
5051 						/*
5052 						 * Remove flag if on the
5053 						 * active open side
5054 						 */
5055 						inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_ABORTED;
5056 					}
5057 				}
5058 				so->so_state &= ~(SS_ISCONNECTING |
5059 				    SS_ISDISCONNECTING |
5060 				    SS_ISCONFIRMING |
5061 				    SS_ISCONNECTED);
5062 				if (error == 0) {
5063 					if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
5064 						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
5065 						error = ENOTCONN;
5066 					} else {
5067 						inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
5068 					}
5069 				}
5070 				goto out;
5071 			}
5072 		}
5073 		error = sbwait(&so->so_rcv);
5074 		if (error) {
5075 			goto out;
5076 		}
5077 		held_length = 0;
5078 		goto restart_nosblocks;
5079 	} else if (so->so_rcv.sb_cc == 0) {
5080 		if (so->so_error) {
5081 			error = so->so_error;
5082 			if ((in_flags & MSG_PEEK) == 0)
5083 				so->so_error = 0;
5084 		} else {
5085 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
5086 			    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
5087 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) {
5088 					/*
5089 					 * For active open side clear flags
5090 					 * for re-use passive open is
5091 					 * blocked by connect.
5092 					 */
5093 					if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) {
5094 						/*
5095 						 * You were aborted, passive
5096 						 * side always hits here
5097 						 */
5098 						SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
5099 						error = ECONNRESET;
5100 						/*
5101 						 * You get this once if you
5102 						 * are active open side
5103 						 */
5104 						if (!(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
5105 							/*
5106 							 * Remove flag if on
5107 							 * the active open
5108 							 * side
5109 							 */
5110 							inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_ABORTED;
5111 						}
5112 					}
5113 					so->so_state &= ~(SS_ISCONNECTING |
5114 					    SS_ISDISCONNECTING |
5115 					    SS_ISCONFIRMING |
5116 					    SS_ISCONNECTED);
5117 					if (error == 0) {
5118 						if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
5119 							SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
5120 							error = ENOTCONN;
5121 						} else {
5122 							inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
5123 						}
5124 					}
5125 					goto out;
5126 				}
5127 			}
5128 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK);
5129 			error = EWOULDBLOCK;
5130 		}
5131 		goto out;
5132 	}
5133 	if (hold_sblock == 1) {
5134 		SOCKBUF_UNLOCK(&so->so_rcv);
5135 		hold_sblock = 0;
5136 	}
5137 	/* we possibly have data we can read */
5138 	/* sa_ignore FREED_MEMORY */
5139 	control = TAILQ_FIRST(&inp->read_queue);
5140 	if (control == NULL) {
5141 		/*
5142 		 * This could be happening since the appender did the
5143 		 * increment but as not yet did the tailq insert onto the
5144 		 * read_queue
5145 		 */
5146 		if (hold_rlock == 0) {
5147 			SCTP_INP_READ_LOCK(inp);
5148 			hold_rlock = 1;
5149 		}
5150 		control = TAILQ_FIRST(&inp->read_queue);
5151 		if ((control == NULL) && (so->so_rcv.sb_cc != 0)) {
5152 #ifdef INVARIANTS
5153 			panic("Huh, its non zero and nothing on control?");
5154 #endif
5155 			so->so_rcv.sb_cc = 0;
5156 		}
5157 		SCTP_INP_READ_UNLOCK(inp);
5158 		hold_rlock = 0;
5159 		goto restart;
5160 	}
5161 	if ((control->length == 0) &&
5162 	    (control->do_not_ref_stcb)) {
5163 		/*
5164 		 * Clean up code for freeing assoc that left behind a
5165 		 * pdapi.. maybe a peer in EEOR that just closed after
5166 		 * sending and never indicated a EOR.
5167 		 */
5168 		if (hold_rlock == 0) {
5169 			hold_rlock = 1;
5170 			SCTP_INP_READ_LOCK(inp);
5171 		}
5172 		control->held_length = 0;
5173 		if (control->data) {
5174 			/* Hmm there is data here .. fix */
5175 			struct mbuf *m_tmp;
5176 			int cnt = 0;
5177 
5178 			m_tmp = control->data;
5179 			while (m_tmp) {
5180 				cnt += SCTP_BUF_LEN(m_tmp);
5181 				if (SCTP_BUF_NEXT(m_tmp) == NULL) {
5182 					control->tail_mbuf = m_tmp;
5183 					control->end_added = 1;
5184 				}
5185 				m_tmp = SCTP_BUF_NEXT(m_tmp);
5186 			}
5187 			control->length = cnt;
5188 		} else {
5189 			/* remove it */
5190 			TAILQ_REMOVE(&inp->read_queue, control, next);
5191 			/* Add back any hiddend data */
5192 			sctp_free_remote_addr(control->whoFrom);
5193 			sctp_free_a_readq(stcb, control);
5194 		}
5195 		if (hold_rlock) {
5196 			hold_rlock = 0;
5197 			SCTP_INP_READ_UNLOCK(inp);
5198 		}
5199 		goto restart;
5200 	}
5201 	if (control->length == 0) {
5202 		if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) &&
5203 		    (filling_sinfo)) {
5204 			/* find a more suitable one then this */
5205 			ctl = TAILQ_NEXT(control, next);
5206 			while (ctl) {
5207 				if ((ctl->stcb != control->stcb) && (ctl->length) &&
5208 				    (ctl->some_taken ||
5209 				    (ctl->spec_flags & M_NOTIFICATION) ||
5210 				    ((ctl->do_not_ref_stcb == 0) &&
5211 				    (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
5212 				    ) {
5213 					/*-
5214 					 * If we have a different TCB next, and there is data
5215 					 * present. If we have already taken some (pdapi), OR we can
5216 					 * ref the tcb and no delivery as started on this stream, we
5217 					 * take it. Note we allow a notification on a different
5218 					 * assoc to be delivered..
5219 					 */
5220 					control = ctl;
5221 					goto found_one;
5222 				} else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) &&
5223 					    (ctl->length) &&
5224 					    ((ctl->some_taken) ||
5225 					    ((ctl->do_not_ref_stcb == 0) &&
5226 					    ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
5227 					    (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
5228 				    ) {
5229 					/*-
5230 					 * If we have the same tcb, and there is data present, and we
5231 					 * have the strm interleave feature present. Then if we have
5232 					 * taken some (pdapi) or we can refer to tht tcb AND we have
5233 					 * not started a delivery for this stream, we can take it.
5234 					 * Note we do NOT allow a notificaiton on the same assoc to
5235 					 * be delivered.
5236 					 */
5237 					control = ctl;
5238 					goto found_one;
5239 				}
5240 				ctl = TAILQ_NEXT(ctl, next);
5241 			}
5242 		}
5243 		/*
5244 		 * if we reach here, not suitable replacement is available
5245 		 * <or> fragment interleave is NOT on. So stuff the sb_cc
5246 		 * into the our held count, and its time to sleep again.
5247 		 */
5248 		held_length = so->so_rcv.sb_cc;
5249 		control->held_length = so->so_rcv.sb_cc;
5250 		goto restart;
5251 	}
5252 	/* Clear the held length since there is something to read */
5253 	control->held_length = 0;
5254 	if (hold_rlock) {
5255 		SCTP_INP_READ_UNLOCK(inp);
5256 		hold_rlock = 0;
5257 	}
5258 found_one:
5259 	/*
5260 	 * If we reach here, control has a some data for us to read off.
5261 	 * Note that stcb COULD be NULL.
5262 	 */
5263 	control->some_taken++;
5264 	if (hold_sblock) {
5265 		SOCKBUF_UNLOCK(&so->so_rcv);
5266 		hold_sblock = 0;
5267 	}
5268 	stcb = control->stcb;
5269 	if (stcb) {
5270 		if ((control->do_not_ref_stcb == 0) &&
5271 		    (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
5272 			if (freecnt_applied == 0)
5273 				stcb = NULL;
5274 		} else if (control->do_not_ref_stcb == 0) {
5275 			/* you can't free it on me please */
5276 			/*
5277 			 * The lock on the socket buffer protects us so the
5278 			 * free code will stop. But since we used the
5279 			 * socketbuf lock and the sender uses the tcb_lock
5280 			 * to increment, we need to use the atomic add to
5281 			 * the refcnt
5282 			 */
5283 			if (freecnt_applied) {
5284 #ifdef INVARIANTS
5285 				panic("refcnt already incremented");
5286 #else
5287 				printf("refcnt already incremented?\n");
5288 #endif
5289 			} else {
5290 				atomic_add_int(&stcb->asoc.refcnt, 1);
5291 				freecnt_applied = 1;
5292 			}
5293 			/*
5294 			 * Setup to remember how much we have not yet told
5295 			 * the peer our rwnd has opened up. Note we grab the
5296 			 * value from the tcb from last time. Note too that
5297 			 * sack sending clears this when a sack is sent,
5298 			 * which is fine. Once we hit the rwnd_req, we then
5299 			 * will go to the sctp_user_rcvd() that will not
5300 			 * lock until it KNOWs it MUST send a WUP-SACK.
5301 			 */
5302 			freed_so_far = stcb->freed_by_sorcv_sincelast;
5303 			stcb->freed_by_sorcv_sincelast = 0;
5304 		}
5305 	}
5306 	if (stcb &&
5307 	    ((control->spec_flags & M_NOTIFICATION) == 0) &&
5308 	    control->do_not_ref_stcb == 0) {
5309 		stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
5310 	}
5311 	/* First lets get off the sinfo and sockaddr info */
5312 	if ((sinfo) && filling_sinfo) {
5313 		memcpy(sinfo, control, sizeof(struct sctp_nonpad_sndrcvinfo));
5314 		nxt = TAILQ_NEXT(control, next);
5315 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO)) {
5316 			struct sctp_extrcvinfo *s_extra;
5317 
5318 			s_extra = (struct sctp_extrcvinfo *)sinfo;
5319 			if ((nxt) &&
5320 			    (nxt->length)) {
5321 				s_extra->sreinfo_next_flags = SCTP_NEXT_MSG_AVAIL;
5322 				if (nxt->sinfo_flags & SCTP_UNORDERED) {
5323 					s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED;
5324 				}
5325 				if (nxt->spec_flags & M_NOTIFICATION) {
5326 					s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION;
5327 				}
5328 				s_extra->sreinfo_next_aid = nxt->sinfo_assoc_id;
5329 				s_extra->sreinfo_next_length = nxt->length;
5330 				s_extra->sreinfo_next_ppid = nxt->sinfo_ppid;
5331 				s_extra->sreinfo_next_stream = nxt->sinfo_stream;
5332 				if (nxt->tail_mbuf != NULL) {
5333 					if (nxt->end_added) {
5334 						s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE;
5335 					}
5336 				}
5337 			} else {
5338 				/*
5339 				 * we explicitly 0 this, since the memcpy
5340 				 * got some other things beyond the older
5341 				 * sinfo_ that is on the control's structure
5342 				 * :-D
5343 				 */
5344 				nxt = NULL;
5345 				s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG;
5346 				s_extra->sreinfo_next_aid = 0;
5347 				s_extra->sreinfo_next_length = 0;
5348 				s_extra->sreinfo_next_ppid = 0;
5349 				s_extra->sreinfo_next_stream = 0;
5350 			}
5351 		}
5352 		/*
5353 		 * update off the real current cum-ack, if we have an stcb.
5354 		 */
5355 		if ((control->do_not_ref_stcb == 0) && stcb)
5356 			sinfo->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
5357 		/*
5358 		 * mask off the high bits, we keep the actual chunk bits in
5359 		 * there.
5360 		 */
5361 		sinfo->sinfo_flags &= 0x00ff;
5362 		if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) {
5363 			sinfo->sinfo_flags |= SCTP_UNORDERED;
5364 		}
5365 	}
5366 #ifdef SCTP_ASOCLOG_OF_TSNS
5367 	{
5368 		int index, newindex;
5369 		struct sctp_pcbtsn_rlog *entry;
5370 
5371 		do {
5372 			index = inp->readlog_index;
5373 			newindex = index + 1;
5374 			if (newindex >= SCTP_READ_LOG_SIZE) {
5375 				newindex = 0;
5376 			}
5377 		} while (atomic_cmpset_int(&inp->readlog_index, index, newindex) == 0);
5378 		entry = &inp->readlog[index];
5379 		entry->vtag = control->sinfo_assoc_id;
5380 		entry->strm = control->sinfo_stream;
5381 		entry->seq = control->sinfo_ssn;
5382 		entry->sz = control->length;
5383 		entry->flgs = control->sinfo_flags;
5384 	}
5385 #endif
5386 	if (fromlen && from) {
5387 		struct sockaddr *to;
5388 
5389 #ifdef INET
5390 		cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sin.sin_len);
5391 		memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
5392 		((struct sockaddr_in *)from)->sin_port = control->port_from;
5393 #else
5394 		/* No AF_INET use AF_INET6 */
5395 		cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sin6.sin6_len);
5396 		memcpy(from, &control->whoFrom->ro._l_addr, cp_len);
5397 		((struct sockaddr_in6 *)from)->sin6_port = control->port_from;
5398 #endif
5399 
5400 		to = from;
5401 #if defined(INET) && defined(INET6)
5402 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
5403 		    (to->sa_family == AF_INET) &&
5404 		    ((size_t)fromlen >= sizeof(struct sockaddr_in6))) {
5405 			struct sockaddr_in *sin;
5406 			struct sockaddr_in6 sin6;
5407 
5408 			sin = (struct sockaddr_in *)to;
5409 			bzero(&sin6, sizeof(sin6));
5410 			sin6.sin6_family = AF_INET6;
5411 			sin6.sin6_len = sizeof(struct sockaddr_in6);
5412 			sin6.sin6_addr.s6_addr16[2] = 0xffff;
5413 			bcopy(&sin->sin_addr,
5414 			    &sin6.sin6_addr.s6_addr16[3],
5415 			    sizeof(sin6.sin6_addr.s6_addr16[3]));
5416 			sin6.sin6_port = sin->sin_port;
5417 			memcpy(from, (caddr_t)&sin6, sizeof(sin6));
5418 		}
5419 #endif
5420 #if defined(INET6)
5421 		{
5422 			struct sockaddr_in6 lsa6, *to6;
5423 
5424 			to6 = (struct sockaddr_in6 *)to;
5425 			sctp_recover_scope_mac(to6, (&lsa6));
5426 		}
5427 #endif
5428 	}
5429 	/* now copy out what data we can */
5430 	if (mp == NULL) {
5431 		/* copy out each mbuf in the chain up to length */
5432 get_more_data:
5433 		m = control->data;
5434 		while (m) {
5435 			/* Move out all we can */
5436 			cp_len = (int)uio->uio_resid;
5437 			my_len = (int)SCTP_BUF_LEN(m);
5438 			if (cp_len > my_len) {
5439 				/* not enough in this buf */
5440 				cp_len = my_len;
5441 			}
5442 			if (hold_rlock) {
5443 				SCTP_INP_READ_UNLOCK(inp);
5444 				hold_rlock = 0;
5445 			}
5446 			if (cp_len > 0)
5447 				error = uiomove(mtod(m, char *), cp_len, uio);
5448 			/* re-read */
5449 			if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5450 				goto release;
5451 			}
5452 			if ((control->do_not_ref_stcb == 0) && stcb &&
5453 			    stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
5454 				no_rcv_needed = 1;
5455 			}
5456 			if (error) {
5457 				/* error we are out of here */
5458 				goto release;
5459 			}
5460 			if ((SCTP_BUF_NEXT(m) == NULL) &&
5461 			    (cp_len >= SCTP_BUF_LEN(m)) &&
5462 			    ((control->end_added == 0) ||
5463 			    (control->end_added &&
5464 			    (TAILQ_NEXT(control, next) == NULL)))
5465 			    ) {
5466 				SCTP_INP_READ_LOCK(inp);
5467 				hold_rlock = 1;
5468 			}
5469 			if (cp_len == SCTP_BUF_LEN(m)) {
5470 				if ((SCTP_BUF_NEXT(m) == NULL) &&
5471 				    (control->end_added)) {
5472 					out_flags |= MSG_EOR;
5473 					if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
5474 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
5475 				}
5476 				if (control->spec_flags & M_NOTIFICATION) {
5477 					out_flags |= MSG_NOTIFICATION;
5478 				}
5479 				/* we ate up the mbuf */
5480 				if (in_flags & MSG_PEEK) {
5481 					/* just looking */
5482 					m = SCTP_BUF_NEXT(m);
5483 					copied_so_far += cp_len;
5484 				} else {
5485 					/* dispose of the mbuf */
5486 					if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5487 						sctp_sblog(&so->so_rcv,
5488 						    control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
5489 					}
5490 					sctp_sbfree(control, stcb, &so->so_rcv, m);
5491 					if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5492 						sctp_sblog(&so->so_rcv,
5493 						    control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
5494 					}
5495 					embuf = m;
5496 					copied_so_far += cp_len;
5497 					freed_so_far += cp_len;
5498 					freed_so_far += MSIZE;
5499 					atomic_subtract_int(&control->length, cp_len);
5500 					control->data = sctp_m_free(m);
5501 					m = control->data;
5502 					/*
5503 					 * been through it all, must hold sb
5504 					 * lock ok to null tail
5505 					 */
5506 					if (control->data == NULL) {
5507 #ifdef INVARIANTS
5508 						if ((control->end_added == 0) ||
5509 						    (TAILQ_NEXT(control, next) == NULL)) {
5510 							/*
5511 							 * If the end is not
5512 							 * added, OR the
5513 							 * next is NOT null
5514 							 * we MUST have the
5515 							 * lock.
5516 							 */
5517 							if (mtx_owned(&inp->inp_rdata_mtx) == 0) {
5518 								panic("Hmm we don't own the lock?");
5519 							}
5520 						}
5521 #endif
5522 						control->tail_mbuf = NULL;
5523 #ifdef INVARIANTS
5524 						if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) {
5525 							panic("end_added, nothing left and no MSG_EOR");
5526 						}
5527 #endif
5528 					}
5529 				}
5530 			} else {
5531 				/* Do we need to trim the mbuf? */
5532 				if (control->spec_flags & M_NOTIFICATION) {
5533 					out_flags |= MSG_NOTIFICATION;
5534 				}
5535 				if ((in_flags & MSG_PEEK) == 0) {
5536 					SCTP_BUF_RESV_UF(m, cp_len);
5537 					SCTP_BUF_LEN(m) -= cp_len;
5538 					if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5539 						sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, cp_len);
5540 					}
5541 					atomic_subtract_int(&so->so_rcv.sb_cc, cp_len);
5542 					if ((control->do_not_ref_stcb == 0) &&
5543 					    stcb) {
5544 						atomic_subtract_int(&stcb->asoc.sb_cc, cp_len);
5545 					}
5546 					copied_so_far += cp_len;
5547 					embuf = m;
5548 					freed_so_far += cp_len;
5549 					freed_so_far += MSIZE;
5550 					if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5551 						sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb,
5552 						    SCTP_LOG_SBRESULT, 0);
5553 					}
5554 					atomic_subtract_int(&control->length, cp_len);
5555 				} else {
5556 					copied_so_far += cp_len;
5557 				}
5558 			}
5559 			if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
5560 				break;
5561 			}
5562 			if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
5563 			    (control->do_not_ref_stcb == 0) &&
5564 			    (freed_so_far >= rwnd_req)) {
5565 				sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
5566 			}
5567 		}		/* end while(m) */
5568 		/*
5569 		 * At this point we have looked at it all and we either have
5570 		 * a MSG_EOR/or read all the user wants... <OR>
5571 		 * control->length == 0.
5572 		 */
5573 		if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) {
5574 			/* we are done with this control */
5575 			if (control->length == 0) {
5576 				if (control->data) {
5577 #ifdef INVARIANTS
5578 					panic("control->data not null at read eor?");
5579 #else
5580 					SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n");
5581 					sctp_m_freem(control->data);
5582 					control->data = NULL;
5583 #endif
5584 				}
5585 		done_with_control:
5586 				if (TAILQ_NEXT(control, next) == NULL) {
5587 					/*
5588 					 * If we don't have a next we need a
5589 					 * lock, if there is a next
5590 					 * interrupt is filling ahead of us
5591 					 * and we don't need a lock to
5592 					 * remove this guy (which is the
5593 					 * head of the queue).
5594 					 */
5595 					if (hold_rlock == 0) {
5596 						SCTP_INP_READ_LOCK(inp);
5597 						hold_rlock = 1;
5598 					}
5599 				}
5600 				TAILQ_REMOVE(&inp->read_queue, control, next);
5601 				/* Add back any hiddend data */
5602 				if (control->held_length) {
5603 					held_length = 0;
5604 					control->held_length = 0;
5605 					wakeup_read_socket = 1;
5606 				}
5607 				if (control->aux_data) {
5608 					sctp_m_free(control->aux_data);
5609 					control->aux_data = NULL;
5610 				}
5611 				no_rcv_needed = control->do_not_ref_stcb;
5612 				sctp_free_remote_addr(control->whoFrom);
5613 				control->data = NULL;
5614 				sctp_free_a_readq(stcb, control);
5615 				control = NULL;
5616 				if ((freed_so_far >= rwnd_req) &&
5617 				    (no_rcv_needed == 0))
5618 					sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
5619 
5620 			} else {
5621 				/*
5622 				 * The user did not read all of this
5623 				 * message, turn off the returned MSG_EOR
5624 				 * since we are leaving more behind on the
5625 				 * control to read.
5626 				 */
5627 #ifdef INVARIANTS
5628 				if (control->end_added &&
5629 				    (control->data == NULL) &&
5630 				    (control->tail_mbuf == NULL)) {
5631 					panic("Gak, control->length is corrupt?");
5632 				}
5633 #endif
5634 				no_rcv_needed = control->do_not_ref_stcb;
5635 				out_flags &= ~MSG_EOR;
5636 			}
5637 		}
5638 		if (out_flags & MSG_EOR) {
5639 			goto release;
5640 		}
5641 		if ((uio->uio_resid == 0) ||
5642 		    ((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))
5643 		    ) {
5644 			goto release;
5645 		}
5646 		/*
5647 		 * If I hit here the receiver wants more and this message is
5648 		 * NOT done (pd-api). So two questions. Can we block? if not
5649 		 * we are done. Did the user NOT set MSG_WAITALL?
5650 		 */
5651 		if (block_allowed == 0) {
5652 			goto release;
5653 		}
5654 		/*
5655 		 * We need to wait for more data a few things: - We don't
5656 		 * sbunlock() so we don't get someone else reading. - We
5657 		 * must be sure to account for the case where what is added
5658 		 * is NOT to our control when we wakeup.
5659 		 */
5660 
5661 		/*
5662 		 * Do we need to tell the transport a rwnd update might be
5663 		 * needed before we go to sleep?
5664 		 */
5665 		if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
5666 		    ((freed_so_far >= rwnd_req) &&
5667 		    (control->do_not_ref_stcb == 0) &&
5668 		    (no_rcv_needed == 0))) {
5669 			sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
5670 		}
5671 wait_some_more:
5672 		if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
5673 			goto release;
5674 		}
5675 		if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)
5676 			goto release;
5677 
5678 		if (hold_rlock == 1) {
5679 			SCTP_INP_READ_UNLOCK(inp);
5680 			hold_rlock = 0;
5681 		}
5682 		if (hold_sblock == 0) {
5683 			SOCKBUF_LOCK(&so->so_rcv);
5684 			hold_sblock = 1;
5685 		}
5686 		if ((copied_so_far) && (control->length == 0) &&
5687 		    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))
5688 		    ) {
5689 			goto release;
5690 		}
5691 		if (so->so_rcv.sb_cc <= control->held_length) {
5692 			error = sbwait(&so->so_rcv);
5693 			if (error) {
5694 				goto release;
5695 			}
5696 			control->held_length = 0;
5697 		}
5698 		if (hold_sblock) {
5699 			SOCKBUF_UNLOCK(&so->so_rcv);
5700 			hold_sblock = 0;
5701 		}
5702 		if (control->length == 0) {
5703 			/* still nothing here */
5704 			if (control->end_added == 1) {
5705 				/* he aborted, or is done i.e.did a shutdown */
5706 				out_flags |= MSG_EOR;
5707 				if (control->pdapi_aborted) {
5708 					if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
5709 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
5710 
5711 					out_flags |= MSG_TRUNC;
5712 				} else {
5713 					if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
5714 						control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
5715 				}
5716 				goto done_with_control;
5717 			}
5718 			if (so->so_rcv.sb_cc > held_length) {
5719 				control->held_length = so->so_rcv.sb_cc;
5720 				held_length = 0;
5721 			}
5722 			goto wait_some_more;
5723 		} else if (control->data == NULL) {
5724 			/*
5725 			 * we must re-sync since data is probably being
5726 			 * added
5727 			 */
5728 			SCTP_INP_READ_LOCK(inp);
5729 			if ((control->length > 0) && (control->data == NULL)) {
5730 				/*
5731 				 * big trouble.. we have the lock and its
5732 				 * corrupt?
5733 				 */
5734 #ifdef INVARIANTS
5735 				panic("Impossible data==NULL length !=0");
5736 #endif
5737 				out_flags |= MSG_EOR;
5738 				out_flags |= MSG_TRUNC;
5739 				control->length = 0;
5740 				SCTP_INP_READ_UNLOCK(inp);
5741 				goto done_with_control;
5742 			}
5743 			SCTP_INP_READ_UNLOCK(inp);
5744 			/* We will fall around to get more data */
5745 		}
5746 		goto get_more_data;
5747 	} else {
5748 		/*-
5749 		 * Give caller back the mbuf chain,
5750 		 * store in uio_resid the length
5751 		 */
5752 		wakeup_read_socket = 0;
5753 		if ((control->end_added == 0) ||
5754 		    (TAILQ_NEXT(control, next) == NULL)) {
5755 			/* Need to get rlock */
5756 			if (hold_rlock == 0) {
5757 				SCTP_INP_READ_LOCK(inp);
5758 				hold_rlock = 1;
5759 			}
5760 		}
5761 		if (control->end_added) {
5762 			out_flags |= MSG_EOR;
5763 			if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
5764 				control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
5765 		}
5766 		if (control->spec_flags & M_NOTIFICATION) {
5767 			out_flags |= MSG_NOTIFICATION;
5768 		}
5769 		uio->uio_resid = control->length;
5770 		*mp = control->data;
5771 		m = control->data;
5772 		while (m) {
5773 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5774 				sctp_sblog(&so->so_rcv,
5775 				    control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
5776 			}
5777 			sctp_sbfree(control, stcb, &so->so_rcv, m);
5778 			freed_so_far += SCTP_BUF_LEN(m);
5779 			freed_so_far += MSIZE;
5780 			if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
5781 				sctp_sblog(&so->so_rcv,
5782 				    control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
5783 			}
5784 			m = SCTP_BUF_NEXT(m);
5785 		}
5786 		control->data = control->tail_mbuf = NULL;
5787 		control->length = 0;
5788 		if (out_flags & MSG_EOR) {
5789 			/* Done with this control */
5790 			goto done_with_control;
5791 		}
5792 	}
5793 release:
5794 	if (hold_rlock == 1) {
5795 		SCTP_INP_READ_UNLOCK(inp);
5796 		hold_rlock = 0;
5797 	}
5798 	if (hold_sblock == 1) {
5799 		SOCKBUF_UNLOCK(&so->so_rcv);
5800 		hold_sblock = 0;
5801 	}
5802 	sbunlock(&so->so_rcv);
5803 	sockbuf_lock = 0;
5804 
5805 release_unlocked:
5806 	if (hold_sblock) {
5807 		SOCKBUF_UNLOCK(&so->so_rcv);
5808 		hold_sblock = 0;
5809 	}
5810 	if ((stcb) && (in_flags & MSG_PEEK) == 0) {
5811 		if ((freed_so_far >= rwnd_req) &&
5812 		    (control && (control->do_not_ref_stcb == 0)) &&
5813 		    (no_rcv_needed == 0))
5814 			sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
5815 	}
5816 	if (msg_flags)
5817 		*msg_flags = out_flags;
5818 out:
5819 	if (((out_flags & MSG_EOR) == 0) &&
5820 	    ((in_flags & MSG_PEEK) == 0) &&
5821 	    (sinfo) &&
5822 	    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO))) {
5823 		struct sctp_extrcvinfo *s_extra;
5824 
5825 		s_extra = (struct sctp_extrcvinfo *)sinfo;
5826 		s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG;
5827 	}
5828 	if (hold_rlock == 1) {
5829 		SCTP_INP_READ_UNLOCK(inp);
5830 		hold_rlock = 0;
5831 	}
5832 	if (hold_sblock) {
5833 		SOCKBUF_UNLOCK(&so->so_rcv);
5834 		hold_sblock = 0;
5835 	}
5836 	if (sockbuf_lock) {
5837 		sbunlock(&so->so_rcv);
5838 	}
5839 	if (freecnt_applied) {
5840 		/*
5841 		 * The lock on the socket buffer protects us so the free
5842 		 * code will stop. But since we used the socketbuf lock and
5843 		 * the sender uses the tcb_lock to increment, we need to use
5844 		 * the atomic add to the refcnt.
5845 		 */
5846 		if (stcb == NULL) {
5847 			panic("stcb for refcnt has gone NULL?");
5848 		}
5849 		atomic_add_int(&stcb->asoc.refcnt, -1);
5850 		freecnt_applied = 0;
5851 		/* Save the value back for next time */
5852 		stcb->freed_by_sorcv_sincelast = freed_so_far;
5853 	}
5854 	if (sctp_logging_level & SCTP_RECV_RWND_LOGGING_ENABLE) {
5855 		if (stcb) {
5856 			sctp_misc_ints(SCTP_SORECV_DONE,
5857 			    freed_so_far,
5858 			    ((uio) ? (slen - uio->uio_resid) : slen),
5859 			    stcb->asoc.my_rwnd,
5860 			    so->so_rcv.sb_cc);
5861 		} else {
5862 			sctp_misc_ints(SCTP_SORECV_DONE,
5863 			    freed_so_far,
5864 			    ((uio) ? (slen - uio->uio_resid) : slen),
5865 			    0,
5866 			    so->so_rcv.sb_cc);
5867 		}
5868 	}
5869 	if (wakeup_read_socket) {
5870 		sctp_sorwakeup(inp, so);
5871 	}
5872 	return (error);
5873 }
5874 
5875 
5876 #ifdef SCTP_MBUF_LOGGING
5877 struct mbuf *
5878 sctp_m_free(struct mbuf *m)
5879 {
5880 	if (sctp_logging_level & SCTP_MBUF_LOGGING_ENABLE) {
5881 		if (SCTP_BUF_IS_EXTENDED(m)) {
5882 			sctp_log_mb(m, SCTP_MBUF_IFREE);
5883 		}
5884 	}
5885 	return (m_free(m));
5886 }
5887 
5888 void
5889 sctp_m_freem(struct mbuf *mb)
5890 {
5891 	while (mb != NULL)
5892 		mb = sctp_m_free(mb);
5893 }
5894 
5895 #endif
5896 
5897 int
5898 sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
5899 {
5900 	/*
5901 	 * Given a local address. For all associations that holds the
5902 	 * address, request a peer-set-primary.
5903 	 */
5904 	struct sctp_ifa *ifa;
5905 	struct sctp_laddr *wi;
5906 
5907 	ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
5908 	if (ifa == NULL) {
5909 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL);
5910 		return (EADDRNOTAVAIL);
5911 	}
5912 	/*
5913 	 * Now that we have the ifa we must awaken the iterator with this
5914 	 * message.
5915 	 */
5916 	wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr);
5917 	if (wi == NULL) {
5918 		SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
5919 		return (ENOMEM);
5920 	}
5921 	/* Now incr the count and int wi structure */
5922 	SCTP_INCR_LADDR_COUNT();
5923 	bzero(wi, sizeof(*wi));
5924 	(void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
5925 	wi->ifa = ifa;
5926 	wi->action = SCTP_SET_PRIM_ADDR;
5927 	atomic_add_int(&ifa->refcount, 1);
5928 
5929 	/* Now add it to the work queue */
5930 	SCTP_IPI_ITERATOR_WQ_LOCK();
5931 	/*
5932 	 * Should this really be a tailq? As it is we will process the
5933 	 * newest first :-0
5934 	 */
5935 	LIST_INSERT_HEAD(&sctppcbinfo.addr_wq, wi, sctp_nxt_addr);
5936 	sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
5937 	    (struct sctp_inpcb *)NULL,
5938 	    (struct sctp_tcb *)NULL,
5939 	    (struct sctp_nets *)NULL);
5940 	SCTP_IPI_ITERATOR_WQ_UNLOCK();
5941 	return (0);
5942 }
5943 
5944 
5945 
5946 
5947 int
5948 sctp_soreceive(struct socket *so,
5949     struct sockaddr **psa,
5950     struct uio *uio,
5951     struct mbuf **mp0,
5952     struct mbuf **controlp,
5953     int *flagsp)
5954 {
5955 	int error, fromlen;
5956 	uint8_t sockbuf[256];
5957 	struct sockaddr *from;
5958 	struct sctp_extrcvinfo sinfo;
5959 	int filling_sinfo = 1;
5960 	struct sctp_inpcb *inp;
5961 
5962 	inp = (struct sctp_inpcb *)so->so_pcb;
5963 	/* pickup the assoc we are reading from */
5964 	if (inp == NULL) {
5965 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
5966 		return (EINVAL);
5967 	}
5968 	if ((sctp_is_feature_off(inp,
5969 	    SCTP_PCB_FLAGS_RECVDATAIOEVNT)) ||
5970 	    (controlp == NULL)) {
5971 		/* user does not want the sndrcv ctl */
5972 		filling_sinfo = 0;
5973 	}
5974 	if (psa) {
5975 		from = (struct sockaddr *)sockbuf;
5976 		fromlen = sizeof(sockbuf);
5977 		from->sa_len = 0;
5978 	} else {
5979 		from = NULL;
5980 		fromlen = 0;
5981 	}
5982 
5983 	error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
5984 	    (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
5985 	if ((controlp) && (filling_sinfo)) {
5986 		/* copy back the sinfo in a CMSG format */
5987 		if (filling_sinfo)
5988 			*controlp = sctp_build_ctl_nchunk(inp,
5989 			    (struct sctp_sndrcvinfo *)&sinfo);
5990 		else
5991 			*controlp = NULL;
5992 	}
5993 	if (psa) {
5994 		/* copy back the address info */
5995 		if (from && from->sa_len) {
5996 			*psa = sodupsockaddr(from, M_NOWAIT);
5997 		} else {
5998 			*psa = NULL;
5999 		}
6000 	}
6001 	return (error);
6002 }
6003 
6004 
6005 int
6006 sctp_l_soreceive(struct socket *so,
6007     struct sockaddr **name,
6008     struct uio *uio,
6009     char **controlp,
6010     int *controllen,
6011     int *flag)
6012 {
6013 	int error, fromlen;
6014 	uint8_t sockbuf[256];
6015 	struct sockaddr *from;
6016 	struct sctp_extrcvinfo sinfo;
6017 	int filling_sinfo = 1;
6018 	struct sctp_inpcb *inp;
6019 
6020 	inp = (struct sctp_inpcb *)so->so_pcb;
6021 	/* pickup the assoc we are reading from */
6022 	if (inp == NULL) {
6023 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6024 		return (EINVAL);
6025 	}
6026 	if ((sctp_is_feature_off(inp,
6027 	    SCTP_PCB_FLAGS_RECVDATAIOEVNT)) ||
6028 	    (controlp == NULL)) {
6029 		/* user does not want the sndrcv ctl */
6030 		filling_sinfo = 0;
6031 	}
6032 	if (name) {
6033 		from = (struct sockaddr *)sockbuf;
6034 		fromlen = sizeof(sockbuf);
6035 		from->sa_len = 0;
6036 	} else {
6037 		from = NULL;
6038 		fromlen = 0;
6039 	}
6040 
6041 	error = sctp_sorecvmsg(so, uio,
6042 	    (struct mbuf **)NULL,
6043 	    from, fromlen, flag,
6044 	    (struct sctp_sndrcvinfo *)&sinfo,
6045 	    filling_sinfo);
6046 	if ((controlp) && (filling_sinfo)) {
6047 		/*
6048 		 * copy back the sinfo in a CMSG format note that the caller
6049 		 * has reponsibility for freeing the memory.
6050 		 */
6051 		if (filling_sinfo)
6052 			*controlp = sctp_build_ctl_cchunk(inp,
6053 			    controllen,
6054 			    (struct sctp_sndrcvinfo *)&sinfo);
6055 	}
6056 	if (name) {
6057 		/* copy back the address info */
6058 		if (from && from->sa_len) {
6059 			*name = sodupsockaddr(from, M_WAIT);
6060 		} else {
6061 			*name = NULL;
6062 		}
6063 	}
6064 	return (error);
6065 }
6066 
6067 
6068 
6069 
6070 
6071 
6072 
6073 int
6074 sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
6075     int totaddr, int *error)
6076 {
6077 	int added = 0;
6078 	int i;
6079 	struct sctp_inpcb *inp;
6080 	struct sockaddr *sa;
6081 	size_t incr = 0;
6082 
6083 	sa = addr;
6084 	inp = stcb->sctp_ep;
6085 	*error = 0;
6086 	for (i = 0; i < totaddr; i++) {
6087 		if (sa->sa_family == AF_INET) {
6088 			incr = sizeof(struct sockaddr_in);
6089 			if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
6090 				/* assoc gone no un-lock */
6091 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
6092 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
6093 				*error = ENOBUFS;
6094 				goto out_now;
6095 			}
6096 			added++;
6097 		} else if (sa->sa_family == AF_INET6) {
6098 			incr = sizeof(struct sockaddr_in6);
6099 			if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
6100 				/* assoc gone no un-lock */
6101 				SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
6102 				(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
6103 				*error = ENOBUFS;
6104 				goto out_now;
6105 			}
6106 			added++;
6107 		}
6108 		sa = (struct sockaddr *)((caddr_t)sa + incr);
6109 	}
6110 out_now:
6111 	return (added);
6112 }
6113 
6114 struct sctp_tcb *
6115 sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
6116     int *totaddr, int *num_v4, int *num_v6, int *error,
6117     int limit, int *bad_addr)
6118 {
6119 	struct sockaddr *sa;
6120 	struct sctp_tcb *stcb = NULL;
6121 	size_t incr, at, i;
6122 
6123 	at = incr = 0;
6124 	sa = addr;
6125 	*error = *num_v6 = *num_v4 = 0;
6126 	/* account and validate addresses */
6127 	for (i = 0; i < (size_t)*totaddr; i++) {
6128 		if (sa->sa_family == AF_INET) {
6129 			(*num_v4) += 1;
6130 			incr = sizeof(struct sockaddr_in);
6131 			if (sa->sa_len != incr) {
6132 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6133 				*error = EINVAL;
6134 				*bad_addr = 1;
6135 				return (NULL);
6136 			}
6137 		} else if (sa->sa_family == AF_INET6) {
6138 			struct sockaddr_in6 *sin6;
6139 
6140 			sin6 = (struct sockaddr_in6 *)sa;
6141 			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
6142 				/* Must be non-mapped for connectx */
6143 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6144 				*error = EINVAL;
6145 				*bad_addr = 1;
6146 				return (NULL);
6147 			}
6148 			(*num_v6) += 1;
6149 			incr = sizeof(struct sockaddr_in6);
6150 			if (sa->sa_len != incr) {
6151 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6152 				*error = EINVAL;
6153 				*bad_addr = 1;
6154 				return (NULL);
6155 			}
6156 		} else {
6157 			*totaddr = i;
6158 			/* we are done */
6159 			break;
6160 		}
6161 		SCTP_INP_INCR_REF(inp);
6162 		stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
6163 		if (stcb != NULL) {
6164 			/* Already have or am bring up an association */
6165 			return (stcb);
6166 		} else {
6167 			SCTP_INP_DECR_REF(inp);
6168 		}
6169 		if ((at + incr) > (size_t)limit) {
6170 			*totaddr = i;
6171 			break;
6172 		}
6173 		sa = (struct sockaddr *)((caddr_t)sa + incr);
6174 	}
6175 	return ((struct sctp_tcb *)NULL);
6176 }
6177 
6178 /*
6179  * sctp_bindx(ADD) for one address.
6180  * assumes all arguments are valid/checked by caller.
6181  */
6182 void
6183 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
6184     struct sockaddr *sa, sctp_assoc_t assoc_id,
6185     uint32_t vrf_id, int *error, void *p)
6186 {
6187 	struct sockaddr *addr_touse;
6188 	struct sockaddr_in sin;
6189 
6190 	/* see if we're bound all already! */
6191 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6192 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6193 		*error = EINVAL;
6194 		return;
6195 	}
6196 	addr_touse = sa;
6197 #if defined(INET6)
6198 	if (sa->sa_family == AF_INET6) {
6199 		struct sockaddr_in6 *sin6;
6200 
6201 		if (sa->sa_len != sizeof(struct sockaddr_in6)) {
6202 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6203 			*error = EINVAL;
6204 			return;
6205 		}
6206 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
6207 			/* can only bind v6 on PF_INET6 sockets */
6208 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6209 			*error = EINVAL;
6210 			return;
6211 		}
6212 		sin6 = (struct sockaddr_in6 *)addr_touse;
6213 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
6214 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
6215 			    SCTP_IPV6_V6ONLY(inp)) {
6216 				/* can't bind v4-mapped on PF_INET sockets */
6217 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6218 				*error = EINVAL;
6219 				return;
6220 			}
6221 			in6_sin6_2_sin(&sin, sin6);
6222 			addr_touse = (struct sockaddr *)&sin;
6223 		}
6224 	}
6225 #endif
6226 	if (sa->sa_family == AF_INET) {
6227 		if (sa->sa_len != sizeof(struct sockaddr_in)) {
6228 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6229 			*error = EINVAL;
6230 			return;
6231 		}
6232 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
6233 		    SCTP_IPV6_V6ONLY(inp)) {
6234 			/* can't bind v4 on PF_INET sockets */
6235 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6236 			*error = EINVAL;
6237 			return;
6238 		}
6239 	}
6240 	if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
6241 		if (p == NULL) {
6242 			/* Can't get proc for Net/Open BSD */
6243 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6244 			*error = EINVAL;
6245 			return;
6246 		}
6247 		*error = sctp_inpcb_bind(so, addr_touse, NULL, p);
6248 		return;
6249 	}
6250 	/*
6251 	 * No locks required here since bind and mgmt_ep_sa all do their own
6252 	 * locking. If we do something for the FIX: below we may need to
6253 	 * lock in that case.
6254 	 */
6255 	if (assoc_id == 0) {
6256 		/* add the address */
6257 		struct sctp_inpcb *lep;
6258 		struct sockaddr_in *lsin = (struct sockaddr_in *)addr_touse;
6259 
6260 		/* validate the incoming port */
6261 		if ((lsin->sin_port != 0) &&
6262 		    (lsin->sin_port != inp->sctp_lport)) {
6263 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6264 			*error = EINVAL;
6265 			return;
6266 		} else {
6267 			/* user specified 0 port, set it to existing port */
6268 			lsin->sin_port = inp->sctp_lport;
6269 		}
6270 
6271 		lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id);
6272 		if (lep != NULL) {
6273 			/*
6274 			 * We must decrement the refcount since we have the
6275 			 * ep already and are binding. No remove going on
6276 			 * here.
6277 			 */
6278 			SCTP_INP_DECR_REF(inp);
6279 		}
6280 		if (lep == inp) {
6281 			/* already bound to it.. ok */
6282 			return;
6283 		} else if (lep == NULL) {
6284 			((struct sockaddr_in *)addr_touse)->sin_port = 0;
6285 			*error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
6286 			    SCTP_ADD_IP_ADDRESS,
6287 			    vrf_id, NULL);
6288 		} else {
6289 			*error = EADDRINUSE;
6290 		}
6291 		if (*error)
6292 			return;
6293 	} else {
6294 		/*
6295 		 * FIX: decide whether we allow assoc based bindx
6296 		 */
6297 	}
6298 }
6299 
6300 /*
6301  * sctp_bindx(DELETE) for one address.
6302  * assumes all arguments are valid/checked by caller.
6303  */
6304 void
6305 sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
6306     struct sockaddr *sa, sctp_assoc_t assoc_id,
6307     uint32_t vrf_id, int *error)
6308 {
6309 	struct sockaddr *addr_touse;
6310 	struct sockaddr_in sin;
6311 
6312 	/* see if we're bound all already! */
6313 	if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6314 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6315 		*error = EINVAL;
6316 		return;
6317 	}
6318 	addr_touse = sa;
6319 #if defined(INET6)
6320 	if (sa->sa_family == AF_INET6) {
6321 		struct sockaddr_in6 *sin6;
6322 
6323 		if (sa->sa_len != sizeof(struct sockaddr_in6)) {
6324 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6325 			*error = EINVAL;
6326 			return;
6327 		}
6328 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
6329 			/* can only bind v6 on PF_INET6 sockets */
6330 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6331 			*error = EINVAL;
6332 			return;
6333 		}
6334 		sin6 = (struct sockaddr_in6 *)addr_touse;
6335 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
6336 			if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
6337 			    SCTP_IPV6_V6ONLY(inp)) {
6338 				/* can't bind mapped-v4 on PF_INET sockets */
6339 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6340 				*error = EINVAL;
6341 				return;
6342 			}
6343 			in6_sin6_2_sin(&sin, sin6);
6344 			addr_touse = (struct sockaddr *)&sin;
6345 		}
6346 	}
6347 #endif
6348 	if (sa->sa_family == AF_INET) {
6349 		if (sa->sa_len != sizeof(struct sockaddr_in)) {
6350 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6351 			*error = EINVAL;
6352 			return;
6353 		}
6354 		if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
6355 		    SCTP_IPV6_V6ONLY(inp)) {
6356 			/* can't bind v4 on PF_INET sockets */
6357 			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6358 			*error = EINVAL;
6359 			return;
6360 		}
6361 	}
6362 	/*
6363 	 * No lock required mgmt_ep_sa does its own locking. If the FIX:
6364 	 * below is ever changed we may need to lock before calling
6365 	 * association level binding.
6366 	 */
6367 	if (assoc_id == 0) {
6368 		/* delete the address */
6369 		*error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
6370 		    SCTP_DEL_IP_ADDRESS,
6371 		    vrf_id, NULL);
6372 	} else {
6373 		/*
6374 		 * FIX: decide whether we allow assoc based bindx
6375 		 */
6376 	}
6377 }
6378 
6379 /*
6380  * returns the valid local address count for an assoc, taking into account
6381  * all scoping rules
6382  */
6383 int
6384 sctp_local_addr_count(struct sctp_tcb *stcb)
6385 {
6386 	int loopback_scope, ipv4_local_scope, local_scope, site_scope;
6387 	int ipv4_addr_legal, ipv6_addr_legal;
6388 	struct sctp_vrf *vrf;
6389 	struct sctp_ifn *sctp_ifn;
6390 	struct sctp_ifa *sctp_ifa;
6391 	int count = 0;
6392 
6393 	/* Turn on all the appropriate scopes */
6394 	loopback_scope = stcb->asoc.loopback_scope;
6395 	ipv4_local_scope = stcb->asoc.ipv4_local_scope;
6396 	local_scope = stcb->asoc.local_scope;
6397 	site_scope = stcb->asoc.site_scope;
6398 	ipv4_addr_legal = ipv6_addr_legal = 0;
6399 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
6400 		ipv6_addr_legal = 1;
6401 		if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) {
6402 			ipv4_addr_legal = 1;
6403 		}
6404 	} else {
6405 		ipv4_addr_legal = 1;
6406 	}
6407 
6408 	SCTP_IPI_ADDR_RLOCK();
6409 	vrf = sctp_find_vrf(stcb->asoc.vrf_id);
6410 	if (vrf == NULL) {
6411 		/* no vrf, no addresses */
6412 		SCTP_IPI_ADDR_RUNLOCK();
6413 		return (0);
6414 	}
6415 	if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
6416 		/*
6417 		 * bound all case: go through all ifns on the vrf
6418 		 */
6419 		LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
6420 			if ((loopback_scope == 0) &&
6421 			    SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
6422 				continue;
6423 			}
6424 			LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
6425 				if (sctp_is_addr_restricted(stcb, sctp_ifa))
6426 					continue;
6427 
6428 				if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
6429 				    (ipv4_addr_legal)) {
6430 					struct sockaddr_in *sin;
6431 
6432 					sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
6433 					if (sin->sin_addr.s_addr == 0) {
6434 						/* skip unspecified addrs */
6435 						continue;
6436 					}
6437 					if ((ipv4_local_scope == 0) &&
6438 					    (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
6439 						continue;
6440 					}
6441 					/* count this one */
6442 					count++;
6443 				} else if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
6444 				    (ipv6_addr_legal)) {
6445 					struct sockaddr_in6 *sin6;
6446 
6447 					sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
6448 					if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
6449 						continue;
6450 					}
6451 					if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
6452 						if (local_scope == 0)
6453 							continue;
6454 						if (sin6->sin6_scope_id == 0) {
6455 							if (sa6_recoverscope(sin6) != 0)
6456 								/*
6457 								 * bad link
6458 								 * local
6459 								 * address
6460 								 */
6461 								continue;
6462 						}
6463 					}
6464 					if ((site_scope == 0) &&
6465 					    (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
6466 						continue;
6467 					}
6468 					/* count this one */
6469 					count++;
6470 				}
6471 			}
6472 		}
6473 	} else {
6474 		/*
6475 		 * subset bound case
6476 		 */
6477 		struct sctp_laddr *laddr;
6478 
6479 		LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list,
6480 		    sctp_nxt_addr) {
6481 			if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
6482 				continue;
6483 			}
6484 			/* count this one */
6485 			count++;
6486 		}
6487 	}
6488 	SCTP_IPI_ADDR_RUNLOCK();
6489 	return (count);
6490 }
6491 
6492 #if defined(SCTP_LOCAL_TRACE_BUF)
6493 
6494 void
6495 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)
6496 {
6497 	uint32_t saveindex, newindex;
6498 
6499 	do {
6500 		saveindex = sctp_log.index;
6501 		if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
6502 			newindex = 1;
6503 		} else {
6504 			newindex = saveindex + 1;
6505 		}
6506 	} while (atomic_cmpset_int(&sctp_log.index, saveindex, newindex) == 0);
6507 	if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
6508 		saveindex = 0;
6509 	}
6510 	sctp_log.entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
6511 	sctp_log.entry[saveindex].subsys = subsys;
6512 	sctp_log.entry[saveindex].params[0] = a;
6513 	sctp_log.entry[saveindex].params[1] = b;
6514 	sctp_log.entry[saveindex].params[2] = c;
6515 	sctp_log.entry[saveindex].params[3] = d;
6516 	sctp_log.entry[saveindex].params[4] = e;
6517 	sctp_log.entry[saveindex].params[5] = f;
6518 }
6519 
6520 #endif
6521