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