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