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