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