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