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