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