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