1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * a) Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * b) Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the distribution.
17 *
18 * c) Neither the name of Cisco Systems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #ifdef __FreeBSD__
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 361225 2020-05-18 19:23:01Z tuexen $");
38 #endif
39
40 #include <netinet/sctp_os.h>
41 #include <netinet/sctp_pcb.h>
42 #include <netinet/sctputil.h>
43 #include <netinet/sctp_var.h>
44 #include <netinet/sctp_sysctl.h>
45 #ifdef INET6
46 #if defined(__Userspace__) || defined(__FreeBSD__)
47 #include <netinet6/sctp6_var.h>
48 #endif
49 #endif
50 #include <netinet/sctp_header.h>
51 #include <netinet/sctp_output.h>
52 #include <netinet/sctp_uio.h>
53 #include <netinet/sctp_timer.h>
54 #include <netinet/sctp_indata.h>
55 #include <netinet/sctp_auth.h>
56 #include <netinet/sctp_asconf.h>
57 #include <netinet/sctp_bsd_addr.h>
58 #if defined(__Userspace__)
59 #include <netinet/sctp_constants.h>
60 #endif
61 #if defined(__FreeBSD__)
62 #include <netinet/sctp_kdtrace.h>
63 #if defined(INET6) || defined(INET)
64 #include <netinet/tcp_var.h>
65 #endif
66 #include <netinet/udp.h>
67 #include <netinet/udp_var.h>
68 #include <sys/proc.h>
69 #ifdef INET6
70 #include <netinet/icmp6.h>
71 #endif
72 #endif
73
74 #if defined(__APPLE__)
75 #define APPLE_FILE_NO 8
76 #endif
77
78 #if defined(__Windows__)
79 #if !defined(SCTP_LOCAL_TRACE_BUF)
80 #include "eventrace_netinet.h"
81 #include "sctputil.tmh" /* this is the file that will be auto generated */
82 #endif
83 #else
84 #ifndef KTR_SCTP
85 #define KTR_SCTP KTR_SUBSYS
86 #endif
87 #endif
88
89 extern const struct sctp_cc_functions sctp_cc_functions[];
90 extern const struct sctp_ss_functions sctp_ss_functions[];
91
92 void
sctp_sblog(struct sockbuf * sb,struct sctp_tcb * stcb,int from,int incr)93 sctp_sblog(struct sockbuf *sb, struct sctp_tcb *stcb, int from, int incr)
94 {
95 #if defined(SCTP_LOCAL_TRACE_BUF)
96 struct sctp_cwnd_log sctp_clog;
97
98 sctp_clog.x.sb.stcb = stcb;
99 sctp_clog.x.sb.so_sbcc = sb->sb_cc;
100 if (stcb)
101 sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc;
102 else
103 sctp_clog.x.sb.stcb_sbcc = 0;
104 sctp_clog.x.sb.incr = incr;
105 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
106 SCTP_LOG_EVENT_SB,
107 from,
108 sctp_clog.x.misc.log1,
109 sctp_clog.x.misc.log2,
110 sctp_clog.x.misc.log3,
111 sctp_clog.x.misc.log4);
112 #endif
113 }
114
115 void
sctp_log_closing(struct sctp_inpcb * inp,struct sctp_tcb * stcb,int16_t loc)116 sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc)
117 {
118 #if defined(SCTP_LOCAL_TRACE_BUF)
119 struct sctp_cwnd_log sctp_clog;
120
121 sctp_clog.x.close.inp = (void *)inp;
122 sctp_clog.x.close.sctp_flags = inp->sctp_flags;
123 if (stcb) {
124 sctp_clog.x.close.stcb = (void *)stcb;
125 sctp_clog.x.close.state = (uint16_t)stcb->asoc.state;
126 } else {
127 sctp_clog.x.close.stcb = 0;
128 sctp_clog.x.close.state = 0;
129 }
130 sctp_clog.x.close.loc = loc;
131 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
132 SCTP_LOG_EVENT_CLOSE,
133 0,
134 sctp_clog.x.misc.log1,
135 sctp_clog.x.misc.log2,
136 sctp_clog.x.misc.log3,
137 sctp_clog.x.misc.log4);
138 #endif
139 }
140
141 void
rto_logging(struct sctp_nets * net,int from)142 rto_logging(struct sctp_nets *net, int from)
143 {
144 #if defined(SCTP_LOCAL_TRACE_BUF)
145 struct sctp_cwnd_log sctp_clog;
146
147 memset(&sctp_clog, 0, sizeof(sctp_clog));
148 sctp_clog.x.rto.net = (void *) net;
149 sctp_clog.x.rto.rtt = net->rtt / 1000;
150 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
151 SCTP_LOG_EVENT_RTT,
152 from,
153 sctp_clog.x.misc.log1,
154 sctp_clog.x.misc.log2,
155 sctp_clog.x.misc.log3,
156 sctp_clog.x.misc.log4);
157 #endif
158 }
159
160 void
sctp_log_strm_del_alt(struct sctp_tcb * stcb,uint32_t tsn,uint16_t sseq,uint16_t stream,int from)161 sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16_t stream, int from)
162 {
163 #if defined(SCTP_LOCAL_TRACE_BUF)
164 struct sctp_cwnd_log sctp_clog;
165
166 sctp_clog.x.strlog.stcb = stcb;
167 sctp_clog.x.strlog.n_tsn = tsn;
168 sctp_clog.x.strlog.n_sseq = sseq;
169 sctp_clog.x.strlog.e_tsn = 0;
170 sctp_clog.x.strlog.e_sseq = 0;
171 sctp_clog.x.strlog.strm = stream;
172 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
173 SCTP_LOG_EVENT_STRM,
174 from,
175 sctp_clog.x.misc.log1,
176 sctp_clog.x.misc.log2,
177 sctp_clog.x.misc.log3,
178 sctp_clog.x.misc.log4);
179 #endif
180 }
181
182 void
sctp_log_nagle_event(struct sctp_tcb * stcb,int action)183 sctp_log_nagle_event(struct sctp_tcb *stcb, int action)
184 {
185 #if defined(SCTP_LOCAL_TRACE_BUF)
186 struct sctp_cwnd_log sctp_clog;
187
188 sctp_clog.x.nagle.stcb = (void *)stcb;
189 sctp_clog.x.nagle.total_flight = stcb->asoc.total_flight;
190 sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size;
191 sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue;
192 sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count;
193 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
194 SCTP_LOG_EVENT_NAGLE,
195 action,
196 sctp_clog.x.misc.log1,
197 sctp_clog.x.misc.log2,
198 sctp_clog.x.misc.log3,
199 sctp_clog.x.misc.log4);
200 #endif
201 }
202
203 void
sctp_log_sack(uint32_t old_cumack,uint32_t cumack,uint32_t tsn,uint16_t gaps,uint16_t dups,int from)204 sctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps, uint16_t dups, int from)
205 {
206 #if defined(SCTP_LOCAL_TRACE_BUF)
207 struct sctp_cwnd_log sctp_clog;
208
209 sctp_clog.x.sack.cumack = cumack;
210 sctp_clog.x.sack.oldcumack = old_cumack;
211 sctp_clog.x.sack.tsn = tsn;
212 sctp_clog.x.sack.numGaps = gaps;
213 sctp_clog.x.sack.numDups = dups;
214 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
215 SCTP_LOG_EVENT_SACK,
216 from,
217 sctp_clog.x.misc.log1,
218 sctp_clog.x.misc.log2,
219 sctp_clog.x.misc.log3,
220 sctp_clog.x.misc.log4);
221 #endif
222 }
223
224 void
sctp_log_map(uint32_t map,uint32_t cum,uint32_t high,int from)225 sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
226 {
227 #if defined(SCTP_LOCAL_TRACE_BUF)
228 struct sctp_cwnd_log sctp_clog;
229
230 memset(&sctp_clog, 0, sizeof(sctp_clog));
231 sctp_clog.x.map.base = map;
232 sctp_clog.x.map.cum = cum;
233 sctp_clog.x.map.high = high;
234 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
235 SCTP_LOG_EVENT_MAP,
236 from,
237 sctp_clog.x.misc.log1,
238 sctp_clog.x.misc.log2,
239 sctp_clog.x.misc.log3,
240 sctp_clog.x.misc.log4);
241 #endif
242 }
243
244 void
sctp_log_fr(uint32_t biggest_tsn,uint32_t biggest_new_tsn,uint32_t tsn,int from)245 sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int from)
246 {
247 #if defined(SCTP_LOCAL_TRACE_BUF)
248 struct sctp_cwnd_log sctp_clog;
249
250 memset(&sctp_clog, 0, sizeof(sctp_clog));
251 sctp_clog.x.fr.largest_tsn = biggest_tsn;
252 sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn;
253 sctp_clog.x.fr.tsn = tsn;
254 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
255 SCTP_LOG_EVENT_FR,
256 from,
257 sctp_clog.x.misc.log1,
258 sctp_clog.x.misc.log2,
259 sctp_clog.x.misc.log3,
260 sctp_clog.x.misc.log4);
261 #endif
262 }
263
264 #ifdef SCTP_MBUF_LOGGING
265 void
sctp_log_mb(struct mbuf * m,int from)266 sctp_log_mb(struct mbuf *m, int from)
267 {
268 #if defined(SCTP_LOCAL_TRACE_BUF)
269 struct sctp_cwnd_log sctp_clog;
270
271 sctp_clog.x.mb.mp = m;
272 sctp_clog.x.mb.mbuf_flags = (uint8_t)(SCTP_BUF_GET_FLAGS(m));
273 sctp_clog.x.mb.size = (uint16_t)(SCTP_BUF_LEN(m));
274 sctp_clog.x.mb.data = SCTP_BUF_AT(m, 0);
275 if (SCTP_BUF_IS_EXTENDED(m)) {
276 sctp_clog.x.mb.ext = SCTP_BUF_EXTEND_BASE(m);
277 #if defined(__APPLE__)
278 /* APPLE does not use a ref_cnt, but a forward/backward ref queue */
279 #else
280 sctp_clog.x.mb.refcnt = (uint8_t)(SCTP_BUF_EXTEND_REFCNT(m));
281 #endif
282 } else {
283 sctp_clog.x.mb.ext = 0;
284 sctp_clog.x.mb.refcnt = 0;
285 }
286 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
287 SCTP_LOG_EVENT_MBUF,
288 from,
289 sctp_clog.x.misc.log1,
290 sctp_clog.x.misc.log2,
291 sctp_clog.x.misc.log3,
292 sctp_clog.x.misc.log4);
293 #endif
294 }
295
296 void
sctp_log_mbc(struct mbuf * m,int from)297 sctp_log_mbc(struct mbuf *m, int from)
298 {
299 struct mbuf *mat;
300
301 for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
302 sctp_log_mb(mat, from);
303 }
304 }
305 #endif
306
307 void
sctp_log_strm_del(struct sctp_queued_to_read * control,struct sctp_queued_to_read * poschk,int from)308 sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk, int from)
309 {
310 #if defined(SCTP_LOCAL_TRACE_BUF)
311 struct sctp_cwnd_log sctp_clog;
312
313 if (control == NULL) {
314 SCTP_PRINTF("Gak log of NULL?\n");
315 return;
316 }
317 sctp_clog.x.strlog.stcb = control->stcb;
318 sctp_clog.x.strlog.n_tsn = control->sinfo_tsn;
319 sctp_clog.x.strlog.n_sseq = (uint16_t)control->mid;
320 sctp_clog.x.strlog.strm = control->sinfo_stream;
321 if (poschk != NULL) {
322 sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn;
323 sctp_clog.x.strlog.e_sseq = (uint16_t)poschk->mid;
324 } else {
325 sctp_clog.x.strlog.e_tsn = 0;
326 sctp_clog.x.strlog.e_sseq = 0;
327 }
328 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
329 SCTP_LOG_EVENT_STRM,
330 from,
331 sctp_clog.x.misc.log1,
332 sctp_clog.x.misc.log2,
333 sctp_clog.x.misc.log3,
334 sctp_clog.x.misc.log4);
335 #endif
336 }
337
338 void
sctp_log_cwnd(struct sctp_tcb * stcb,struct sctp_nets * net,int augment,uint8_t from)339 sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
340 {
341 #if defined(SCTP_LOCAL_TRACE_BUF)
342 struct sctp_cwnd_log sctp_clog;
343
344 sctp_clog.x.cwnd.net = net;
345 if (stcb->asoc.send_queue_cnt > 255)
346 sctp_clog.x.cwnd.cnt_in_send = 255;
347 else
348 sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
349 if (stcb->asoc.stream_queue_cnt > 255)
350 sctp_clog.x.cwnd.cnt_in_str = 255;
351 else
352 sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
353
354 if (net) {
355 sctp_clog.x.cwnd.cwnd_new_value = net->cwnd;
356 sctp_clog.x.cwnd.inflight = net->flight_size;
357 sctp_clog.x.cwnd.pseudo_cumack = net->pseudo_cumack;
358 sctp_clog.x.cwnd.meets_pseudo_cumack = net->new_pseudo_cumack;
359 sctp_clog.x.cwnd.need_new_pseudo_cumack = net->find_pseudo_cumack;
360 }
361 if (SCTP_CWNDLOG_PRESEND == from) {
362 sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd;
363 }
364 sctp_clog.x.cwnd.cwnd_augment = augment;
365 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
366 SCTP_LOG_EVENT_CWND,
367 from,
368 sctp_clog.x.misc.log1,
369 sctp_clog.x.misc.log2,
370 sctp_clog.x.misc.log3,
371 sctp_clog.x.misc.log4);
372 #endif
373 }
374
375 #ifndef __APPLE__
376 void
sctp_log_lock(struct sctp_inpcb * inp,struct sctp_tcb * stcb,uint8_t from)377 sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from)
378 {
379 #if defined(SCTP_LOCAL_TRACE_BUF)
380 struct sctp_cwnd_log sctp_clog;
381
382 memset(&sctp_clog, 0, sizeof(sctp_clog));
383 if (inp) {
384 sctp_clog.x.lock.sock = (void *) inp->sctp_socket;
385
386 } else {
387 sctp_clog.x.lock.sock = (void *) NULL;
388 }
389 sctp_clog.x.lock.inp = (void *) inp;
390 #if (defined(__FreeBSD__) && __FreeBSD_version >= 503000) || (defined(__APPLE__))
391 if (stcb) {
392 sctp_clog.x.lock.tcb_lock = mtx_owned(&stcb->tcb_mtx);
393 } else {
394 sctp_clog.x.lock.tcb_lock = SCTP_LOCK_UNKNOWN;
395 }
396 if (inp) {
397 sctp_clog.x.lock.inp_lock = mtx_owned(&inp->inp_mtx);
398 sctp_clog.x.lock.create_lock = mtx_owned(&inp->inp_create_mtx);
399 } else {
400 sctp_clog.x.lock.inp_lock = SCTP_LOCK_UNKNOWN;
401 sctp_clog.x.lock.create_lock = SCTP_LOCK_UNKNOWN;
402 }
403 #if (defined(__FreeBSD__) && __FreeBSD_version <= 602000)
404 sctp_clog.x.lock.info_lock = mtx_owned(&SCTP_BASE_INFO(ipi_ep_mtx));
405 #else
406 sctp_clog.x.lock.info_lock = rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx));
407 #endif
408 if (inp && (inp->sctp_socket)) {
409 sctp_clog.x.lock.sock_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
410 sctp_clog.x.lock.sockrcvbuf_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx));
411 sctp_clog.x.lock.socksndbuf_lock = mtx_owned(&(inp->sctp_socket->so_snd.sb_mtx));
412 } else {
413 sctp_clog.x.lock.sock_lock = SCTP_LOCK_UNKNOWN;
414 sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN;
415 sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN;
416 }
417 #endif
418 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
419 SCTP_LOG_LOCK_EVENT,
420 from,
421 sctp_clog.x.misc.log1,
422 sctp_clog.x.misc.log2,
423 sctp_clog.x.misc.log3,
424 sctp_clog.x.misc.log4);
425 #endif
426 }
427 #endif
428
429 void
sctp_log_maxburst(struct sctp_tcb * stcb,struct sctp_nets * net,int error,int burst,uint8_t from)430 sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from)
431 {
432 #if defined(SCTP_LOCAL_TRACE_BUF)
433 struct sctp_cwnd_log sctp_clog;
434
435 memset(&sctp_clog, 0, sizeof(sctp_clog));
436 sctp_clog.x.cwnd.net = net;
437 sctp_clog.x.cwnd.cwnd_new_value = error;
438 sctp_clog.x.cwnd.inflight = net->flight_size;
439 sctp_clog.x.cwnd.cwnd_augment = burst;
440 if (stcb->asoc.send_queue_cnt > 255)
441 sctp_clog.x.cwnd.cnt_in_send = 255;
442 else
443 sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt;
444 if (stcb->asoc.stream_queue_cnt > 255)
445 sctp_clog.x.cwnd.cnt_in_str = 255;
446 else
447 sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
448 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
449 SCTP_LOG_EVENT_MAXBURST,
450 from,
451 sctp_clog.x.misc.log1,
452 sctp_clog.x.misc.log2,
453 sctp_clog.x.misc.log3,
454 sctp_clog.x.misc.log4);
455 #endif
456 }
457
458 void
sctp_log_rwnd(uint8_t from,uint32_t peers_rwnd,uint32_t snd_size,uint32_t overhead)459 sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead)
460 {
461 #if defined(SCTP_LOCAL_TRACE_BUF)
462 struct sctp_cwnd_log sctp_clog;
463
464 sctp_clog.x.rwnd.rwnd = peers_rwnd;
465 sctp_clog.x.rwnd.send_size = snd_size;
466 sctp_clog.x.rwnd.overhead = overhead;
467 sctp_clog.x.rwnd.new_rwnd = 0;
468 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
469 SCTP_LOG_EVENT_RWND,
470 from,
471 sctp_clog.x.misc.log1,
472 sctp_clog.x.misc.log2,
473 sctp_clog.x.misc.log3,
474 sctp_clog.x.misc.log4);
475 #endif
476 }
477
478 void
sctp_log_rwnd_set(uint8_t from,uint32_t peers_rwnd,uint32_t flight_size,uint32_t overhead,uint32_t a_rwndval)479 sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint32_t overhead, uint32_t a_rwndval)
480 {
481 #if defined(SCTP_LOCAL_TRACE_BUF)
482 struct sctp_cwnd_log sctp_clog;
483
484 sctp_clog.x.rwnd.rwnd = peers_rwnd;
485 sctp_clog.x.rwnd.send_size = flight_size;
486 sctp_clog.x.rwnd.overhead = overhead;
487 sctp_clog.x.rwnd.new_rwnd = a_rwndval;
488 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
489 SCTP_LOG_EVENT_RWND,
490 from,
491 sctp_clog.x.misc.log1,
492 sctp_clog.x.misc.log2,
493 sctp_clog.x.misc.log3,
494 sctp_clog.x.misc.log4);
495 #endif
496 }
497
498 #ifdef SCTP_MBCNT_LOGGING
499 static void
sctp_log_mbcnt(uint8_t from,uint32_t total_oq,uint32_t book,uint32_t total_mbcnt_q,uint32_t mbcnt)500 sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt)
501 {
502 #if defined(SCTP_LOCAL_TRACE_BUF)
503 struct sctp_cwnd_log sctp_clog;
504
505 sctp_clog.x.mbcnt.total_queue_size = total_oq;
506 sctp_clog.x.mbcnt.size_change = book;
507 sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q;
508 sctp_clog.x.mbcnt.mbcnt_change = mbcnt;
509 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
510 SCTP_LOG_EVENT_MBCNT,
511 from,
512 sctp_clog.x.misc.log1,
513 sctp_clog.x.misc.log2,
514 sctp_clog.x.misc.log3,
515 sctp_clog.x.misc.log4);
516 #endif
517 }
518 #endif
519
520 void
sctp_misc_ints(uint8_t from,uint32_t a,uint32_t b,uint32_t c,uint32_t d)521 sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
522 {
523 #if defined(SCTP_LOCAL_TRACE_BUF)
524 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
525 SCTP_LOG_MISC_EVENT,
526 from,
527 a, b, c, d);
528 #endif
529 }
530
531 void
sctp_wakeup_log(struct sctp_tcb * stcb,uint32_t wake_cnt,int from)532 sctp_wakeup_log(struct sctp_tcb *stcb, uint32_t wake_cnt, int from)
533 {
534 #if defined(SCTP_LOCAL_TRACE_BUF)
535 struct sctp_cwnd_log sctp_clog;
536
537 sctp_clog.x.wake.stcb = (void *)stcb;
538 sctp_clog.x.wake.wake_cnt = wake_cnt;
539 sctp_clog.x.wake.flight = stcb->asoc.total_flight_count;
540 sctp_clog.x.wake.send_q = stcb->asoc.send_queue_cnt;
541 sctp_clog.x.wake.sent_q = stcb->asoc.sent_queue_cnt;
542
543 if (stcb->asoc.stream_queue_cnt < 0xff)
544 sctp_clog.x.wake.stream_qcnt = (uint8_t) stcb->asoc.stream_queue_cnt;
545 else
546 sctp_clog.x.wake.stream_qcnt = 0xff;
547
548 if (stcb->asoc.chunks_on_out_queue < 0xff)
549 sctp_clog.x.wake.chunks_on_oque = (uint8_t) stcb->asoc.chunks_on_out_queue;
550 else
551 sctp_clog.x.wake.chunks_on_oque = 0xff;
552
553 sctp_clog.x.wake.sctpflags = 0;
554 /* set in the defered mode stuff */
555 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE)
556 sctp_clog.x.wake.sctpflags |= 1;
557 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT)
558 sctp_clog.x.wake.sctpflags |= 2;
559 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT)
560 sctp_clog.x.wake.sctpflags |= 4;
561 /* what about the sb */
562 if (stcb->sctp_socket) {
563 struct socket *so = stcb->sctp_socket;
564
565 sctp_clog.x.wake.sbflags = (uint8_t)((so->so_snd.sb_flags & 0x00ff));
566 } else {
567 sctp_clog.x.wake.sbflags = 0xff;
568 }
569 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
570 SCTP_LOG_EVENT_WAKE,
571 from,
572 sctp_clog.x.misc.log1,
573 sctp_clog.x.misc.log2,
574 sctp_clog.x.misc.log3,
575 sctp_clog.x.misc.log4);
576 #endif
577 }
578
579 void
sctp_log_block(uint8_t from,struct sctp_association * asoc,ssize_t sendlen)580 sctp_log_block(uint8_t from, struct sctp_association *asoc, ssize_t sendlen)
581 {
582 #if defined(SCTP_LOCAL_TRACE_BUF)
583 struct sctp_cwnd_log sctp_clog;
584
585 sctp_clog.x.blk.onsb = asoc->total_output_queue_size;
586 sctp_clog.x.blk.send_sent_qcnt = (uint16_t) (asoc->send_queue_cnt + asoc->sent_queue_cnt);
587 sctp_clog.x.blk.peer_rwnd = asoc->peers_rwnd;
588 sctp_clog.x.blk.stream_qcnt = (uint16_t) asoc->stream_queue_cnt;
589 sctp_clog.x.blk.chunks_on_oque = (uint16_t) asoc->chunks_on_out_queue;
590 sctp_clog.x.blk.flight_size = (uint16_t) (asoc->total_flight/1024);
591 sctp_clog.x.blk.sndlen = (uint32_t)sendlen;
592 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
593 SCTP_LOG_EVENT_BLOCK,
594 from,
595 sctp_clog.x.misc.log1,
596 sctp_clog.x.misc.log2,
597 sctp_clog.x.misc.log3,
598 sctp_clog.x.misc.log4);
599 #endif
600 }
601
602 int
sctp_fill_stat_log(void * optval SCTP_UNUSED,size_t * optsize SCTP_UNUSED)603 sctp_fill_stat_log(void *optval SCTP_UNUSED, size_t *optsize SCTP_UNUSED)
604 {
605 /* May need to fix this if ktrdump does not work */
606 return (0);
607 }
608
609 #ifdef SCTP_AUDITING_ENABLED
610 uint8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
611 static int sctp_audit_indx = 0;
612
613 static
614 void
sctp_print_audit_report(void)615 sctp_print_audit_report(void)
616 {
617 int i;
618 int cnt;
619
620 cnt = 0;
621 for (i = sctp_audit_indx; i < SCTP_AUDIT_SIZE; i++) {
622 if ((sctp_audit_data[i][0] == 0xe0) &&
623 (sctp_audit_data[i][1] == 0x01)) {
624 cnt = 0;
625 SCTP_PRINTF("\n");
626 } else if (sctp_audit_data[i][0] == 0xf0) {
627 cnt = 0;
628 SCTP_PRINTF("\n");
629 } else if ((sctp_audit_data[i][0] == 0xc0) &&
630 (sctp_audit_data[i][1] == 0x01)) {
631 SCTP_PRINTF("\n");
632 cnt = 0;
633 }
634 SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
635 (uint32_t) sctp_audit_data[i][1]);
636 cnt++;
637 if ((cnt % 14) == 0)
638 SCTP_PRINTF("\n");
639 }
640 for (i = 0; i < sctp_audit_indx; i++) {
641 if ((sctp_audit_data[i][0] == 0xe0) &&
642 (sctp_audit_data[i][1] == 0x01)) {
643 cnt = 0;
644 SCTP_PRINTF("\n");
645 } else if (sctp_audit_data[i][0] == 0xf0) {
646 cnt = 0;
647 SCTP_PRINTF("\n");
648 } else if ((sctp_audit_data[i][0] == 0xc0) &&
649 (sctp_audit_data[i][1] == 0x01)) {
650 SCTP_PRINTF("\n");
651 cnt = 0;
652 }
653 SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0],
654 (uint32_t) sctp_audit_data[i][1]);
655 cnt++;
656 if ((cnt % 14) == 0)
657 SCTP_PRINTF("\n");
658 }
659 SCTP_PRINTF("\n");
660 }
661
662 void
sctp_auditing(int from,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net)663 sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
664 struct sctp_nets *net)
665 {
666 int resend_cnt, tot_out, rep, tot_book_cnt;
667 struct sctp_nets *lnet;
668 struct sctp_tmit_chunk *chk;
669
670 sctp_audit_data[sctp_audit_indx][0] = 0xAA;
671 sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
672 sctp_audit_indx++;
673 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
674 sctp_audit_indx = 0;
675 }
676 if (inp == NULL) {
677 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
678 sctp_audit_data[sctp_audit_indx][1] = 0x01;
679 sctp_audit_indx++;
680 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
681 sctp_audit_indx = 0;
682 }
683 return;
684 }
685 if (stcb == NULL) {
686 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
687 sctp_audit_data[sctp_audit_indx][1] = 0x02;
688 sctp_audit_indx++;
689 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
690 sctp_audit_indx = 0;
691 }
692 return;
693 }
694 sctp_audit_data[sctp_audit_indx][0] = 0xA1;
695 sctp_audit_data[sctp_audit_indx][1] =
696 (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
697 sctp_audit_indx++;
698 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
699 sctp_audit_indx = 0;
700 }
701 rep = 0;
702 tot_book_cnt = 0;
703 resend_cnt = tot_out = 0;
704 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
705 if (chk->sent == SCTP_DATAGRAM_RESEND) {
706 resend_cnt++;
707 } else if (chk->sent < SCTP_DATAGRAM_RESEND) {
708 tot_out += chk->book_size;
709 tot_book_cnt++;
710 }
711 }
712 if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
713 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
714 sctp_audit_data[sctp_audit_indx][1] = 0xA1;
715 sctp_audit_indx++;
716 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
717 sctp_audit_indx = 0;
718 }
719 SCTP_PRINTF("resend_cnt:%d asoc-tot:%d\n",
720 resend_cnt, stcb->asoc.sent_queue_retran_cnt);
721 rep = 1;
722 stcb->asoc.sent_queue_retran_cnt = resend_cnt;
723 sctp_audit_data[sctp_audit_indx][0] = 0xA2;
724 sctp_audit_data[sctp_audit_indx][1] =
725 (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
726 sctp_audit_indx++;
727 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
728 sctp_audit_indx = 0;
729 }
730 }
731 if (tot_out != stcb->asoc.total_flight) {
732 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
733 sctp_audit_data[sctp_audit_indx][1] = 0xA2;
734 sctp_audit_indx++;
735 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
736 sctp_audit_indx = 0;
737 }
738 rep = 1;
739 SCTP_PRINTF("tot_flt:%d asoc_tot:%d\n", tot_out,
740 (int)stcb->asoc.total_flight);
741 stcb->asoc.total_flight = tot_out;
742 }
743 if (tot_book_cnt != stcb->asoc.total_flight_count) {
744 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
745 sctp_audit_data[sctp_audit_indx][1] = 0xA5;
746 sctp_audit_indx++;
747 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
748 sctp_audit_indx = 0;
749 }
750 rep = 1;
751 SCTP_PRINTF("tot_flt_book:%d\n", tot_book_cnt);
752
753 stcb->asoc.total_flight_count = tot_book_cnt;
754 }
755 tot_out = 0;
756 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
757 tot_out += lnet->flight_size;
758 }
759 if (tot_out != stcb->asoc.total_flight) {
760 sctp_audit_data[sctp_audit_indx][0] = 0xAF;
761 sctp_audit_data[sctp_audit_indx][1] = 0xA3;
762 sctp_audit_indx++;
763 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
764 sctp_audit_indx = 0;
765 }
766 rep = 1;
767 SCTP_PRINTF("real flight:%d net total was %d\n",
768 stcb->asoc.total_flight, tot_out);
769 /* now corrective action */
770 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
771
772 tot_out = 0;
773 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
774 if ((chk->whoTo == lnet) &&
775 (chk->sent < SCTP_DATAGRAM_RESEND)) {
776 tot_out += chk->book_size;
777 }
778 }
779 if (lnet->flight_size != tot_out) {
780 SCTP_PRINTF("net:%p flight was %d corrected to %d\n",
781 (void *)lnet, lnet->flight_size,
782 tot_out);
783 lnet->flight_size = tot_out;
784 }
785 }
786 }
787 if (rep) {
788 sctp_print_audit_report();
789 }
790 }
791
792 void
sctp_audit_log(uint8_t ev,uint8_t fd)793 sctp_audit_log(uint8_t ev, uint8_t fd)
794 {
795
796 sctp_audit_data[sctp_audit_indx][0] = ev;
797 sctp_audit_data[sctp_audit_indx][1] = fd;
798 sctp_audit_indx++;
799 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
800 sctp_audit_indx = 0;
801 }
802 }
803
804 #endif
805
806 /*
807 * The conversion from time to ticks and vice versa is done by rounding
808 * upwards. This way we can test in the code the time to be positive and
809 * know that this corresponds to a positive number of ticks.
810 */
811
812 uint32_t
sctp_msecs_to_ticks(uint32_t msecs)813 sctp_msecs_to_ticks(uint32_t msecs)
814 {
815 uint64_t temp;
816 uint32_t ticks;
817
818 if (hz == 1000) {
819 ticks = msecs;
820 } else {
821 temp = (((uint64_t)msecs * hz) + 999) / 1000;
822 if (temp > UINT32_MAX) {
823 ticks = UINT32_MAX;
824 } else {
825 ticks = (uint32_t)temp;
826 }
827 }
828 return (ticks);
829 }
830
831 uint32_t
sctp_ticks_to_msecs(uint32_t ticks)832 sctp_ticks_to_msecs(uint32_t ticks)
833 {
834 uint64_t temp;
835 uint32_t msecs;
836
837 if (hz == 1000) {
838 msecs = ticks;
839 } else {
840 temp = (((uint64_t)ticks * 1000) + (hz - 1)) / hz;
841 if (temp > UINT32_MAX) {
842 msecs = UINT32_MAX;
843 } else {
844 msecs = (uint32_t)temp;
845 }
846 }
847 return (msecs);
848 }
849
850 uint32_t
sctp_secs_to_ticks(uint32_t secs)851 sctp_secs_to_ticks(uint32_t secs)
852 {
853 uint64_t temp;
854 uint32_t ticks;
855
856 temp = (uint64_t)secs * hz;
857 if (temp > UINT32_MAX) {
858 ticks = UINT32_MAX;
859 } else {
860 ticks = (uint32_t)temp;
861 }
862 return (ticks);
863 }
864
865 uint32_t
sctp_ticks_to_secs(uint32_t ticks)866 sctp_ticks_to_secs(uint32_t ticks)
867 {
868 uint64_t temp;
869 uint32_t secs;
870
871 temp = ((uint64_t)ticks + (hz - 1)) / hz;
872 if (temp > UINT32_MAX) {
873 secs = UINT32_MAX;
874 } else {
875 secs = (uint32_t)temp;
876 }
877 return (secs);
878 }
879
880 /*
881 * sctp_stop_timers_for_shutdown() should be called
882 * when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT
883 * state to make sure that all timers are stopped.
884 */
885 void
sctp_stop_timers_for_shutdown(struct sctp_tcb * stcb)886 sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
887 {
888 struct sctp_inpcb *inp;
889 struct sctp_nets *net;
890
891 inp = stcb->sctp_ep;
892
893 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
894 SCTP_FROM_SCTPUTIL + SCTP_LOC_12);
895 sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
896 SCTP_FROM_SCTPUTIL + SCTP_LOC_13);
897 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
898 SCTP_FROM_SCTPUTIL + SCTP_LOC_14);
899 sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
900 SCTP_FROM_SCTPUTIL + SCTP_LOC_15);
901 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
902 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
903 SCTP_FROM_SCTPUTIL + SCTP_LOC_16);
904 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
905 SCTP_FROM_SCTPUTIL + SCTP_LOC_17);
906 }
907 }
908
909 void
sctp_stop_association_timers(struct sctp_tcb * stcb,bool stop_assoc_kill_timer)910 sctp_stop_association_timers(struct sctp_tcb *stcb, bool stop_assoc_kill_timer)
911 {
912 struct sctp_inpcb *inp;
913 struct sctp_nets *net;
914
915 inp = stcb->sctp_ep;
916 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
917 SCTP_FROM_SCTPUTIL + SCTP_LOC_18);
918 sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
919 SCTP_FROM_SCTPUTIL + SCTP_LOC_19);
920 if (stop_assoc_kill_timer) {
921 sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
922 SCTP_FROM_SCTPUTIL + SCTP_LOC_20);
923 }
924 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
925 SCTP_FROM_SCTPUTIL + SCTP_LOC_21);
926 sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
927 SCTP_FROM_SCTPUTIL + SCTP_LOC_22);
928 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNGUARD, inp, stcb, NULL,
929 SCTP_FROM_SCTPUTIL + SCTP_LOC_23);
930 /* Mobility adaptation */
931 sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, inp, stcb, NULL,
932 SCTP_FROM_SCTPUTIL + SCTP_LOC_24);
933 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
934 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
935 SCTP_FROM_SCTPUTIL + SCTP_LOC_25);
936 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
937 SCTP_FROM_SCTPUTIL + SCTP_LOC_26);
938 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, net,
939 SCTP_FROM_SCTPUTIL + SCTP_LOC_27);
940 sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net,
941 SCTP_FROM_SCTPUTIL + SCTP_LOC_28);
942 sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, net,
943 SCTP_FROM_SCTPUTIL + SCTP_LOC_29);
944 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
945 SCTP_FROM_SCTPUTIL + SCTP_LOC_30);
946 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
947 SCTP_FROM_SCTPUTIL + SCTP_LOC_31);
948 }
949 }
950
951 /*
952 * A list of sizes based on typical mtu's, used only if next hop size not
953 * returned. These values MUST be multiples of 4 and MUST be ordered.
954 */
955 static uint32_t sctp_mtu_sizes[] = {
956 68,
957 296,
958 508,
959 512,
960 544,
961 576,
962 1004,
963 1492,
964 1500,
965 1536,
966 2000,
967 2048,
968 4352,
969 4464,
970 8168,
971 17912,
972 32000,
973 65532
974 };
975
976 /*
977 * Return the largest MTU in sctp_mtu_sizes smaller than val.
978 * If val is smaller than the minimum, just return the largest
979 * multiple of 4 smaller or equal to val.
980 * Ensure that the result is a multiple of 4.
981 */
982 uint32_t
sctp_get_prev_mtu(uint32_t val)983 sctp_get_prev_mtu(uint32_t val)
984 {
985 uint32_t i;
986
987 val &= 0xfffffffc;
988 if (val <= sctp_mtu_sizes[0]) {
989 return (val);
990 }
991 for (i = 1; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) {
992 if (val <= sctp_mtu_sizes[i]) {
993 break;
994 }
995 }
996 KASSERT((sctp_mtu_sizes[i - 1] & 0x00000003) == 0,
997 ("sctp_mtu_sizes[%u] not a multiple of 4", i - 1));
998 return (sctp_mtu_sizes[i - 1]);
999 }
1000
1001 /*
1002 * Return the smallest MTU in sctp_mtu_sizes larger than val.
1003 * If val is larger than the maximum, just return the largest multiple of 4 smaller
1004 * or equal to val.
1005 * Ensure that the result is a multiple of 4.
1006 */
1007 uint32_t
sctp_get_next_mtu(uint32_t val)1008 sctp_get_next_mtu(uint32_t val)
1009 {
1010 /* select another MTU that is just bigger than this one */
1011 uint32_t i;
1012
1013 val &= 0xfffffffc;
1014 for (i = 0; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) {
1015 if (val < sctp_mtu_sizes[i]) {
1016 KASSERT((sctp_mtu_sizes[i] & 0x00000003) == 0,
1017 ("sctp_mtu_sizes[%u] not a multiple of 4", i));
1018 return (sctp_mtu_sizes[i]);
1019 }
1020 }
1021 return (val);
1022 }
1023
1024 void
sctp_fill_random_store(struct sctp_pcb * m)1025 sctp_fill_random_store(struct sctp_pcb *m)
1026 {
1027 /*
1028 * Here we use the MD5/SHA-1 to hash with our good randomNumbers and
1029 * our counter. The result becomes our good random numbers and we
1030 * then setup to give these out. Note that we do no locking to
1031 * protect this. This is ok, since if competing folks call this we
1032 * will get more gobbled gook in the random store which is what we
1033 * want. There is a danger that two guys will use the same random
1034 * numbers, but thats ok too since that is random as well :->
1035 */
1036 m->store_at = 0;
1037 #if defined(__Userspace__) && defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
1038 for (int i = 0; i < (int) (sizeof(m->random_store) / sizeof(m->random_store[0])); i++) {
1039 m->random_store[i] = (uint8_t) rand();
1040 }
1041 #else
1042 (void)sctp_hmac(SCTP_HMAC, (uint8_t *)m->random_numbers,
1043 sizeof(m->random_numbers), (uint8_t *)&m->random_counter,
1044 sizeof(m->random_counter), (uint8_t *)m->random_store);
1045 #endif
1046 m->random_counter++;
1047 }
1048
1049 uint32_t
sctp_select_initial_TSN(struct sctp_pcb * inp)1050 sctp_select_initial_TSN(struct sctp_pcb *inp)
1051 {
1052 /*
1053 * A true implementation should use random selection process to get
1054 * the initial stream sequence number, using RFC1750 as a good
1055 * guideline
1056 */
1057 uint32_t x, *xp;
1058 uint8_t *p;
1059 int store_at, new_store;
1060
1061 if (inp->initial_sequence_debug != 0) {
1062 uint32_t ret;
1063
1064 ret = inp->initial_sequence_debug;
1065 inp->initial_sequence_debug++;
1066 return (ret);
1067 }
1068 retry:
1069 store_at = inp->store_at;
1070 new_store = store_at + sizeof(uint32_t);
1071 if (new_store >= (SCTP_SIGNATURE_SIZE-3)) {
1072 new_store = 0;
1073 }
1074 if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) {
1075 goto retry;
1076 }
1077 if (new_store == 0) {
1078 /* Refill the random store */
1079 sctp_fill_random_store(inp);
1080 }
1081 p = &inp->random_store[store_at];
1082 xp = (uint32_t *)p;
1083 x = *xp;
1084 return (x);
1085 }
1086
1087 uint32_t
sctp_select_a_tag(struct sctp_inpcb * inp,uint16_t lport,uint16_t rport,int check)1088 sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check)
1089 {
1090 uint32_t x;
1091 struct timeval now;
1092
1093 if (check) {
1094 (void)SCTP_GETTIME_TIMEVAL(&now);
1095 }
1096 for (;;) {
1097 x = sctp_select_initial_TSN(&inp->sctp_ep);
1098 if (x == 0) {
1099 /* we never use 0 */
1100 continue;
1101 }
1102 if (!check || sctp_is_vtag_good(x, lport, rport, &now)) {
1103 break;
1104 }
1105 }
1106 return (x);
1107 }
1108
1109 int32_t
sctp_map_assoc_state(int kernel_state)1110 sctp_map_assoc_state(int kernel_state)
1111 {
1112 int32_t user_state;
1113
1114 if (kernel_state & SCTP_STATE_WAS_ABORTED) {
1115 user_state = SCTP_CLOSED;
1116 } else if (kernel_state & SCTP_STATE_SHUTDOWN_PENDING) {
1117 user_state = SCTP_SHUTDOWN_PENDING;
1118 } else {
1119 switch (kernel_state & SCTP_STATE_MASK) {
1120 case SCTP_STATE_EMPTY:
1121 user_state = SCTP_CLOSED;
1122 break;
1123 case SCTP_STATE_INUSE:
1124 user_state = SCTP_CLOSED;
1125 break;
1126 case SCTP_STATE_COOKIE_WAIT:
1127 user_state = SCTP_COOKIE_WAIT;
1128 break;
1129 case SCTP_STATE_COOKIE_ECHOED:
1130 user_state = SCTP_COOKIE_ECHOED;
1131 break;
1132 case SCTP_STATE_OPEN:
1133 user_state = SCTP_ESTABLISHED;
1134 break;
1135 case SCTP_STATE_SHUTDOWN_SENT:
1136 user_state = SCTP_SHUTDOWN_SENT;
1137 break;
1138 case SCTP_STATE_SHUTDOWN_RECEIVED:
1139 user_state = SCTP_SHUTDOWN_RECEIVED;
1140 break;
1141 case SCTP_STATE_SHUTDOWN_ACK_SENT:
1142 user_state = SCTP_SHUTDOWN_ACK_SENT;
1143 break;
1144 default:
1145 user_state = SCTP_CLOSED;
1146 break;
1147 }
1148 }
1149 return (user_state);
1150 }
1151
1152 int
sctp_init_asoc(struct sctp_inpcb * inp,struct sctp_tcb * stcb,uint32_t override_tag,uint32_t vrf_id,uint16_t o_strms)1153 sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1154 uint32_t override_tag, uint32_t vrf_id, uint16_t o_strms)
1155 {
1156 struct sctp_association *asoc;
1157 /*
1158 * Anything set to zero is taken care of by the allocation routine's
1159 * bzero
1160 */
1161
1162 /*
1163 * Up front select what scoping to apply on addresses I tell my peer
1164 * Not sure what to do with these right now, we will need to come up
1165 * with a way to set them. We may need to pass them through from the
1166 * caller in the sctp_aloc_assoc() function.
1167 */
1168 int i;
1169 #if defined(SCTP_DETAILED_STR_STATS)
1170 int j;
1171 #endif
1172
1173 asoc = &stcb->asoc;
1174 /* init all variables to a known value. */
1175 SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
1176 asoc->max_burst = inp->sctp_ep.max_burst;
1177 asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
1178 asoc->heart_beat_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
1179 asoc->cookie_life = inp->sctp_ep.def_cookie_life;
1180 asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
1181 asoc->ecn_supported = inp->ecn_supported;
1182 asoc->prsctp_supported = inp->prsctp_supported;
1183 asoc->auth_supported = inp->auth_supported;
1184 asoc->asconf_supported = inp->asconf_supported;
1185 asoc->reconfig_supported = inp->reconfig_supported;
1186 asoc->nrsack_supported = inp->nrsack_supported;
1187 asoc->pktdrop_supported = inp->pktdrop_supported;
1188 asoc->idata_supported = inp->idata_supported;
1189 asoc->sctp_cmt_pf = (uint8_t)0;
1190 asoc->sctp_frag_point = inp->sctp_frag_point;
1191 asoc->sctp_features = inp->sctp_features;
1192 asoc->default_dscp = inp->sctp_ep.default_dscp;
1193 asoc->max_cwnd = inp->max_cwnd;
1194 #ifdef INET6
1195 if (inp->sctp_ep.default_flowlabel) {
1196 asoc->default_flowlabel = inp->sctp_ep.default_flowlabel;
1197 } else {
1198 if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) {
1199 asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep);
1200 asoc->default_flowlabel &= 0x000fffff;
1201 asoc->default_flowlabel |= 0x80000000;
1202 } else {
1203 asoc->default_flowlabel = 0;
1204 }
1205 }
1206 #endif
1207 asoc->sb_send_resv = 0;
1208 if (override_tag) {
1209 asoc->my_vtag = override_tag;
1210 } else {
1211 asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1);
1212 }
1213 /* Get the nonce tags */
1214 asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1215 asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1216 asoc->vrf_id = vrf_id;
1217
1218 #ifdef SCTP_ASOCLOG_OF_TSNS
1219 asoc->tsn_in_at = 0;
1220 asoc->tsn_out_at = 0;
1221 asoc->tsn_in_wrapped = 0;
1222 asoc->tsn_out_wrapped = 0;
1223 asoc->cumack_log_at = 0;
1224 asoc->cumack_log_atsnt = 0;
1225 #endif
1226 #ifdef SCTP_FS_SPEC_LOG
1227 asoc->fs_index = 0;
1228 #endif
1229 asoc->refcnt = 0;
1230 asoc->assoc_up_sent = 0;
1231 asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
1232 sctp_select_initial_TSN(&inp->sctp_ep);
1233 asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
1234 /* we are optimisitic here */
1235 asoc->peer_supports_nat = 0;
1236 asoc->sent_queue_retran_cnt = 0;
1237
1238 /* for CMT */
1239 asoc->last_net_cmt_send_started = NULL;
1240
1241 /* This will need to be adjusted */
1242 asoc->last_acked_seq = asoc->init_seq_number - 1;
1243 asoc->advanced_peer_ack_point = asoc->last_acked_seq;
1244 asoc->asconf_seq_in = asoc->last_acked_seq;
1245
1246 /* here we are different, we hold the next one we expect */
1247 asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
1248
1249 asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max;
1250 asoc->initial_rto = inp->sctp_ep.initial_rto;
1251
1252 asoc->default_mtu = inp->sctp_ep.default_mtu;
1253 asoc->max_init_times = inp->sctp_ep.max_init_times;
1254 asoc->max_send_times = inp->sctp_ep.max_send_times;
1255 asoc->def_net_failure = inp->sctp_ep.def_net_failure;
1256 asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold;
1257 asoc->free_chunk_cnt = 0;
1258
1259 asoc->iam_blocking = 0;
1260 asoc->context = inp->sctp_context;
1261 asoc->local_strreset_support = inp->local_strreset_support;
1262 asoc->def_send = inp->def_send;
1263 asoc->delayed_ack = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1264 asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
1265 asoc->pr_sctp_cnt = 0;
1266 asoc->total_output_queue_size = 0;
1267
1268 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1269 asoc->scope.ipv6_addr_legal = 1;
1270 if (SCTP_IPV6_V6ONLY(inp) == 0) {
1271 asoc->scope.ipv4_addr_legal = 1;
1272 } else {
1273 asoc->scope.ipv4_addr_legal = 0;
1274 }
1275 #if defined(__Userspace__)
1276 asoc->scope.conn_addr_legal = 0;
1277 #endif
1278 } else {
1279 asoc->scope.ipv6_addr_legal = 0;
1280 #if defined(__Userspace__)
1281 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
1282 asoc->scope.conn_addr_legal = 1;
1283 asoc->scope.ipv4_addr_legal = 0;
1284 } else {
1285 asoc->scope.conn_addr_legal = 0;
1286 asoc->scope.ipv4_addr_legal = 1;
1287 }
1288 #else
1289 asoc->scope.ipv4_addr_legal = 1;
1290 #endif
1291 }
1292
1293 asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND);
1294 asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket);
1295
1296 asoc->smallest_mtu = inp->sctp_frag_point;
1297 asoc->minrto = inp->sctp_ep.sctp_minrto;
1298 asoc->maxrto = inp->sctp_ep.sctp_maxrto;
1299
1300 asoc->stream_locked_on = 0;
1301 asoc->ecn_echo_cnt_onq = 0;
1302 asoc->stream_locked = 0;
1303
1304 asoc->send_sack = 1;
1305
1306 LIST_INIT(&asoc->sctp_restricted_addrs);
1307
1308 TAILQ_INIT(&asoc->nets);
1309 TAILQ_INIT(&asoc->pending_reply_queue);
1310 TAILQ_INIT(&asoc->asconf_ack_sent);
1311 /* Setup to fill the hb random cache at first HB */
1312 asoc->hb_random_idx = 4;
1313
1314 asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time;
1315
1316 stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module;
1317 stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module];
1318
1319 stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module;
1320 stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module];
1321
1322 /*
1323 * Now the stream parameters, here we allocate space for all streams
1324 * that we request by default.
1325 */
1326 asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
1327 o_strms;
1328 SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
1329 asoc->streamoutcnt * sizeof(struct sctp_stream_out),
1330 SCTP_M_STRMO);
1331 if (asoc->strmout == NULL) {
1332 /* big trouble no memory */
1333 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1334 return (ENOMEM);
1335 }
1336 for (i = 0; i < asoc->streamoutcnt; i++) {
1337 /*
1338 * inbound side must be set to 0xffff, also NOTE when we get
1339 * the INIT-ACK back (for INIT sender) we MUST reduce the
1340 * count (streamoutcnt) but first check if we sent to any of
1341 * the upper streams that were dropped (if some were). Those
1342 * that were dropped must be notified to the upper layer as
1343 * failed to send.
1344 */
1345 asoc->strmout[i].next_mid_ordered = 0;
1346 asoc->strmout[i].next_mid_unordered = 0;
1347 TAILQ_INIT(&asoc->strmout[i].outqueue);
1348 asoc->strmout[i].chunks_on_queues = 0;
1349 #if defined(SCTP_DETAILED_STR_STATS)
1350 for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
1351 asoc->strmout[i].abandoned_sent[j] = 0;
1352 asoc->strmout[i].abandoned_unsent[j] = 0;
1353 }
1354 #else
1355 asoc->strmout[i].abandoned_sent[0] = 0;
1356 asoc->strmout[i].abandoned_unsent[0] = 0;
1357 #endif
1358 asoc->strmout[i].sid = i;
1359 asoc->strmout[i].last_msg_incomplete = 0;
1360 asoc->strmout[i].state = SCTP_STREAM_OPENING;
1361 asoc->ss_functions.sctp_ss_init_stream(stcb, &asoc->strmout[i], NULL);
1362 }
1363 asoc->ss_functions.sctp_ss_init(stcb, asoc, 0);
1364
1365 /* Now the mapping array */
1366 asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
1367 SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1368 SCTP_M_MAP);
1369 if (asoc->mapping_array == NULL) {
1370 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1371 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1372 return (ENOMEM);
1373 }
1374 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
1375 SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
1376 SCTP_M_MAP);
1377 if (asoc->nr_mapping_array == NULL) {
1378 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1379 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1380 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1381 return (ENOMEM);
1382 }
1383 memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
1384
1385 /* Now the init of the other outqueues */
1386 TAILQ_INIT(&asoc->free_chunks);
1387 TAILQ_INIT(&asoc->control_send_queue);
1388 TAILQ_INIT(&asoc->asconf_send_queue);
1389 TAILQ_INIT(&asoc->send_queue);
1390 TAILQ_INIT(&asoc->sent_queue);
1391 TAILQ_INIT(&asoc->resetHead);
1392 asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome;
1393 TAILQ_INIT(&asoc->asconf_queue);
1394 /* authentication fields */
1395 asoc->authinfo.random = NULL;
1396 asoc->authinfo.active_keyid = 0;
1397 asoc->authinfo.assoc_key = NULL;
1398 asoc->authinfo.assoc_keyid = 0;
1399 asoc->authinfo.recv_key = NULL;
1400 asoc->authinfo.recv_keyid = 0;
1401 LIST_INIT(&asoc->shared_keys);
1402 asoc->marked_retrans = 0;
1403 asoc->port = inp->sctp_ep.port;
1404 asoc->timoinit = 0;
1405 asoc->timodata = 0;
1406 asoc->timosack = 0;
1407 asoc->timoshutdown = 0;
1408 asoc->timoheartbeat = 0;
1409 asoc->timocookie = 0;
1410 asoc->timoshutdownack = 0;
1411 (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
1412 asoc->discontinuity_time = asoc->start_time;
1413 for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
1414 asoc->abandoned_unsent[i] = 0;
1415 asoc->abandoned_sent[i] = 0;
1416 }
1417 /* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
1418 * the association is freed.
1419 */
1420 return (0);
1421 }
1422
1423 void
sctp_print_mapping_array(struct sctp_association * asoc)1424 sctp_print_mapping_array(struct sctp_association *asoc)
1425 {
1426 unsigned int i, limit;
1427
1428 SCTP_PRINTF("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n",
1429 asoc->mapping_array_size,
1430 asoc->mapping_array_base_tsn,
1431 asoc->cumulative_tsn,
1432 asoc->highest_tsn_inside_map,
1433 asoc->highest_tsn_inside_nr_map);
1434 for (limit = asoc->mapping_array_size; limit > 1; limit--) {
1435 if (asoc->mapping_array[limit - 1] != 0) {
1436 break;
1437 }
1438 }
1439 SCTP_PRINTF("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
1440 for (i = 0; i < limit; i++) {
1441 SCTP_PRINTF("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
1442 }
1443 if (limit % 16)
1444 SCTP_PRINTF("\n");
1445 for (limit = asoc->mapping_array_size; limit > 1; limit--) {
1446 if (asoc->nr_mapping_array[limit - 1]) {
1447 break;
1448 }
1449 }
1450 SCTP_PRINTF("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
1451 for (i = 0; i < limit; i++) {
1452 SCTP_PRINTF("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ': '\n');
1453 }
1454 if (limit % 16)
1455 SCTP_PRINTF("\n");
1456 }
1457
1458 int
sctp_expand_mapping_array(struct sctp_association * asoc,uint32_t needed)1459 sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
1460 {
1461 /* mapping array needs to grow */
1462 uint8_t *new_array1, *new_array2;
1463 uint32_t new_size;
1464
1465 new_size = asoc->mapping_array_size + ((needed+7)/8 + SCTP_MAPPING_ARRAY_INCR);
1466 SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
1467 SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
1468 if ((new_array1 == NULL) || (new_array2 == NULL)) {
1469 /* can't get more, forget it */
1470 SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size);
1471 if (new_array1) {
1472 SCTP_FREE(new_array1, SCTP_M_MAP);
1473 }
1474 if (new_array2) {
1475 SCTP_FREE(new_array2, SCTP_M_MAP);
1476 }
1477 return (-1);
1478 }
1479 memset(new_array1, 0, new_size);
1480 memset(new_array2, 0, new_size);
1481 memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
1482 memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
1483 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1484 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
1485 asoc->mapping_array = new_array1;
1486 asoc->nr_mapping_array = new_array2;
1487 asoc->mapping_array_size = new_size;
1488 return (0);
1489 }
1490
1491
1492 static void
sctp_iterator_work(struct sctp_iterator * it)1493 sctp_iterator_work(struct sctp_iterator *it)
1494 {
1495 #if defined(__FreeBSD__)
1496 struct epoch_tracker et;
1497 #endif
1498 struct sctp_inpcb *tinp;
1499 int iteration_count = 0;
1500 int inp_skip = 0;
1501 int first_in = 1;
1502
1503 #if defined(__FreeBSD__)
1504 NET_EPOCH_ENTER(et);
1505 #endif
1506 SCTP_INP_INFO_RLOCK();
1507 SCTP_ITERATOR_LOCK();
1508 sctp_it_ctl.cur_it = it;
1509 if (it->inp) {
1510 SCTP_INP_RLOCK(it->inp);
1511 SCTP_INP_DECR_REF(it->inp);
1512 }
1513 if (it->inp == NULL) {
1514 /* iterator is complete */
1515 done_with_iterator:
1516 sctp_it_ctl.cur_it = NULL;
1517 SCTP_ITERATOR_UNLOCK();
1518 SCTP_INP_INFO_RUNLOCK();
1519 if (it->function_atend != NULL) {
1520 (*it->function_atend) (it->pointer, it->val);
1521 }
1522 SCTP_FREE(it, SCTP_M_ITER);
1523 #if defined(__FreeBSD__)
1524 NET_EPOCH_EXIT(et);
1525 #endif
1526 return;
1527 }
1528 select_a_new_ep:
1529 if (first_in) {
1530 first_in = 0;
1531 } else {
1532 SCTP_INP_RLOCK(it->inp);
1533 }
1534 while (((it->pcb_flags) &&
1535 ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) ||
1536 ((it->pcb_features) &&
1537 ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) {
1538 /* endpoint flags or features don't match, so keep looking */
1539 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1540 SCTP_INP_RUNLOCK(it->inp);
1541 goto done_with_iterator;
1542 }
1543 tinp = it->inp;
1544 it->inp = LIST_NEXT(it->inp, sctp_list);
1545 it->stcb = NULL;
1546 SCTP_INP_RUNLOCK(tinp);
1547 if (it->inp == NULL) {
1548 goto done_with_iterator;
1549 }
1550 SCTP_INP_RLOCK(it->inp);
1551 }
1552 /* now go through each assoc which is in the desired state */
1553 if (it->done_current_ep == 0) {
1554 if (it->function_inp != NULL)
1555 inp_skip = (*it->function_inp)(it->inp, it->pointer, it->val);
1556 it->done_current_ep = 1;
1557 }
1558 if (it->stcb == NULL) {
1559 /* run the per instance function */
1560 it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list);
1561 }
1562 if ((inp_skip) || it->stcb == NULL) {
1563 if (it->function_inp_end != NULL) {
1564 inp_skip = (*it->function_inp_end)(it->inp,
1565 it->pointer,
1566 it->val);
1567 }
1568 SCTP_INP_RUNLOCK(it->inp);
1569 goto no_stcb;
1570 }
1571 while (it->stcb) {
1572 SCTP_TCB_LOCK(it->stcb);
1573 if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
1574 /* not in the right state... keep looking */
1575 SCTP_TCB_UNLOCK(it->stcb);
1576 goto next_assoc;
1577 }
1578 /* see if we have limited out the iterator loop */
1579 iteration_count++;
1580 if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) {
1581 /* Pause to let others grab the lock */
1582 atomic_add_int(&it->stcb->asoc.refcnt, 1);
1583 SCTP_TCB_UNLOCK(it->stcb);
1584 SCTP_INP_INCR_REF(it->inp);
1585 SCTP_INP_RUNLOCK(it->inp);
1586 SCTP_ITERATOR_UNLOCK();
1587 SCTP_INP_INFO_RUNLOCK();
1588 SCTP_INP_INFO_RLOCK();
1589 SCTP_ITERATOR_LOCK();
1590 if (sctp_it_ctl.iterator_flags) {
1591 /* We won't be staying here */
1592 SCTP_INP_DECR_REF(it->inp);
1593 atomic_add_int(&it->stcb->asoc.refcnt, -1);
1594 #if !defined(__FreeBSD__)
1595 if (sctp_it_ctl.iterator_flags &
1596 SCTP_ITERATOR_MUST_EXIT) {
1597 goto done_with_iterator;
1598 }
1599 #endif
1600 if (sctp_it_ctl.iterator_flags &
1601 SCTP_ITERATOR_STOP_CUR_IT) {
1602 sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_IT;
1603 goto done_with_iterator;
1604 }
1605 if (sctp_it_ctl.iterator_flags &
1606 SCTP_ITERATOR_STOP_CUR_INP) {
1607 sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_INP;
1608 goto no_stcb;
1609 }
1610 /* If we reach here huh? */
1611 SCTP_PRINTF("Unknown it ctl flag %x\n",
1612 sctp_it_ctl.iterator_flags);
1613 sctp_it_ctl.iterator_flags = 0;
1614 }
1615 SCTP_INP_RLOCK(it->inp);
1616 SCTP_INP_DECR_REF(it->inp);
1617 SCTP_TCB_LOCK(it->stcb);
1618 atomic_add_int(&it->stcb->asoc.refcnt, -1);
1619 iteration_count = 0;
1620 }
1621 KASSERT(it->inp == it->stcb->sctp_ep,
1622 ("%s: stcb %p does not belong to inp %p, but inp %p",
1623 __func__, it->stcb, it->inp, it->stcb->sctp_ep));
1624
1625 /* run function on this one */
1626 (*it->function_assoc)(it->inp, it->stcb, it->pointer, it->val);
1627
1628 /*
1629 * we lie here, it really needs to have its own type but
1630 * first I must verify that this won't effect things :-0
1631 */
1632 if (it->no_chunk_output == 0)
1633 sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1634
1635 SCTP_TCB_UNLOCK(it->stcb);
1636 next_assoc:
1637 it->stcb = LIST_NEXT(it->stcb, sctp_tcblist);
1638 if (it->stcb == NULL) {
1639 /* Run last function */
1640 if (it->function_inp_end != NULL) {
1641 inp_skip = (*it->function_inp_end)(it->inp,
1642 it->pointer,
1643 it->val);
1644 }
1645 }
1646 }
1647 SCTP_INP_RUNLOCK(it->inp);
1648 no_stcb:
1649 /* done with all assocs on this endpoint, move on to next endpoint */
1650 it->done_current_ep = 0;
1651 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
1652 it->inp = NULL;
1653 } else {
1654 it->inp = LIST_NEXT(it->inp, sctp_list);
1655 }
1656 it->stcb = NULL;
1657 if (it->inp == NULL) {
1658 goto done_with_iterator;
1659 }
1660 goto select_a_new_ep;
1661 }
1662
1663 void
sctp_iterator_worker(void)1664 sctp_iterator_worker(void)
1665 {
1666 struct sctp_iterator *it;
1667
1668 /* This function is called with the WQ lock in place */
1669 sctp_it_ctl.iterator_running = 1;
1670 while ((it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead)) != NULL) {
1671 /* now lets work on this one */
1672 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
1673 SCTP_IPI_ITERATOR_WQ_UNLOCK();
1674 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1675 CURVNET_SET(it->vn);
1676 #endif
1677 sctp_iterator_work(it);
1678 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1679 CURVNET_RESTORE();
1680 #endif
1681 SCTP_IPI_ITERATOR_WQ_LOCK();
1682 #if !defined(__FreeBSD__)
1683 if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) {
1684 break;
1685 }
1686 #endif
1687 /*sa_ignore FREED_MEMORY*/
1688 }
1689 sctp_it_ctl.iterator_running = 0;
1690 return;
1691 }
1692
1693
1694 static void
sctp_handle_addr_wq(void)1695 sctp_handle_addr_wq(void)
1696 {
1697 /* deal with the ADDR wq from the rtsock calls */
1698 struct sctp_laddr *wi, *nwi;
1699 struct sctp_asconf_iterator *asc;
1700
1701 SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
1702 sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT);
1703 if (asc == NULL) {
1704 /* Try later, no memory */
1705 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
1706 (struct sctp_inpcb *)NULL,
1707 (struct sctp_tcb *)NULL,
1708 (struct sctp_nets *)NULL);
1709 return;
1710 }
1711 LIST_INIT(&asc->list_of_work);
1712 asc->cnt = 0;
1713
1714 LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
1715 LIST_REMOVE(wi, sctp_nxt_addr);
1716 LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
1717 asc->cnt++;
1718 }
1719
1720 if (asc->cnt == 0) {
1721 SCTP_FREE(asc, SCTP_M_ASC_IT);
1722 } else {
1723 int ret;
1724
1725 ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
1726 sctp_asconf_iterator_stcb,
1727 NULL, /* No ep end for boundall */
1728 SCTP_PCB_FLAGS_BOUNDALL,
1729 SCTP_PCB_ANY_FEATURES,
1730 SCTP_ASOC_ANY_STATE,
1731 (void *)asc, 0,
1732 sctp_asconf_iterator_end, NULL, 0);
1733 if (ret) {
1734 SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n");
1735 /* Freeing if we are stopping or put back on the addr_wq. */
1736 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
1737 sctp_asconf_iterator_end(asc, 0);
1738 } else {
1739 LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) {
1740 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
1741 }
1742 SCTP_FREE(asc, SCTP_M_ASC_IT);
1743 }
1744 }
1745 }
1746 }
1747
1748 /*-
1749 * The following table shows which pointers for the inp, stcb, or net are
1750 * stored for each timer after it was started.
1751 *
1752 *|Name |Timer |inp |stcb|net |
1753 *|-----------------------------|-----------------------------|----|----|----|
1754 *|SCTP_TIMER_TYPE_SEND |net->rxt_timer |Yes |Yes |Yes |
1755 *|SCTP_TIMER_TYPE_INIT |net->rxt_timer |Yes |Yes |Yes |
1756 *|SCTP_TIMER_TYPE_RECV |stcb->asoc.dack_timer |Yes |Yes |No |
1757 *|SCTP_TIMER_TYPE_SHUTDOWN |net->rxt_timer |Yes |Yes |Yes |
1758 *|SCTP_TIMER_TYPE_HEARTBEAT |net->hb_timer |Yes |Yes |Yes |
1759 *|SCTP_TIMER_TYPE_COOKIE |net->rxt_timer |Yes |Yes |Yes |
1760 *|SCTP_TIMER_TYPE_NEWCOOKIE |inp->sctp_ep.signature_change|Yes |No |No |
1761 *|SCTP_TIMER_TYPE_PATHMTURAISE |net->pmtu_timer |Yes |Yes |Yes |
1762 *|SCTP_TIMER_TYPE_SHUTDOWNACK |net->rxt_timer |Yes |Yes |Yes |
1763 *|SCTP_TIMER_TYPE_ASCONF |stcb->asoc.asconf_timer |Yes |Yes |Yes |
1764 *|SCTP_TIMER_TYPE_SHUTDOWNGUARD|stcb->asoc.shut_guard_timer |Yes |Yes |No |
1765 *|SCTP_TIMER_TYPE_AUTOCLOSE |stcb->asoc.autoclose_timer |Yes |Yes |No |
1766 *|SCTP_TIMER_TYPE_STRRESET |stcb->asoc.strreset_timer |Yes |Yes |No |
1767 *|SCTP_TIMER_TYPE_INPKILL |inp->sctp_ep.signature_change|Yes |No |No |
1768 *|SCTP_TIMER_TYPE_ASOCKILL |stcb->asoc.strreset_timer |Yes |Yes |No |
1769 *|SCTP_TIMER_TYPE_ADDR_WQ |SCTP_BASE_INFO(addr_wq_timer)|No |No |No |
1770 *|SCTP_TIMER_TYPE_PRIM_DELETED |stcb->asoc.delete_prim_timer |Yes |Yes |No |
1771 */
1772
1773 void
sctp_timeout_handler(void * t)1774 sctp_timeout_handler(void *t)
1775 {
1776 #if defined(__FreeBSD__)
1777 struct epoch_tracker et;
1778 #endif
1779 struct timeval tv;
1780 struct sctp_inpcb *inp;
1781 struct sctp_tcb *stcb;
1782 struct sctp_nets *net;
1783 struct sctp_timer *tmr;
1784 struct mbuf *op_err;
1785 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
1786 struct socket *so;
1787 #endif
1788 #if defined(__Userspace__)
1789 struct socket *upcall_socket = NULL;
1790 #endif
1791 int did_output;
1792 int type;
1793 int i, secret;
1794
1795 tmr = (struct sctp_timer *)t;
1796 inp = (struct sctp_inpcb *)tmr->ep;
1797 stcb = (struct sctp_tcb *)tmr->tcb;
1798 net = (struct sctp_nets *)tmr->net;
1799 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1800 CURVNET_SET((struct vnet *)tmr->vnet);
1801 #endif
1802 did_output = 1;
1803
1804 #ifdef SCTP_AUDITING_ENABLED
1805 sctp_audit_log(0xF0, (uint8_t) tmr->type);
1806 sctp_auditing(3, inp, stcb, net);
1807 #endif
1808
1809 /* sanity checks... */
1810 KASSERT(tmr->self == tmr,
1811 ("sctp_timeout_handler: tmr->self corrupted"));
1812 KASSERT(SCTP_IS_TIMER_TYPE_VALID(tmr->type),
1813 ("sctp_timeout_handler: invalid timer type %d", tmr->type));
1814 type = tmr->type;
1815 KASSERT(stcb == NULL || stcb->sctp_ep == inp,
1816 ("sctp_timeout_handler of type %d: inp = %p, stcb->sctp_ep %p",
1817 type, stcb, stcb->sctp_ep));
1818 if (inp) {
1819 SCTP_INP_INCR_REF(inp);
1820 }
1821 tmr->stopped_from = 0xa001;
1822 if (stcb) {
1823 atomic_add_int(&stcb->asoc.refcnt, 1);
1824 if (stcb->asoc.state == 0) {
1825 atomic_add_int(&stcb->asoc.refcnt, -1);
1826 if (inp) {
1827 SCTP_INP_DECR_REF(inp);
1828 }
1829 SCTPDBG(SCTP_DEBUG_TIMER2,
1830 "Timer type %d handler exiting due to CLOSED association.\n",
1831 type);
1832 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1833 CURVNET_RESTORE();
1834 #endif
1835 return;
1836 }
1837 }
1838 tmr->stopped_from = 0xa002;
1839 SCTPDBG(SCTP_DEBUG_TIMER2, "Timer type %d goes off.\n", type);
1840 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1841 if (inp) {
1842 SCTP_INP_DECR_REF(inp);
1843 }
1844 if (stcb) {
1845 atomic_add_int(&stcb->asoc.refcnt, -1);
1846 }
1847 SCTPDBG(SCTP_DEBUG_TIMER2,
1848 "Timer type %d handler exiting due to not being active.\n",
1849 type);
1850 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1851 CURVNET_RESTORE();
1852 #endif
1853 return;
1854 }
1855
1856 tmr->stopped_from = 0xa003;
1857 if (stcb) {
1858 SCTP_TCB_LOCK(stcb);
1859 atomic_add_int(&stcb->asoc.refcnt, -1);
1860 if ((type != SCTP_TIMER_TYPE_ASOCKILL) &&
1861 ((stcb->asoc.state == 0) ||
1862 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) {
1863 SCTP_TCB_UNLOCK(stcb);
1864 if (inp) {
1865 SCTP_INP_DECR_REF(inp);
1866 }
1867 SCTPDBG(SCTP_DEBUG_TIMER2,
1868 "Timer type %d handler exiting due to CLOSED association.\n",
1869 type);
1870 #if defined(__FreeBSD__) && __FreeBSD_version >= 801000
1871 CURVNET_RESTORE();
1872 #endif
1873 return;
1874 }
1875 } else if (inp != NULL) {
1876 SCTP_INP_WLOCK(inp);
1877 } else {
1878 SCTP_WQ_ADDR_LOCK();
1879 }
1880
1881 /* Record in stopped_from which timeout occurred. */
1882 tmr->stopped_from = type;
1883 #if defined(__FreeBSD__)
1884 NET_EPOCH_ENTER(et);
1885 #endif
1886 /* mark as being serviced now */
1887 if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
1888 /*
1889 * Callout has been rescheduled.
1890 */
1891 goto get_out;
1892 }
1893 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1894 /*
1895 * Not active, so no action.
1896 */
1897 goto get_out;
1898 }
1899 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);
1900
1901 #if defined(__Userspace__)
1902 if ((stcb != NULL) &&
1903 !(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
1904 (stcb->sctp_socket != NULL)) {
1905 upcall_socket = stcb->sctp_socket;
1906 SOCK_LOCK(upcall_socket);
1907 soref(upcall_socket);
1908 SOCK_UNLOCK(upcall_socket);
1909 }
1910 #endif
1911 /* call the handler for the appropriate timer type */
1912 switch (type) {
1913 case SCTP_TIMER_TYPE_SEND:
1914 KASSERT(inp != NULL && stcb != NULL && net != NULL,
1915 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1916 type, inp, stcb, net));
1917 SCTP_STAT_INCR(sctps_timodata);
1918 stcb->asoc.timodata++;
1919 stcb->asoc.num_send_timers_up--;
1920 if (stcb->asoc.num_send_timers_up < 0) {
1921 stcb->asoc.num_send_timers_up = 0;
1922 }
1923 SCTP_TCB_LOCK_ASSERT(stcb);
1924 if (sctp_t3rxt_timer(inp, stcb, net)) {
1925 /* no need to unlock on tcb its gone */
1926
1927 goto out_decr;
1928 }
1929 SCTP_TCB_LOCK_ASSERT(stcb);
1930 #ifdef SCTP_AUDITING_ENABLED
1931 sctp_auditing(4, inp, stcb, net);
1932 #endif
1933 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1934 if ((stcb->asoc.num_send_timers_up == 0) &&
1935 (stcb->asoc.sent_queue_cnt > 0)) {
1936 struct sctp_tmit_chunk *chk;
1937
1938 /*
1939 * Safeguard. If there on some on the sent queue
1940 * somewhere but no timers running something is
1941 * wrong... so we start a timer on the first chunk
1942 * on the send queue on whatever net it is sent to.
1943 */
1944 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1945 if (chk->whoTo != NULL) {
1946 break;
1947 }
1948 }
1949 if (chk != NULL) {
1950 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
1951 }
1952 }
1953 break;
1954 case SCTP_TIMER_TYPE_INIT:
1955 KASSERT(inp != NULL && stcb != NULL && net != NULL,
1956 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1957 type, inp, stcb, net));
1958 SCTP_STAT_INCR(sctps_timoinit);
1959 stcb->asoc.timoinit++;
1960 if (sctp_t1init_timer(inp, stcb, net)) {
1961 /* no need to unlock on tcb its gone */
1962 goto out_decr;
1963 }
1964 /* We do output but not here */
1965 did_output = 0;
1966 break;
1967 case SCTP_TIMER_TYPE_RECV:
1968 KASSERT(inp != NULL && stcb != NULL && net == NULL,
1969 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1970 type, inp, stcb, net));
1971 SCTP_STAT_INCR(sctps_timosack);
1972 stcb->asoc.timosack++;
1973 sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
1974 #ifdef SCTP_AUDITING_ENABLED
1975 sctp_auditing(4, inp, stcb, NULL);
1976 #endif
1977 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED);
1978 break;
1979 case SCTP_TIMER_TYPE_SHUTDOWN:
1980 KASSERT(inp != NULL && stcb != NULL && net != NULL,
1981 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1982 type, inp, stcb, net));
1983 SCTP_STAT_INCR(sctps_timoshutdown);
1984 stcb->asoc.timoshutdown++;
1985 if (sctp_shutdown_timer(inp, stcb, net)) {
1986 /* no need to unlock on tcb its gone */
1987 goto out_decr;
1988 }
1989 #ifdef SCTP_AUDITING_ENABLED
1990 sctp_auditing(4, inp, stcb, net);
1991 #endif
1992 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_NOT_LOCKED);
1993 break;
1994 case SCTP_TIMER_TYPE_HEARTBEAT:
1995 KASSERT(inp != NULL && stcb != NULL && net != NULL,
1996 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
1997 type, inp, stcb, net));
1998 SCTP_STAT_INCR(sctps_timoheartbeat);
1999 stcb->asoc.timoheartbeat++;
2000 if (sctp_heartbeat_timer(inp, stcb, net)) {
2001 /* no need to unlock on tcb its gone */
2002 goto out_decr;
2003 }
2004 #ifdef SCTP_AUDITING_ENABLED
2005 sctp_auditing(4, inp, stcb, net);
2006 #endif
2007 if (!(net->dest_state & SCTP_ADDR_NOHB)) {
2008 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
2009 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED);
2010 }
2011 break;
2012 case SCTP_TIMER_TYPE_COOKIE:
2013 KASSERT(inp != NULL && stcb != NULL && net != NULL,
2014 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2015 type, inp, stcb, net));
2016 SCTP_STAT_INCR(sctps_timocookie);
2017 stcb->asoc.timocookie++;
2018 if (sctp_cookie_timer(inp, stcb, net)) {
2019 /* no need to unlock on tcb its gone */
2020 goto out_decr;
2021 }
2022 #ifdef SCTP_AUDITING_ENABLED
2023 sctp_auditing(4, inp, stcb, net);
2024 #endif
2025 /*
2026 * We consider T3 and Cookie timer pretty much the same with
2027 * respect to where from in chunk_output.
2028 */
2029 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
2030 break;
2031 case SCTP_TIMER_TYPE_NEWCOOKIE:
2032 KASSERT(inp != NULL && stcb == NULL && net == NULL,
2033 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2034 type, inp, stcb, net));
2035 SCTP_STAT_INCR(sctps_timosecret);
2036 (void)SCTP_GETTIME_TIMEVAL(&tv);
2037 inp->sctp_ep.time_of_secret_change = tv.tv_sec;
2038 inp->sctp_ep.last_secret_number =
2039 inp->sctp_ep.current_secret_number;
2040 inp->sctp_ep.current_secret_number++;
2041 if (inp->sctp_ep.current_secret_number >=
2042 SCTP_HOW_MANY_SECRETS) {
2043 inp->sctp_ep.current_secret_number = 0;
2044 }
2045 secret = (int)inp->sctp_ep.current_secret_number;
2046 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
2047 inp->sctp_ep.secret_key[secret][i] =
2048 sctp_select_initial_TSN(&inp->sctp_ep);
2049 }
2050 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
2051 did_output = 0;
2052 break;
2053 case SCTP_TIMER_TYPE_PATHMTURAISE:
2054 KASSERT(inp != NULL && stcb != NULL && net != NULL,
2055 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2056 type, inp, stcb, net));
2057 SCTP_STAT_INCR(sctps_timopathmtu);
2058 sctp_pathmtu_timer(inp, stcb, net);
2059 did_output = 0;
2060 break;
2061 case SCTP_TIMER_TYPE_SHUTDOWNACK:
2062 KASSERT(inp != NULL && stcb != NULL && net != NULL,
2063 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2064 type, inp, stcb, net));
2065 if (sctp_shutdownack_timer(inp, stcb, net)) {
2066 /* no need to unlock on tcb its gone */
2067 goto out_decr;
2068 }
2069 SCTP_STAT_INCR(sctps_timoshutdownack);
2070 stcb->asoc.timoshutdownack++;
2071 #ifdef SCTP_AUDITING_ENABLED
2072 sctp_auditing(4, inp, stcb, net);
2073 #endif
2074 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_ACK_TMR, SCTP_SO_NOT_LOCKED);
2075 break;
2076 case SCTP_TIMER_TYPE_ASCONF:
2077 KASSERT(inp != NULL && stcb != NULL && net != NULL,
2078 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2079 type, inp, stcb, net));
2080 SCTP_STAT_INCR(sctps_timoasconf);
2081 if (sctp_asconf_timer(inp, stcb, net)) {
2082 /* no need to unlock on tcb its gone */
2083 goto out_decr;
2084 }
2085 #ifdef SCTP_AUDITING_ENABLED
2086 sctp_auditing(4, inp, stcb, net);
2087 #endif
2088 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_ASCONF_TMR, SCTP_SO_NOT_LOCKED);
2089 break;
2090 case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2091 KASSERT(inp != NULL && stcb != NULL && net == NULL,
2092 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2093 type, inp, stcb, net));
2094 SCTP_STAT_INCR(sctps_timoshutdownguard);
2095 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
2096 "Shutdown guard timer expired");
2097 sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
2098 /* no need to unlock on tcb its gone */
2099 goto out_decr;
2100 case SCTP_TIMER_TYPE_AUTOCLOSE:
2101 KASSERT(inp != NULL && stcb != NULL && net == NULL,
2102 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2103 type, inp, stcb, net));
2104 SCTP_STAT_INCR(sctps_timoautoclose);
2105 sctp_autoclose_timer(inp, stcb);
2106 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED);
2107 did_output = 0;
2108 break;
2109 case SCTP_TIMER_TYPE_STRRESET:
2110 KASSERT(inp != NULL && stcb != NULL && net == NULL,
2111 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2112 type, inp, stcb, net));
2113 SCTP_STAT_INCR(sctps_timostrmrst);
2114 if (sctp_strreset_timer(inp, stcb)) {
2115 /* no need to unlock on tcb its gone */
2116 goto out_decr;
2117 }
2118 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_TMR, SCTP_SO_NOT_LOCKED);
2119 break;
2120 case SCTP_TIMER_TYPE_INPKILL:
2121 KASSERT(inp != NULL && stcb == NULL && net == NULL,
2122 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2123 type, inp, stcb, net));
2124 SCTP_STAT_INCR(sctps_timoinpkill);
2125 /*
2126 * special case, take away our increment since WE are the
2127 * killer
2128 */
2129 sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL,
2130 SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
2131 #if defined(__APPLE__)
2132 SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
2133 #endif
2134 SCTP_INP_DECR_REF(inp);
2135 SCTP_INP_WUNLOCK(inp);
2136 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
2137 SCTP_CALLED_FROM_INPKILL_TIMER);
2138 #if defined(__APPLE__)
2139 SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1);
2140 #endif
2141 inp = NULL;
2142 goto out_no_decr;
2143 case SCTP_TIMER_TYPE_ASOCKILL:
2144 KASSERT(inp != NULL && stcb != NULL && net == NULL,
2145 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2146 type, inp, stcb, net));
2147 SCTP_STAT_INCR(sctps_timoassockill);
2148 /* Can we free it yet? */
2149 SCTP_INP_DECR_REF(inp);
2150 sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
2151 SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
2152 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2153 so = SCTP_INP_SO(inp);
2154 atomic_add_int(&stcb->asoc.refcnt, 1);
2155 SCTP_TCB_UNLOCK(stcb);
2156 SCTP_SOCKET_LOCK(so, 1);
2157 SCTP_TCB_LOCK(stcb);
2158 atomic_subtract_int(&stcb->asoc.refcnt, 1);
2159 #endif
2160 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
2161 SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
2162 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
2163 SCTP_SOCKET_UNLOCK(so, 1);
2164 #endif
2165 /*
2166 * free asoc, always unlocks (or destroy's) so prevent
2167 * duplicate unlock or unlock of a free mtx :-0
2168 */
2169 stcb = NULL;
2170 goto out_no_decr;
2171 case SCTP_TIMER_TYPE_ADDR_WQ:
2172 KASSERT(inp == NULL && stcb == NULL && net == NULL,
2173 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2174 type, inp, stcb, net));
2175 sctp_handle_addr_wq();
2176 break;
2177 case SCTP_TIMER_TYPE_PRIM_DELETED:
2178 KASSERT(inp != NULL && stcb != NULL && net == NULL,
2179 ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2180 type, inp, stcb, net));
2181 SCTP_STAT_INCR(sctps_timodelprim);
2182 sctp_delete_prim_timer(inp, stcb);
2183 break;
2184 default:
2185 #ifdef INVARIANTS
2186 panic("Unknown timer type %d", type);
2187 #else
2188 goto get_out;
2189 #endif
2190 }
2191 #ifdef SCTP_AUDITING_ENABLED
2192 sctp_audit_log(0xF1, (uint8_t) type);
2193 if (inp)
2194 sctp_auditing(5, inp, stcb, net);
2195 #endif
2196 if ((did_output) && stcb) {
2197 /*
2198 * Now we need to clean up the control chunk chain if an
2199 * ECNE is on it. It must be marked as UNSENT again so next
2200 * call will continue to send it until such time that we get
2201 * a CWR, to remove it. It is, however, less likely that we
2202 * will find a ecn echo on the chain though.
2203 */
2204 sctp_fix_ecn_echo(&stcb->asoc);
2205 }
2206 get_out:
2207 if (stcb) {
2208 SCTP_TCB_UNLOCK(stcb);
2209 } else if (inp != NULL) {
2210 SCTP_INP_WUNLOCK(inp);
2211 } else {
2212 SCTP_WQ_ADDR_UNLOCK();
2213 }
2214
2215 out_decr:
2216 #if defined(__Userspace__)
2217 if (upcall_socket != NULL) {
2218 if ((upcall_socket->so_upcall != NULL) &&
2219 (upcall_socket->so_error != 0)) {
2220 (*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
2221 }
2222 ACCEPT_LOCK();
2223 SOCK_LOCK(upcall_socket);
2224 sorele(upcall_socket);
2225 }
2226 #endif
2227 if (inp) {
2228 SCTP_INP_DECR_REF(inp);
2229 }
2230
2231 out_no_decr:
2232 SCTPDBG(SCTP_DEBUG_TIMER2, "Timer type %d handler finished.\n", type);
2233 #if defined(__FreeBSD__)
2234 #if __FreeBSD_version >= 801000
2235 CURVNET_RESTORE();
2236 #endif
2237 NET_EPOCH_EXIT(et);
2238 #endif
2239 }
2240
2241 /*-
2242 * The following table shows which parameters must be provided
2243 * when calling sctp_timer_start(). For parameters not being
2244 * provided, NULL must be used.
2245 *
2246 * |Name |inp |stcb|net |
2247 * |-----------------------------|----|----|----|
2248 * |SCTP_TIMER_TYPE_SEND |Yes |Yes |Yes |
2249 * |SCTP_TIMER_TYPE_INIT |Yes |Yes |Yes |
2250 * |SCTP_TIMER_TYPE_RECV |Yes |Yes |No |
2251 * |SCTP_TIMER_TYPE_SHUTDOWN |Yes |Yes |Yes |
2252 * |SCTP_TIMER_TYPE_HEARTBEAT |Yes |Yes |Yes |
2253 * |SCTP_TIMER_TYPE_COOKIE |Yes |Yes |Yes |
2254 * |SCTP_TIMER_TYPE_NEWCOOKIE |Yes |No |No |
2255 * |SCTP_TIMER_TYPE_PATHMTURAISE |Yes |Yes |Yes |
2256 * |SCTP_TIMER_TYPE_SHUTDOWNACK |Yes |Yes |Yes |
2257 * |SCTP_TIMER_TYPE_ASCONF |Yes |Yes |Yes |
2258 * |SCTP_TIMER_TYPE_SHUTDOWNGUARD|Yes |Yes |No |
2259 * |SCTP_TIMER_TYPE_AUTOCLOSE |Yes |Yes |No |
2260 * |SCTP_TIMER_TYPE_STRRESET |Yes |Yes |Yes |
2261 * |SCTP_TIMER_TYPE_INPKILL |Yes |No |No |
2262 * |SCTP_TIMER_TYPE_ASOCKILL |Yes |Yes |No |
2263 * |SCTP_TIMER_TYPE_ADDR_WQ |No |No |No |
2264 * |SCTP_TIMER_TYPE_PRIM_DELETED |Yes |Yes |No |
2265 *
2266 */
2267
2268 void
sctp_timer_start(int t_type,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net)2269 sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2270 struct sctp_nets *net)
2271 {
2272 struct sctp_timer *tmr;
2273 uint32_t to_ticks;
2274 uint32_t rndval, jitter;
2275
2276 KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2277 ("sctp_timer_start of type %d: inp = %p, stcb->sctp_ep %p",
2278 t_type, stcb, stcb->sctp_ep));
2279 tmr = NULL;
2280 to_ticks = 0;
2281 if (stcb != NULL) {
2282 SCTP_TCB_LOCK_ASSERT(stcb);
2283 } else if (inp != NULL) {
2284 SCTP_INP_WLOCK_ASSERT(inp);
2285 } else {
2286 SCTP_WQ_ADDR_LOCK_ASSERT();
2287 }
2288 if (stcb != NULL) {
2289 /* Don't restart timer on association that's about to be killed. */
2290 if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
2291 (t_type != SCTP_TIMER_TYPE_ASOCKILL)) {
2292 SCTPDBG(SCTP_DEBUG_TIMER2,
2293 "Timer type %d not started: inp=%p, stcb=%p, net=%p (stcb deleted).\n",
2294 t_type, inp, stcb, net);
2295 return;
2296 }
2297 /* Don't restart timer on net that's been removed. */
2298 if (net != NULL && (net->dest_state & SCTP_ADDR_BEING_DELETED)) {
2299 SCTPDBG(SCTP_DEBUG_TIMER2,
2300 "Timer type %d not started: inp=%p, stcb=%p, net=%p (net deleted).\n",
2301 t_type, inp, stcb, net);
2302 return;
2303 }
2304 }
2305 switch (t_type) {
2306 case SCTP_TIMER_TYPE_SEND:
2307 /* Here we use the RTO timer. */
2308 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2309 #ifdef INVARIANTS
2310 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2311 t_type, inp, stcb, net);
2312 #else
2313 return;
2314 #endif
2315 }
2316 tmr = &net->rxt_timer;
2317 if (net->RTO == 0) {
2318 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2319 } else {
2320 to_ticks = sctp_msecs_to_ticks(net->RTO);
2321 }
2322 break;
2323 case SCTP_TIMER_TYPE_INIT:
2324 /*
2325 * Here we use the INIT timer default usually about 1
2326 * second.
2327 */
2328 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2329 #ifdef INVARIANTS
2330 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2331 t_type, inp, stcb, net);
2332 #else
2333 return;
2334 #endif
2335 }
2336 tmr = &net->rxt_timer;
2337 if (net->RTO == 0) {
2338 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2339 } else {
2340 to_ticks = sctp_msecs_to_ticks(net->RTO);
2341 }
2342 break;
2343 case SCTP_TIMER_TYPE_RECV:
2344 /*
2345 * Here we use the Delayed-Ack timer value from the inp,
2346 * ususually about 200ms.
2347 */
2348 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2349 #ifdef INVARIANTS
2350 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2351 t_type, inp, stcb, net);
2352 #else
2353 return;
2354 #endif
2355 }
2356 tmr = &stcb->asoc.dack_timer;
2357 to_ticks = sctp_msecs_to_ticks(stcb->asoc.delayed_ack);
2358 break;
2359 case SCTP_TIMER_TYPE_SHUTDOWN:
2360 /* Here we use the RTO of the destination. */
2361 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2362 #ifdef INVARIANTS
2363 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2364 t_type, inp, stcb, net);
2365 #else
2366 return;
2367 #endif
2368 }
2369 tmr = &net->rxt_timer;
2370 if (net->RTO == 0) {
2371 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2372 } else {
2373 to_ticks = sctp_msecs_to_ticks(net->RTO);
2374 }
2375 break;
2376 case SCTP_TIMER_TYPE_HEARTBEAT:
2377 /*
2378 * The net is used here so that we can add in the RTO. Even
2379 * though we use a different timer. We also add the HB timer
2380 * PLUS a random jitter.
2381 */
2382 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2383 #ifdef INVARIANTS
2384 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2385 t_type, inp, stcb, net);
2386 #else
2387 return;
2388 #endif
2389 }
2390 if ((net->dest_state & SCTP_ADDR_NOHB) &&
2391 !(net->dest_state & SCTP_ADDR_UNCONFIRMED)) {
2392 SCTPDBG(SCTP_DEBUG_TIMER2,
2393 "Timer type %d not started: inp=%p, stcb=%p, net=%p.\n",
2394 t_type, inp, stcb, net);
2395 return;
2396 }
2397 tmr = &net->hb_timer;
2398 if (net->RTO == 0) {
2399 to_ticks = stcb->asoc.initial_rto;
2400 } else {
2401 to_ticks = net->RTO;
2402 }
2403 rndval = sctp_select_initial_TSN(&inp->sctp_ep);
2404 jitter = rndval % to_ticks;
2405 if (jitter >= (to_ticks >> 1)) {
2406 to_ticks = to_ticks + (jitter - (to_ticks >> 1));
2407 } else {
2408 to_ticks = to_ticks - jitter;
2409 }
2410 if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
2411 !(net->dest_state & SCTP_ADDR_PF)) {
2412 to_ticks += net->heart_beat_delay;
2413 }
2414 /*
2415 * Now we must convert the to_ticks that are now in
2416 * ms to ticks.
2417 */
2418 to_ticks = sctp_msecs_to_ticks(to_ticks);
2419 break;
2420 case SCTP_TIMER_TYPE_COOKIE:
2421 /*
2422 * Here we can use the RTO timer from the network since one
2423 * RTT was complete. If a retransmission happened then we will
2424 * be using the RTO initial value.
2425 */
2426 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2427 #ifdef INVARIANTS
2428 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2429 t_type, inp, stcb, net);
2430 #else
2431 return;
2432 #endif
2433 }
2434 tmr = &net->rxt_timer;
2435 if (net->RTO == 0) {
2436 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2437 } else {
2438 to_ticks = sctp_msecs_to_ticks(net->RTO);
2439 }
2440 break;
2441 case SCTP_TIMER_TYPE_NEWCOOKIE:
2442 /*
2443 * Nothing needed but the endpoint here ususually about 60
2444 * minutes.
2445 */
2446 if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2447 #ifdef INVARIANTS
2448 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2449 t_type, inp, stcb, net);
2450 #else
2451 return;
2452 #endif
2453 }
2454 tmr = &inp->sctp_ep.signature_change;
2455 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
2456 break;
2457 case SCTP_TIMER_TYPE_PATHMTURAISE:
2458 /*
2459 * Here we use the value found in the EP for PMTUD, ususually
2460 * about 10 minutes.
2461 */
2462 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2463 #ifdef INVARIANTS
2464 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2465 t_type, inp, stcb, net);
2466 #else
2467 return;
2468 #endif
2469 }
2470 if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
2471 SCTPDBG(SCTP_DEBUG_TIMER2,
2472 "Timer type %d not started: inp=%p, stcb=%p, net=%p.\n",
2473 t_type, inp, stcb, net);
2474 return;
2475 }
2476 tmr = &net->pmtu_timer;
2477 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
2478 break;
2479 case SCTP_TIMER_TYPE_SHUTDOWNACK:
2480 /* Here we use the RTO of the destination. */
2481 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2482 #ifdef INVARIANTS
2483 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2484 t_type, inp, stcb, net);
2485 #else
2486 return;
2487 #endif
2488 }
2489 tmr = &net->rxt_timer;
2490 if (net->RTO == 0) {
2491 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2492 } else {
2493 to_ticks = sctp_msecs_to_ticks(net->RTO);
2494 }
2495 break;
2496 case SCTP_TIMER_TYPE_ASCONF:
2497 /*
2498 * Here the timer comes from the stcb but its value is from
2499 * the net's RTO.
2500 */
2501 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2502 #ifdef INVARIANTS
2503 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2504 t_type, inp, stcb, net);
2505 #else
2506 return;
2507 #endif
2508 }
2509 tmr = &stcb->asoc.asconf_timer;
2510 if (net->RTO == 0) {
2511 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2512 } else {
2513 to_ticks = sctp_msecs_to_ticks(net->RTO);
2514 }
2515 break;
2516 case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2517 /*
2518 * Here we use the endpoints shutdown guard timer usually
2519 * about 3 minutes.
2520 */
2521 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2522 #ifdef INVARIANTS
2523 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2524 t_type, inp, stcb, net);
2525 #else
2526 return;
2527 #endif
2528 }
2529 tmr = &stcb->asoc.shut_guard_timer;
2530 if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) {
2531 if (stcb->asoc.maxrto < UINT32_MAX / 5) {
2532 to_ticks = sctp_msecs_to_ticks(5 * stcb->asoc.maxrto);
2533 } else {
2534 to_ticks = sctp_msecs_to_ticks(UINT32_MAX);
2535 }
2536 } else {
2537 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
2538 }
2539 break;
2540 case SCTP_TIMER_TYPE_AUTOCLOSE:
2541 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2542 #ifdef INVARIANTS
2543 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2544 t_type, inp, stcb, net);
2545 #else
2546 return;
2547 #endif
2548 }
2549 tmr = &stcb->asoc.autoclose_timer;
2550 to_ticks = stcb->asoc.sctp_autoclose_ticks;
2551 break;
2552 case SCTP_TIMER_TYPE_STRRESET:
2553 /*
2554 * Here the timer comes from the stcb but its value is from
2555 * the net's RTO.
2556 */
2557 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2558 #ifdef INVARIANTS
2559 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2560 t_type, inp, stcb, net);
2561 #else
2562 return;
2563 #endif
2564 }
2565 tmr = &stcb->asoc.strreset_timer;
2566 if (net->RTO == 0) {
2567 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2568 } else {
2569 to_ticks = sctp_msecs_to_ticks(net->RTO);
2570 }
2571 break;
2572 case SCTP_TIMER_TYPE_INPKILL:
2573 /*
2574 * The inp is setup to die. We re-use the signature_chage
2575 * timer since that has stopped and we are in the GONE
2576 * state.
2577 */
2578 if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2579 #ifdef INVARIANTS
2580 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2581 t_type, inp, stcb, net);
2582 #else
2583 return;
2584 #endif
2585 }
2586 tmr = &inp->sctp_ep.signature_change;
2587 to_ticks = sctp_msecs_to_ticks(SCTP_INP_KILL_TIMEOUT);
2588 break;
2589 case SCTP_TIMER_TYPE_ASOCKILL:
2590 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2591 #ifdef INVARIANTS
2592 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2593 t_type, inp, stcb, net);
2594 #else
2595 return;
2596 #endif
2597 }
2598 tmr = &stcb->asoc.strreset_timer;
2599 to_ticks = sctp_msecs_to_ticks(SCTP_ASOC_KILL_TIMEOUT);
2600 break;
2601 case SCTP_TIMER_TYPE_ADDR_WQ:
2602 if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
2603 #ifdef INVARIANTS
2604 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2605 t_type, inp, stcb, net);
2606 #else
2607 return;
2608 #endif
2609 }
2610 /* Only 1 tick away :-) */
2611 tmr = &SCTP_BASE_INFO(addr_wq_timer);
2612 to_ticks = SCTP_ADDRESS_TICK_DELAY;
2613 break;
2614 case SCTP_TIMER_TYPE_PRIM_DELETED:
2615 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2616 #ifdef INVARIANTS
2617 panic("sctp_timer_start of type %d: inp = %p, stcb = %p, net = %p",
2618 t_type, inp, stcb, net);
2619 #else
2620 return;
2621 #endif
2622 }
2623 tmr = &stcb->asoc.delete_prim_timer;
2624 to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2625 break;
2626 default:
2627 #ifdef INVARIANTS
2628 panic("Unknown timer type %d", t_type);
2629 #else
2630 return;
2631 #endif
2632 }
2633 KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2634 KASSERT(to_ticks > 0, ("to_ticks == 0 for timer type %d", t_type));
2635 if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
2636 /*
2637 * We do NOT allow you to have it already running. If it is,
2638 * we leave the current one up unchanged.
2639 */
2640 SCTPDBG(SCTP_DEBUG_TIMER2,
2641 "Timer type %d already running: inp=%p, stcb=%p, net=%p.\n",
2642 t_type, inp, stcb, net);
2643 return;
2644 }
2645 /* At this point we can proceed. */
2646 if (t_type == SCTP_TIMER_TYPE_SEND) {
2647 stcb->asoc.num_send_timers_up++;
2648 }
2649 tmr->stopped_from = 0;
2650 tmr->type = t_type;
2651 tmr->ep = (void *)inp;
2652 tmr->tcb = (void *)stcb;
2653 if (t_type == SCTP_TIMER_TYPE_STRRESET) {
2654 tmr->net = NULL;
2655 } else {
2656 tmr->net = (void *)net;
2657 }
2658 tmr->self = (void *)tmr;
2659 #if defined(__FreeBSD__)
2660 tmr->vnet = (void *)curvnet;
2661 #endif
2662 tmr->ticks = sctp_get_tick_count();
2663 if (SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr) == 0) {
2664 SCTPDBG(SCTP_DEBUG_TIMER2,
2665 "Timer type %d started: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2666 t_type, to_ticks, inp, stcb, net);
2667 } else {
2668 /*
2669 * This should not happen, since we checked for pending
2670 * above.
2671 */
2672 SCTPDBG(SCTP_DEBUG_TIMER2,
2673 "Timer type %d restarted: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2674 t_type, to_ticks, inp, stcb, net);
2675 }
2676 return;
2677 }
2678
2679 /*-
2680 * The following table shows which parameters must be provided
2681 * when calling sctp_timer_stop(). For parameters not being
2682 * provided, NULL must be used.
2683 *
2684 * |Name |inp |stcb|net |
2685 * |-----------------------------|----|----|----|
2686 * |SCTP_TIMER_TYPE_SEND |Yes |Yes |Yes |
2687 * |SCTP_TIMER_TYPE_INIT |Yes |Yes |Yes |
2688 * |SCTP_TIMER_TYPE_RECV |Yes |Yes |No |
2689 * |SCTP_TIMER_TYPE_SHUTDOWN |Yes |Yes |Yes |
2690 * |SCTP_TIMER_TYPE_HEARTBEAT |Yes |Yes |Yes |
2691 * |SCTP_TIMER_TYPE_COOKIE |Yes |Yes |Yes |
2692 * |SCTP_TIMER_TYPE_NEWCOOKIE |Yes |No |No |
2693 * |SCTP_TIMER_TYPE_PATHMTURAISE |Yes |Yes |Yes |
2694 * |SCTP_TIMER_TYPE_SHUTDOWNACK |Yes |Yes |Yes |
2695 * |SCTP_TIMER_TYPE_ASCONF |Yes |Yes |No |
2696 * |SCTP_TIMER_TYPE_SHUTDOWNGUARD|Yes |Yes |No |
2697 * |SCTP_TIMER_TYPE_AUTOCLOSE |Yes |Yes |No |
2698 * |SCTP_TIMER_TYPE_STRRESET |Yes |Yes |No |
2699 * |SCTP_TIMER_TYPE_INPKILL |Yes |No |No |
2700 * |SCTP_TIMER_TYPE_ASOCKILL |Yes |Yes |No |
2701 * |SCTP_TIMER_TYPE_ADDR_WQ |No |No |No |
2702 * |SCTP_TIMER_TYPE_PRIM_DELETED |Yes |Yes |No |
2703 *
2704 */
2705
2706 void
sctp_timer_stop(int t_type,struct sctp_inpcb * inp,struct sctp_tcb * stcb,struct sctp_nets * net,uint32_t from)2707 sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2708 struct sctp_nets *net, uint32_t from)
2709 {
2710 struct sctp_timer *tmr;
2711
2712 KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2713 ("sctp_timer_stop of type %d: inp = %p, stcb->sctp_ep %p",
2714 t_type, stcb, stcb->sctp_ep));
2715 if (stcb != NULL) {
2716 SCTP_TCB_LOCK_ASSERT(stcb);
2717 } else if (inp != NULL) {
2718 SCTP_INP_WLOCK_ASSERT(inp);
2719 } else {
2720 SCTP_WQ_ADDR_LOCK_ASSERT();
2721 }
2722 tmr = NULL;
2723 switch (t_type) {
2724 case SCTP_TIMER_TYPE_SEND:
2725 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2726 #ifdef INVARIANTS
2727 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2728 t_type, inp, stcb, net);
2729 #else
2730 return;
2731 #endif
2732 }
2733 tmr = &net->rxt_timer;
2734 break;
2735 case SCTP_TIMER_TYPE_INIT:
2736 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2737 #ifdef INVARIANTS
2738 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2739 t_type, inp, stcb, net);
2740 #else
2741 return;
2742 #endif
2743 }
2744 tmr = &net->rxt_timer;
2745 break;
2746 case SCTP_TIMER_TYPE_RECV:
2747 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2748 #ifdef INVARIANTS
2749 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2750 t_type, inp, stcb, net);
2751 #else
2752 return;
2753 #endif
2754 }
2755 tmr = &stcb->asoc.dack_timer;
2756 break;
2757 case SCTP_TIMER_TYPE_SHUTDOWN:
2758 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2759 #ifdef INVARIANTS
2760 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2761 t_type, inp, stcb, net);
2762 #else
2763 return;
2764 #endif
2765 }
2766 tmr = &net->rxt_timer;
2767 break;
2768 case SCTP_TIMER_TYPE_HEARTBEAT:
2769 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2770 #ifdef INVARIANTS
2771 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2772 t_type, inp, stcb, net);
2773 #else
2774 return;
2775 #endif
2776 }
2777 tmr = &net->hb_timer;
2778 break;
2779 case SCTP_TIMER_TYPE_COOKIE:
2780 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2781 #ifdef INVARIANTS
2782 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2783 t_type, inp, stcb, net);
2784 #else
2785 return;
2786 #endif
2787 }
2788 tmr = &net->rxt_timer;
2789 break;
2790 case SCTP_TIMER_TYPE_NEWCOOKIE:
2791 if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2792 #ifdef INVARIANTS
2793 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2794 t_type, inp, stcb, net);
2795 #else
2796 return;
2797 #endif
2798 }
2799 tmr = &inp->sctp_ep.signature_change;
2800 break;
2801 case SCTP_TIMER_TYPE_PATHMTURAISE:
2802 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2803 #ifdef INVARIANTS
2804 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2805 t_type, inp, stcb, net);
2806 #else
2807 return;
2808 #endif
2809 }
2810 tmr = &net->pmtu_timer;
2811 break;
2812 case SCTP_TIMER_TYPE_SHUTDOWNACK:
2813 if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
2814 #ifdef INVARIANTS
2815 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2816 t_type, inp, stcb, net);
2817 #else
2818 return;
2819 #endif
2820 }
2821 tmr = &net->rxt_timer;
2822 break;
2823 case SCTP_TIMER_TYPE_ASCONF:
2824 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2825 #ifdef INVARIANTS
2826 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2827 t_type, inp, stcb, net);
2828 #else
2829 return;
2830 #endif
2831 }
2832 tmr = &stcb->asoc.asconf_timer;
2833 break;
2834 case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2835 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2836 #ifdef INVARIANTS
2837 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2838 t_type, inp, stcb, net);
2839 #else
2840 return;
2841 #endif
2842 }
2843 tmr = &stcb->asoc.shut_guard_timer;
2844 break;
2845 case SCTP_TIMER_TYPE_AUTOCLOSE:
2846 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2847 #ifdef INVARIANTS
2848 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2849 t_type, inp, stcb, net);
2850 #else
2851 return;
2852 #endif
2853 }
2854 tmr = &stcb->asoc.autoclose_timer;
2855 break;
2856 case SCTP_TIMER_TYPE_STRRESET:
2857 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2858 #ifdef INVARIANTS
2859 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2860 t_type, inp, stcb, net);
2861 #else
2862 return;
2863 #endif
2864 }
2865 tmr = &stcb->asoc.strreset_timer;
2866 break;
2867 case SCTP_TIMER_TYPE_INPKILL:
2868 /*
2869 * The inp is setup to die. We re-use the signature_chage
2870 * timer since that has stopped and we are in the GONE
2871 * state.
2872 */
2873 if ((inp == NULL) || (stcb != NULL) || (net != NULL)) {
2874 #ifdef INVARIANTS
2875 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2876 t_type, inp, stcb, net);
2877 #else
2878 return;
2879 #endif
2880 }
2881 tmr = &inp->sctp_ep.signature_change;
2882 break;
2883 case SCTP_TIMER_TYPE_ASOCKILL:
2884 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2885 #ifdef INVARIANTS
2886 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2887 t_type, inp, stcb, net);
2888 #else
2889 return;
2890 #endif
2891 }
2892 tmr = &stcb->asoc.strreset_timer;
2893 break;
2894 case SCTP_TIMER_TYPE_ADDR_WQ:
2895 if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
2896 #ifdef INVARIANTS
2897 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2898 t_type, inp, stcb, net);
2899 #else
2900 return;
2901 #endif
2902 }
2903 tmr = &SCTP_BASE_INFO(addr_wq_timer);
2904 break;
2905 case SCTP_TIMER_TYPE_PRIM_DELETED:
2906 if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
2907 #ifdef INVARIANTS
2908 panic("sctp_timer_stop of type %d: inp = %p, stcb = %p, net = %p",
2909 t_type, inp, stcb, net);
2910 #else
2911 return;
2912 #endif
2913 }
2914 tmr = &stcb->asoc.delete_prim_timer;
2915 break;
2916 default:
2917 #ifdef INVARIANTS
2918 panic("Unknown timer type %d", t_type);
2919 #else
2920 return;
2921 #endif
2922 }
2923 KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2924 if ((tmr->type != SCTP_TIMER_TYPE_NONE) &&
2925 (tmr->type != t_type)) {
2926 /*
2927 * Ok we have a timer that is under joint use. Cookie timer
2928 * per chance with the SEND timer. We therefore are NOT
2929 * running the timer that the caller wants stopped. So just
2930 * return.
2931 */
2932 SCTPDBG(SCTP_DEBUG_TIMER2,
2933 "Shared timer type %d not running: inp=%p, stcb=%p, net=%p.\n",
2934 t_type, inp, stcb, net);
2935 return;
2936 }
2937 if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) {
2938 stcb->asoc.num_send_timers_up--;
2939 if (stcb->asoc.num_send_timers_up < 0) {
2940 stcb->asoc.num_send_timers_up = 0;
2941 }
2942 }
2943 tmr->self = NULL;
2944 tmr->stopped_from = from;
2945 if (SCTP_OS_TIMER_STOP(&tmr->timer) == 1) {
2946 KASSERT(tmr->ep == inp,
2947 ("sctp_timer_stop of type %d: inp = %p, tmr->inp = %p",
2948 t_type, inp, tmr->ep));
2949 KASSERT(tmr->tcb == stcb,
2950 ("sctp_timer_stop of type %d: stcb = %p, tmr->stcb = %p",
2951 t_type, stcb, tmr->tcb));
2952 KASSERT(((t_type == SCTP_TIMER_TYPE_ASCONF) && (tmr->net != NULL)) ||
2953 ((t_type != SCTP_TIMER_TYPE_ASCONF) && (tmr->net == net)),
2954 ("sctp_timer_stop of type %d: net = %p, tmr->net = %p",
2955 t_type, net, tmr->net));
2956 SCTPDBG(SCTP_DEBUG_TIMER2,
2957 "Timer type %d stopped: inp=%p, stcb=%p, net=%p.\n",
2958 t_type, inp, stcb, net);
2959 tmr->ep = NULL;
2960 tmr->tcb = NULL;
2961 tmr->net = NULL;
2962 } else {
2963 SCTPDBG(SCTP_DEBUG_TIMER2,
2964 "Timer type %d not stopped: inp=%p, stcb=%p, net=%p.\n",
2965 t_type, inp, stcb, net);
2966 }
2967 return;
2968 }
2969
2970 uint32_t
sctp_calculate_len(struct mbuf * m)2971 sctp_calculate_len(struct mbuf *m)
2972 {
2973 uint32_t tlen = 0;
2974 struct mbuf *at;
2975
2976 at = m;
2977 while (at) {
2978 tlen += SCTP_BUF_LEN(at);
2979 at = SCTP_BUF_NEXT(at);
2980 }
2981 return (tlen);
2982 }
2983
2984 void
sctp_mtu_size_reset(struct sctp_inpcb * inp,struct sctp_association * asoc,uint32_t mtu)2985 sctp_mtu_size_reset(struct sctp_inpcb *inp,
2986 struct sctp_association *asoc, uint32_t mtu)
2987 {
2988 /*
2989 * Reset the P-MTU size on this association, this involves changing
2990 * the asoc MTU, going through ANY chunk+overhead larger than mtu to
2991 * allow the DF flag to be cleared.
2992 */
2993 struct sctp_tmit_chunk *chk;
2994 unsigned int eff_mtu, ovh;
2995
2996 asoc->smallest_mtu = mtu;
2997 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2998 ovh = SCTP_MIN_OVERHEAD;
2999 } else {
3000 ovh = SCTP_MIN_V4_OVERHEAD;
3001 }
3002 eff_mtu = mtu - ovh;
3003 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
3004 if (chk->send_size > eff_mtu) {
3005 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
3006 }
3007 }
3008 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
3009 if (chk->send_size > eff_mtu) {
3010 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
3011 }
3012 }
3013 }
3014
3015
3016 /*
3017 * Given an association and starting time of the current RTT period, update
3018 * RTO in number of msecs. net should point to the current network.
3019 * Return 1, if an RTO update was performed, return 0 if no update was
3020 * performed due to invalid starting point.
3021 */
3022
3023 int
sctp_calculate_rto(struct sctp_tcb * stcb,struct sctp_association * asoc,struct sctp_nets * net,struct timeval * old,int rtt_from_sack)3024 sctp_calculate_rto(struct sctp_tcb *stcb,
3025 struct sctp_association *asoc,
3026 struct sctp_nets *net,
3027 struct timeval *old,
3028 int rtt_from_sack)
3029 {
3030 struct timeval now;
3031 uint64_t rtt_us; /* RTT in us */
3032 int32_t rtt; /* RTT in ms */
3033 uint32_t new_rto;
3034 int first_measure = 0;
3035
3036 /************************/
3037 /* 1. calculate new RTT */
3038 /************************/
3039 /* get the current time */
3040 if (stcb->asoc.use_precise_time) {
3041 (void)SCTP_GETPTIME_TIMEVAL(&now);
3042 } else {
3043 (void)SCTP_GETTIME_TIMEVAL(&now);
3044 }
3045 if ((old->tv_sec > now.tv_sec) ||
3046 ((old->tv_sec == now.tv_sec) && (old->tv_usec > now.tv_usec))) {
3047 /* The starting point is in the future. */
3048 return (0);
3049 }
3050 timevalsub(&now, old);
3051 rtt_us = (uint64_t)1000000 * (uint64_t)now.tv_sec + (uint64_t)now.tv_usec;
3052 if (rtt_us > SCTP_RTO_UPPER_BOUND * 1000) {
3053 /* The RTT is larger than a sane value. */
3054 return (0);
3055 }
3056 /* store the current RTT in us */
3057 net->rtt = rtt_us;
3058 /* compute rtt in ms */
3059 rtt = (int32_t)(net->rtt / 1000);
3060 if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) {
3061 /* Tell the CC module that a new update has just occurred from a sack */
3062 (*asoc->cc_functions.sctp_rtt_calculated)(stcb, net, &now);
3063 }
3064 /* Do we need to determine the lan? We do this only
3065 * on sacks i.e. RTT being determined from data not
3066 * non-data (HB/INIT->INITACK).
3067 */
3068 if ((rtt_from_sack == SCTP_RTT_FROM_DATA) &&
3069 (net->lan_type == SCTP_LAN_UNKNOWN)) {
3070 if (net->rtt > SCTP_LOCAL_LAN_RTT) {
3071 net->lan_type = SCTP_LAN_INTERNET;
3072 } else {
3073 net->lan_type = SCTP_LAN_LOCAL;
3074 }
3075 }
3076
3077 /***************************/
3078 /* 2. update RTTVAR & SRTT */
3079 /***************************/
3080 /*-
3081 * Compute the scaled average lastsa and the
3082 * scaled variance lastsv as described in van Jacobson
3083 * Paper "Congestion Avoidance and Control", Annex A.
3084 *
3085 * (net->lastsa >> SCTP_RTT_SHIFT) is the srtt
3086 * (net->lastsv >> SCTP_RTT_VAR_SHIFT) is the rttvar
3087 */
3088 if (net->RTO_measured) {
3089 rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
3090 net->lastsa += rtt;
3091 if (rtt < 0) {
3092 rtt = -rtt;
3093 }
3094 rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);
3095 net->lastsv += rtt;
3096 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3097 rto_logging(net, SCTP_LOG_RTTVAR);
3098 }
3099 } else {
3100 /* First RTO measurment */
3101 net->RTO_measured = 1;
3102 first_measure = 1;
3103 net->lastsa = rtt << SCTP_RTT_SHIFT;
3104 net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT;
3105 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3106 rto_logging(net, SCTP_LOG_INITIAL_RTT);
3107 }
3108 }
3109 if (net->lastsv == 0) {
3110 net->lastsv = SCTP_CLOCK_GRANULARITY;
3111 }
3112 new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
3113 if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
3114 (stcb->asoc.sat_network_lockout == 0)) {
3115 stcb->asoc.sat_network = 1;
3116 } else if ((!first_measure) && stcb->asoc.sat_network) {
3117 stcb->asoc.sat_network = 0;
3118 stcb->asoc.sat_network_lockout = 1;
3119 }
3120 /* bound it, per C6/C7 in Section 5.3.1 */
3121 if (new_rto < stcb->asoc.minrto) {
3122 new_rto = stcb->asoc.minrto;
3123 }
3124 if (new_rto > stcb->asoc.maxrto) {
3125 new_rto = stcb->asoc.maxrto;
3126 }
3127 net->RTO = new_rto;
3128 return (1);
3129 }
3130
3131 /*
3132 * return a pointer to a contiguous piece of data from the given mbuf chain
3133 * starting at 'off' for 'len' bytes. If the desired piece spans more than
3134 * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size
3135 * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain.
3136 */
3137 caddr_t
sctp_m_getptr(struct mbuf * m,int off,int len,uint8_t * in_ptr)3138 sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr)
3139 {
3140 uint32_t count;
3141 uint8_t *ptr;
3142
3143 ptr = in_ptr;
3144 if ((off < 0) || (len <= 0))
3145 return (NULL);
3146
3147 /* find the desired start location */
3148 while ((m != NULL) && (off > 0)) {
3149 if (off < SCTP_BUF_LEN(m))
3150 break;
3151 off -= SCTP_BUF_LEN(m);
3152 m = SCTP_BUF_NEXT(m);
3153 }
3154 if (m == NULL)
3155 return (NULL);
3156
3157 /* is the current mbuf large enough (eg. contiguous)? */
3158 if ((SCTP_BUF_LEN(m) - off) >= len) {
3159 return (mtod(m, caddr_t) + off);
3160 } else {
3161 /* else, it spans more than one mbuf, so save a temp copy... */
3162 while ((m != NULL) && (len > 0)) {
3163 count = min(SCTP_BUF_LEN(m) - off, len);
3164 memcpy(ptr, mtod(m, caddr_t) + off, count);
3165 len -= count;
3166 ptr += count;
3167 off = 0;
3168 m = SCTP_BUF_NEXT(m);
3169 }
3170 if ((m == NULL) && (len > 0))
3171 return (NULL);
3172 else
3173 return ((caddr_t)in_ptr);
3174 }
3175 }
3176
3177
3178
3179 struct sctp_paramhdr *
sctp_get_next_param(struct mbuf * m,int offset,struct sctp_paramhdr * pull,int pull_limit)3180 sctp_get_next_param(struct mbuf *m,
3181 int offset,
3182 struct sctp_paramhdr *pull,
3183 int pull_limit)
3184 {
3185 /* This just provides a typed signature to Peter's Pull routine */
3186 return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
3187 (uint8_t *) pull));
3188 }
3189
3190
3191 struct mbuf *
sctp_add_pad_tombuf(struct mbuf * m,int padlen)3192 sctp_add_pad_tombuf(struct mbuf *m, int padlen)
3193 {
3194 struct mbuf *m_last;
3195 caddr_t dp;
3196
3197 if (padlen > 3) {
3198 return (NULL);
3199 }
3200 if (padlen <= M_TRAILINGSPACE(m)) {
3201 /*
3202 * The easy way. We hope the majority of the time we hit
3203 * here :)
3204 */
3205 m_last = m;
3206 } else {
3207 /* Hard way we must grow the mbuf chain */
3208 m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
3209 if (m_last == NULL) {
3210 return (NULL);
3211 }
3212 SCTP_BUF_LEN(m_last) = 0;
3213 SCTP_BUF_NEXT(m_last) = NULL;
3214 SCTP_BUF_NEXT(m) = m_last;
3215 }
3216 dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
3217 SCTP_BUF_LEN(m_last) += padlen;
3218 memset(dp, 0, padlen);
3219 return (m_last);
3220 }
3221
3222 struct mbuf *
sctp_pad_lastmbuf(struct mbuf * m,int padval,struct mbuf * last_mbuf)3223 sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
3224 {
3225 /* find the last mbuf in chain and pad it */
3226 struct mbuf *m_at;
3227
3228 if (last_mbuf != NULL) {
3229 return (sctp_add_pad_tombuf(last_mbuf, padval));
3230 } else {
3231 for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
3232 if (SCTP_BUF_NEXT(m_at) == NULL) {
3233 return (sctp_add_pad_tombuf(m_at, padval));
3234 }
3235 }
3236 }
3237 return (NULL);
3238 }
3239
3240 static void
sctp_notify_assoc_change(uint16_t state,struct sctp_tcb * stcb,uint16_t error,struct sctp_abort_chunk * abort,uint8_t from_peer,int so_locked SCTP_UNUSED)3241 sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
3242 uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked
3243 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3244 SCTP_UNUSED
3245 #endif
3246 )
3247 {
3248 struct mbuf *m_notify;
3249 struct sctp_assoc_change *sac;
3250 struct sctp_queued_to_read *control;
3251 unsigned int notif_len;
3252 uint16_t abort_len;
3253 unsigned int i;
3254 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3255 struct socket *so;
3256 #endif
3257
3258 if (stcb == NULL) {
3259 return;
3260 }
3261 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
3262 notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
3263 if (abort != NULL) {
3264 abort_len = ntohs(abort->ch.chunk_length);
3265 /*
3266 * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
3267 * contiguous.
3268 */
3269 if (abort_len > SCTP_CHUNK_BUFFER_SIZE) {
3270 abort_len = SCTP_CHUNK_BUFFER_SIZE;
3271 }
3272 } else {
3273 abort_len = 0;
3274 }
3275 if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3276 notif_len += SCTP_ASSOC_SUPPORTS_MAX;
3277 } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3278 notif_len += abort_len;
3279 }
3280 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
3281 if (m_notify == NULL) {
3282 /* Retry with smaller value. */
3283 notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
3284 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
3285 if (m_notify == NULL) {
3286 goto set_error;
3287 }
3288 }
3289 SCTP_BUF_NEXT(m_notify) = NULL;
3290 sac = mtod(m_notify, struct sctp_assoc_change *);
3291 memset(sac, 0, notif_len);
3292 sac->sac_type = SCTP_ASSOC_CHANGE;
3293 sac->sac_flags = 0;
3294 sac->sac_length = sizeof(struct sctp_assoc_change);
3295 sac->sac_state = state;
3296 sac->sac_error = error;
3297 /* XXX verify these stream counts */
3298 sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
3299 sac->sac_inbound_streams = stcb->asoc.streamincnt;
3300 sac->sac_assoc_id = sctp_get_associd(stcb);
3301 if (notif_len > sizeof(struct sctp_assoc_change)) {
3302 if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3303 i = 0;
3304 if (stcb->asoc.prsctp_supported == 1) {
3305 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
3306 }
3307 if (stcb->asoc.auth_supported == 1) {
3308 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
3309 }
3310 if (stcb->asoc.asconf_supported == 1) {
3311 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
3312 }
3313 if (stcb->asoc.idata_supported == 1) {
3314 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_INTERLEAVING;
3315 }
3316 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
3317 if (stcb->asoc.reconfig_supported == 1) {
3318 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
3319 }
3320 sac->sac_length += i;
3321 } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3322 memcpy(sac->sac_info, abort, abort_len);
3323 sac->sac_length += abort_len;
3324 }
3325 }
3326 SCTP_BUF_LEN(m_notify) = sac->sac_length;
3327 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3328 0, 0, stcb->asoc.context, 0, 0, 0,
3329 m_notify);
3330 if (control != NULL) {
3331 control->length = SCTP_BUF_LEN(m_notify);
3332 control->spec_flags = M_NOTIFICATION;
3333 /* not that we need this */
3334 control->tail_mbuf = m_notify;
3335 sctp_add_to_readq(stcb->sctp_ep, stcb,
3336 control,
3337 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
3338 so_locked);
3339 } else {
3340 sctp_m_freem(m_notify);
3341 }
3342 }
3343 /*
3344 * For 1-to-1 style sockets, we send up and error when an ABORT
3345 * comes in.
3346 */
3347 set_error:
3348 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3349 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3350 ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3351 SOCK_LOCK(stcb->sctp_socket);
3352 if (from_peer) {
3353 if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) {
3354 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
3355 stcb->sctp_socket->so_error = ECONNREFUSED;
3356 } else {
3357 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
3358 stcb->sctp_socket->so_error = ECONNRESET;
3359 }
3360 } else {
3361 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
3362 (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
3363 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT);
3364 stcb->sctp_socket->so_error = ETIMEDOUT;
3365 } else {
3366 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
3367 stcb->sctp_socket->so_error = ECONNABORTED;
3368 }
3369 }
3370 SOCK_UNLOCK(stcb->sctp_socket);
3371 }
3372 /* Wake ANY sleepers */
3373 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3374 so = SCTP_INP_SO(stcb->sctp_ep);
3375 if (!so_locked) {
3376 atomic_add_int(&stcb->asoc.refcnt, 1);
3377 SCTP_TCB_UNLOCK(stcb);
3378 SCTP_SOCKET_LOCK(so, 1);
3379 SCTP_TCB_LOCK(stcb);
3380 atomic_subtract_int(&stcb->asoc.refcnt, 1);
3381 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3382 SCTP_SOCKET_UNLOCK(so, 1);
3383 return;
3384 }
3385 }
3386 #endif
3387 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3388 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3389 ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3390 socantrcvmore(stcb->sctp_socket);
3391 }
3392 sorwakeup(stcb->sctp_socket);
3393 sowwakeup(stcb->sctp_socket);
3394 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3395 if (!so_locked) {
3396 SCTP_SOCKET_UNLOCK(so, 1);
3397 }
3398 #endif
3399 }
3400
3401 static void
sctp_notify_peer_addr_change(struct sctp_tcb * stcb,uint32_t state,struct sockaddr * sa,uint32_t error,int so_locked SCTP_UNUSED)3402 sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
3403 struct sockaddr *sa, uint32_t error, int so_locked
3404 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3405 SCTP_UNUSED
3406 #endif
3407 )
3408 {
3409 struct mbuf *m_notify;
3410 struct sctp_paddr_change *spc;
3411 struct sctp_queued_to_read *control;
3412
3413 if ((stcb == NULL) ||
3414 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) {
3415 /* event not enabled */
3416 return;
3417 }
3418 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA);
3419 if (m_notify == NULL)
3420 return;
3421 SCTP_BUF_LEN(m_notify) = 0;
3422 spc = mtod(m_notify, struct sctp_paddr_change *);
3423 memset(spc, 0, sizeof(struct sctp_paddr_change));
3424 spc->spc_type = SCTP_PEER_ADDR_CHANGE;
3425 spc->spc_flags = 0;
3426 spc->spc_length = sizeof(struct sctp_paddr_change);
3427 switch (sa->sa_family) {
3428 #ifdef INET
3429 case AF_INET:
3430 #ifdef INET6
3431 if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
3432 in6_sin_2_v4mapsin6((struct sockaddr_in *)sa,
3433 (struct sockaddr_in6 *)&spc->spc_aaddr);
3434 } else {
3435 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3436 }
3437 #else
3438 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3439 #endif
3440 break;
3441 #endif
3442 #ifdef INET6
3443 case AF_INET6:
3444 {
3445 #ifdef SCTP_EMBEDDED_V6_SCOPE
3446 struct sockaddr_in6 *sin6;
3447 #endif /* SCTP_EMBEDDED_V6_SCOPE */
3448 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
3449
3450 #ifdef SCTP_EMBEDDED_V6_SCOPE
3451 sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
3452 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3453 if (sin6->sin6_scope_id == 0) {
3454 /* recover scope_id for user */
3455 #ifdef SCTP_KAME
3456 (void)sa6_recoverscope(sin6);
3457 #else
3458 (void)in6_recoverscope(sin6, &sin6->sin6_addr,
3459 NULL);
3460 #endif
3461 } else {
3462 /* clear embedded scope_id for user */
3463 in6_clearscope(&sin6->sin6_addr);
3464 }
3465 }
3466 #endif /* SCTP_EMBEDDED_V6_SCOPE */
3467 break;
3468 }
3469 #endif
3470 #if defined(__Userspace__)
3471 case AF_CONN:
3472 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_conn));
3473 break;
3474 #endif
3475 default:
3476 /* TSNH */
3477 break;
3478 }
3479 spc->spc_state = state;
3480 spc->spc_error = error;
3481 spc->spc_assoc_id = sctp_get_associd(stcb);
3482
3483 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change);
3484 SCTP_BUF_NEXT(m_notify) = NULL;
3485
3486 /* append to socket */
3487 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3488 0, 0, stcb->asoc.context, 0, 0, 0,
3489 m_notify);
3490 if (control == NULL) {
3491 /* no memory */
3492 sctp_m_freem(m_notify);
3493 return;
3494 }
3495 control->length = SCTP_BUF_LEN(m_notify);
3496 control->spec_flags = M_NOTIFICATION;
3497 /* not that we need this */
3498 control->tail_mbuf = m_notify;
3499 sctp_add_to_readq(stcb->sctp_ep, stcb,
3500 control,
3501 &stcb->sctp_socket->so_rcv, 1,
3502 SCTP_READ_LOCK_NOT_HELD,
3503 so_locked);
3504 }
3505
3506
3507 static void
sctp_notify_send_failed(struct sctp_tcb * stcb,uint8_t sent,uint32_t error,struct sctp_tmit_chunk * chk,int so_locked SCTP_UNUSED)3508 sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
3509 struct sctp_tmit_chunk *chk, int so_locked
3510 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3511 SCTP_UNUSED
3512 #endif
3513 )
3514 {
3515 struct mbuf *m_notify;
3516 struct sctp_send_failed *ssf;
3517 struct sctp_send_failed_event *ssfe;
3518 struct sctp_queued_to_read *control;
3519 struct sctp_chunkhdr *chkhdr;
3520 int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len;
3521
3522 if ((stcb == NULL) ||
3523 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
3524 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
3525 /* event not enabled */
3526 return;
3527 }
3528
3529 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3530 notifhdr_len = sizeof(struct sctp_send_failed_event);
3531 } else {
3532 notifhdr_len = sizeof(struct sctp_send_failed);
3533 }
3534 m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3535 if (m_notify == NULL)
3536 /* no space left */
3537 return;
3538 SCTP_BUF_LEN(m_notify) = notifhdr_len;
3539 if (stcb->asoc.idata_supported) {
3540 chkhdr_len = sizeof(struct sctp_idata_chunk);
3541 } else {
3542 chkhdr_len = sizeof(struct sctp_data_chunk);
3543 }
3544 /* Use some defaults in case we can't access the chunk header */
3545 if (chk->send_size >= chkhdr_len) {
3546 payload_len = chk->send_size - chkhdr_len;
3547 } else {
3548 payload_len = 0;
3549 }
3550 padding_len = 0;
3551 if (chk->data != NULL) {
3552 chkhdr = mtod(chk->data, struct sctp_chunkhdr *);
3553 if (chkhdr != NULL) {
3554 chk_len = ntohs(chkhdr->chunk_length);
3555 if ((chk_len >= chkhdr_len) &&
3556 (chk->send_size >= chk_len) &&
3557 (chk->send_size - chk_len < 4)) {
3558 padding_len = chk->send_size - chk_len;
3559 payload_len = chk->send_size - chkhdr_len - padding_len;
3560 }
3561 }
3562 }
3563 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3564 ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3565 memset(ssfe, 0, notifhdr_len);
3566 ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3567 if (sent) {
3568 ssfe->ssfe_flags = SCTP_DATA_SENT;
3569 } else {
3570 ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3571 }
3572 ssfe->ssfe_length = (uint32_t)(notifhdr_len + payload_len);
3573 ssfe->ssfe_error = error;
3574 /* not exactly what the user sent in, but should be close :) */
3575 ssfe->ssfe_info.snd_sid = chk->rec.data.sid;
3576 ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
3577 ssfe->ssfe_info.snd_ppid = chk->rec.data.ppid;
3578 ssfe->ssfe_info.snd_context = chk->rec.data.context;
3579 ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3580 ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3581 } else {
3582 ssf = mtod(m_notify, struct sctp_send_failed *);
3583 memset(ssf, 0, notifhdr_len);
3584 ssf->ssf_type = SCTP_SEND_FAILED;
3585 if (sent) {
3586 ssf->ssf_flags = SCTP_DATA_SENT;
3587 } else {
3588 ssf->ssf_flags = SCTP_DATA_UNSENT;
3589 }
3590 ssf->ssf_length = (uint32_t)(notifhdr_len + payload_len);
3591 ssf->ssf_error = error;
3592 /* not exactly what the user sent in, but should be close :) */
3593 ssf->ssf_info.sinfo_stream = chk->rec.data.sid;
3594 ssf->ssf_info.sinfo_ssn = (uint16_t)chk->rec.data.mid;
3595 ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
3596 ssf->ssf_info.sinfo_ppid = chk->rec.data.ppid;
3597 ssf->ssf_info.sinfo_context = chk->rec.data.context;
3598 ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3599 ssf->ssf_assoc_id = sctp_get_associd(stcb);
3600 }
3601 if (chk->data != NULL) {
3602 /* Trim off the sctp chunk header (it should be there) */
3603 if (chk->send_size == chkhdr_len + payload_len + padding_len) {
3604 m_adj(chk->data, chkhdr_len);
3605 m_adj(chk->data, -padding_len);
3606 sctp_mbuf_crush(chk->data);
3607 chk->send_size -= (chkhdr_len + padding_len);
3608 }
3609 }
3610 SCTP_BUF_NEXT(m_notify) = chk->data;
3611 /* Steal off the mbuf */
3612 chk->data = NULL;
3613 /*
3614 * For this case, we check the actual socket buffer, since the assoc
3615 * is going away we don't want to overfill the socket buffer for a
3616 * non-reader
3617 */
3618 if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3619 sctp_m_freem(m_notify);
3620 return;
3621 }
3622 /* append to socket */
3623 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3624 0, 0, stcb->asoc.context, 0, 0, 0,
3625 m_notify);
3626 if (control == NULL) {
3627 /* no memory */
3628 sctp_m_freem(m_notify);
3629 return;
3630 }
3631 control->length = SCTP_BUF_LEN(m_notify);
3632 control->spec_flags = M_NOTIFICATION;
3633 /* not that we need this */
3634 control->tail_mbuf = m_notify;
3635 sctp_add_to_readq(stcb->sctp_ep, stcb,
3636 control,
3637 &stcb->sctp_socket->so_rcv, 1,
3638 SCTP_READ_LOCK_NOT_HELD,
3639 so_locked);
3640 }
3641
3642
3643 static void
sctp_notify_send_failed2(struct sctp_tcb * stcb,uint32_t error,struct sctp_stream_queue_pending * sp,int so_locked SCTP_UNUSED)3644 sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
3645 struct sctp_stream_queue_pending *sp, int so_locked
3646 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3647 SCTP_UNUSED
3648 #endif
3649 )
3650 {
3651 struct mbuf *m_notify;
3652 struct sctp_send_failed *ssf;
3653 struct sctp_send_failed_event *ssfe;
3654 struct sctp_queued_to_read *control;
3655 int notifhdr_len;
3656
3657 if ((stcb == NULL) ||
3658 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
3659 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
3660 /* event not enabled */
3661 return;
3662 }
3663 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3664 notifhdr_len = sizeof(struct sctp_send_failed_event);
3665 } else {
3666 notifhdr_len = sizeof(struct sctp_send_failed);
3667 }
3668 m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3669 if (m_notify == NULL) {
3670 /* no space left */
3671 return;
3672 }
3673 SCTP_BUF_LEN(m_notify) = notifhdr_len;
3674 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3675 ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3676 memset(ssfe, 0, notifhdr_len);
3677 ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3678 ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3679 ssfe->ssfe_length = (uint32_t)(notifhdr_len + sp->length);
3680 ssfe->ssfe_error = error;
3681 /* not exactly what the user sent in, but should be close :) */
3682 ssfe->ssfe_info.snd_sid = sp->sid;
3683 if (sp->some_taken) {
3684 ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
3685 } else {
3686 ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG;
3687 }
3688 ssfe->ssfe_info.snd_ppid = sp->ppid;
3689 ssfe->ssfe_info.snd_context = sp->context;
3690 ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3691 ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3692 } else {
3693 ssf = mtod(m_notify, struct sctp_send_failed *);
3694 memset(ssf, 0, notifhdr_len);
3695 ssf->ssf_type = SCTP_SEND_FAILED;
3696 ssf->ssf_flags = SCTP_DATA_UNSENT;
3697 ssf->ssf_length = (uint32_t)(notifhdr_len + sp->length);
3698 ssf->ssf_error = error;
3699 /* not exactly what the user sent in, but should be close :) */
3700 ssf->ssf_info.sinfo_stream = sp->sid;
3701 ssf->ssf_info.sinfo_ssn = 0;
3702 if (sp->some_taken) {
3703 ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
3704 } else {
3705 ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG;
3706 }
3707 ssf->ssf_info.sinfo_ppid = sp->ppid;
3708 ssf->ssf_info.sinfo_context = sp->context;
3709 ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
3710 ssf->ssf_assoc_id = sctp_get_associd(stcb);
3711 }
3712 SCTP_BUF_NEXT(m_notify) = sp->data;
3713
3714 /* Steal off the mbuf */
3715 sp->data = NULL;
3716 /*
3717 * For this case, we check the actual socket buffer, since the assoc
3718 * is going away we don't want to overfill the socket buffer for a
3719 * non-reader
3720 */
3721 if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3722 sctp_m_freem(m_notify);
3723 return;
3724 }
3725 /* append to socket */
3726 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3727 0, 0, stcb->asoc.context, 0, 0, 0,
3728 m_notify);
3729 if (control == NULL) {
3730 /* no memory */
3731 sctp_m_freem(m_notify);
3732 return;
3733 }
3734 control->length = SCTP_BUF_LEN(m_notify);
3735 control->spec_flags = M_NOTIFICATION;
3736 /* not that we need this */
3737 control->tail_mbuf = m_notify;
3738 sctp_add_to_readq(stcb->sctp_ep, stcb,
3739 control,
3740 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
3741 }
3742
3743
3744
3745 static void
sctp_notify_adaptation_layer(struct sctp_tcb * stcb)3746 sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
3747 {
3748 struct mbuf *m_notify;
3749 struct sctp_adaptation_event *sai;
3750 struct sctp_queued_to_read *control;
3751
3752 if ((stcb == NULL) ||
3753 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) {
3754 /* event not enabled */
3755 return;
3756 }
3757
3758 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_NOWAIT, 1, MT_DATA);
3759 if (m_notify == NULL)
3760 /* no space left */
3761 return;
3762 SCTP_BUF_LEN(m_notify) = 0;
3763 sai = mtod(m_notify, struct sctp_adaptation_event *);
3764 memset(sai, 0, sizeof(struct sctp_adaptation_event));
3765 sai->sai_type = SCTP_ADAPTATION_INDICATION;
3766 sai->sai_flags = 0;
3767 sai->sai_length = sizeof(struct sctp_adaptation_event);
3768 sai->sai_adaptation_ind = stcb->asoc.peers_adaptation;
3769 sai->sai_assoc_id = sctp_get_associd(stcb);
3770
3771 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event);
3772 SCTP_BUF_NEXT(m_notify) = NULL;
3773
3774 /* append to socket */
3775 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3776 0, 0, stcb->asoc.context, 0, 0, 0,
3777 m_notify);
3778 if (control == NULL) {
3779 /* no memory */
3780 sctp_m_freem(m_notify);
3781 return;
3782 }
3783 control->length = SCTP_BUF_LEN(m_notify);
3784 control->spec_flags = M_NOTIFICATION;
3785 /* not that we need this */
3786 control->tail_mbuf = m_notify;
3787 sctp_add_to_readq(stcb->sctp_ep, stcb,
3788 control,
3789 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
3790 }
3791
3792 /* This always must be called with the read-queue LOCKED in the INP */
3793 static void
sctp_notify_partial_delivery_indication(struct sctp_tcb * stcb,uint32_t error,uint32_t val,int so_locked SCTP_UNUSED)3794 sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
3795 uint32_t val, int so_locked
3796 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3797 SCTP_UNUSED
3798 #endif
3799 )
3800 {
3801 struct mbuf *m_notify;
3802 struct sctp_pdapi_event *pdapi;
3803 struct sctp_queued_to_read *control;
3804 struct sockbuf *sb;
3805
3806 if ((stcb == NULL) ||
3807 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) {
3808 /* event not enabled */
3809 return;
3810 }
3811 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
3812 return;
3813 }
3814
3815 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA);
3816 if (m_notify == NULL)
3817 /* no space left */
3818 return;
3819 SCTP_BUF_LEN(m_notify) = 0;
3820 pdapi = mtod(m_notify, struct sctp_pdapi_event *);
3821 memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
3822 pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
3823 pdapi->pdapi_flags = 0;
3824 pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
3825 pdapi->pdapi_indication = error;
3826 pdapi->pdapi_stream = (val >> 16);
3827 pdapi->pdapi_seq = (val & 0x0000ffff);
3828 pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
3829
3830 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
3831 SCTP_BUF_NEXT(m_notify) = NULL;
3832 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3833 0, 0, stcb->asoc.context, 0, 0, 0,
3834 m_notify);
3835 if (control == NULL) {
3836 /* no memory */
3837 sctp_m_freem(m_notify);
3838 return;
3839 }
3840 control->length = SCTP_BUF_LEN(m_notify);
3841 control->spec_flags = M_NOTIFICATION;
3842 /* not that we need this */
3843 control->tail_mbuf = m_notify;
3844 sb = &stcb->sctp_socket->so_rcv;
3845 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
3846 sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify));
3847 }
3848 sctp_sballoc(stcb, sb, m_notify);
3849 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
3850 sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
3851 }
3852 control->end_added = 1;
3853 if (stcb->asoc.control_pdapi)
3854 TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next);
3855 else {
3856 /* we really should not see this case */
3857 TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next);
3858 }
3859 if (stcb->sctp_ep && stcb->sctp_socket) {
3860 /* This should always be the case */
3861 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3862 struct socket *so;
3863
3864 so = SCTP_INP_SO(stcb->sctp_ep);
3865 if (!so_locked) {
3866 atomic_add_int(&stcb->asoc.refcnt, 1);
3867 SCTP_TCB_UNLOCK(stcb);
3868 SCTP_SOCKET_LOCK(so, 1);
3869 SCTP_TCB_LOCK(stcb);
3870 atomic_subtract_int(&stcb->asoc.refcnt, 1);
3871 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
3872 SCTP_SOCKET_UNLOCK(so, 1);
3873 return;
3874 }
3875 }
3876 #endif
3877 sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
3878 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3879 if (!so_locked) {
3880 SCTP_SOCKET_UNLOCK(so, 1);
3881 }
3882 #endif
3883 }
3884 }
3885
3886 static void
sctp_notify_shutdown_event(struct sctp_tcb * stcb)3887 sctp_notify_shutdown_event(struct sctp_tcb *stcb)
3888 {
3889 struct mbuf *m_notify;
3890 struct sctp_shutdown_event *sse;
3891 struct sctp_queued_to_read *control;
3892
3893 /*
3894 * For TCP model AND UDP connected sockets we will send an error up
3895 * when an SHUTDOWN completes
3896 */
3897 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3898 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
3899 /* mark socket closed for read/write and wakeup! */
3900 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3901 struct socket *so;
3902
3903 so = SCTP_INP_SO(stcb->sctp_ep);
3904 atomic_add_int(&stcb->asoc.refcnt, 1);
3905 SCTP_TCB_UNLOCK(stcb);
3906 SCTP_SOCKET_LOCK(so, 1);
3907 SCTP_TCB_LOCK(stcb);
3908 atomic_subtract_int(&stcb->asoc.refcnt, 1);
3909 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
3910 SCTP_SOCKET_UNLOCK(so, 1);
3911 return;
3912 }
3913 #endif
3914 socantsendmore(stcb->sctp_socket);
3915 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
3916 SCTP_SOCKET_UNLOCK(so, 1);
3917 #endif
3918 }
3919 if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) {
3920 /* event not enabled */
3921 return;
3922 }
3923
3924 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_NOWAIT, 1, MT_DATA);
3925 if (m_notify == NULL)
3926 /* no space left */
3927 return;
3928 sse = mtod(m_notify, struct sctp_shutdown_event *);
3929 memset(sse, 0, sizeof(struct sctp_shutdown_event));
3930 sse->sse_type = SCTP_SHUTDOWN_EVENT;
3931 sse->sse_flags = 0;
3932 sse->sse_length = sizeof(struct sctp_shutdown_event);
3933 sse->sse_assoc_id = sctp_get_associd(stcb);
3934
3935 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event);
3936 SCTP_BUF_NEXT(m_notify) = NULL;
3937
3938 /* append to socket */
3939 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3940 0, 0, stcb->asoc.context, 0, 0, 0,
3941 m_notify);
3942 if (control == NULL) {
3943 /* no memory */
3944 sctp_m_freem(m_notify);
3945 return;
3946 }
3947 control->length = SCTP_BUF_LEN(m_notify);
3948 control->spec_flags = M_NOTIFICATION;
3949 /* not that we need this */
3950 control->tail_mbuf = m_notify;
3951 sctp_add_to_readq(stcb->sctp_ep, stcb,
3952 control,
3953 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
3954 }
3955
3956 static void
sctp_notify_sender_dry_event(struct sctp_tcb * stcb,int so_locked SCTP_UNUSED)3957 sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
3958 int so_locked
3959 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
3960 SCTP_UNUSED
3961 #endif
3962 )
3963 {
3964 struct mbuf *m_notify;
3965 struct sctp_sender_dry_event *event;
3966 struct sctp_queued_to_read *control;
3967
3968 if ((stcb == NULL) ||
3969 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) {
3970 /* event not enabled */
3971 return;
3972 }
3973
3974 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_sender_dry_event), 0, M_NOWAIT, 1, MT_DATA);
3975 if (m_notify == NULL) {
3976 /* no space left */
3977 return;
3978 }
3979 SCTP_BUF_LEN(m_notify) = 0;
3980 event = mtod(m_notify, struct sctp_sender_dry_event *);
3981 memset(event, 0, sizeof(struct sctp_sender_dry_event));
3982 event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
3983 event->sender_dry_flags = 0;
3984 event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
3985 event->sender_dry_assoc_id = sctp_get_associd(stcb);
3986
3987 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_sender_dry_event);
3988 SCTP_BUF_NEXT(m_notify) = NULL;
3989
3990 /* append to socket */
3991 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3992 0, 0, stcb->asoc.context, 0, 0, 0,
3993 m_notify);
3994 if (control == NULL) {
3995 /* no memory */
3996 sctp_m_freem(m_notify);
3997 return;
3998 }
3999 control->length = SCTP_BUF_LEN(m_notify);
4000 control->spec_flags = M_NOTIFICATION;
4001 /* not that we need this */
4002 control->tail_mbuf = m_notify;
4003 sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4004 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
4005 }
4006
4007
4008 void
sctp_notify_stream_reset_add(struct sctp_tcb * stcb,uint16_t numberin,uint16_t numberout,int flag)4009 sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t numberout, int flag)
4010 {
4011 struct mbuf *m_notify;
4012 struct sctp_queued_to_read *control;
4013 struct sctp_stream_change_event *stradd;
4014
4015 if ((stcb == NULL) ||
4016 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
4017 /* event not enabled */
4018 return;
4019 }
4020 if ((stcb->asoc.peer_req_out) && flag) {
4021 /* Peer made the request, don't tell the local user */
4022 stcb->asoc.peer_req_out = 0;
4023 return;
4024 }
4025 stcb->asoc.peer_req_out = 0;
4026 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
4027 if (m_notify == NULL)
4028 /* no space left */
4029 return;
4030 SCTP_BUF_LEN(m_notify) = 0;
4031 stradd = mtod(m_notify, struct sctp_stream_change_event *);
4032 memset(stradd, 0, sizeof(struct sctp_stream_change_event));
4033 stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
4034 stradd->strchange_flags = flag;
4035 stradd->strchange_length = sizeof(struct sctp_stream_change_event);
4036 stradd->strchange_assoc_id = sctp_get_associd(stcb);
4037 stradd->strchange_instrms = numberin;
4038 stradd->strchange_outstrms = numberout;
4039 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
4040 SCTP_BUF_NEXT(m_notify) = NULL;
4041 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4042 /* no space */
4043 sctp_m_freem(m_notify);
4044 return;
4045 }
4046 /* append to socket */
4047 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4048 0, 0, stcb->asoc.context, 0, 0, 0,
4049 m_notify);
4050 if (control == NULL) {
4051 /* no memory */
4052 sctp_m_freem(m_notify);
4053 return;
4054 }
4055 control->length = SCTP_BUF_LEN(m_notify);
4056 control->spec_flags = M_NOTIFICATION;
4057 /* not that we need this */
4058 control->tail_mbuf = m_notify;
4059 sctp_add_to_readq(stcb->sctp_ep, stcb,
4060 control,
4061 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4062 }
4063
4064 void
sctp_notify_stream_reset_tsn(struct sctp_tcb * stcb,uint32_t sending_tsn,uint32_t recv_tsn,int flag)4065 sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag)
4066 {
4067 struct mbuf *m_notify;
4068 struct sctp_queued_to_read *control;
4069 struct sctp_assoc_reset_event *strasoc;
4070
4071 if ((stcb == NULL) ||
4072 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
4073 /* event not enabled */
4074 return;
4075 }
4076 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
4077 if (m_notify == NULL)
4078 /* no space left */
4079 return;
4080 SCTP_BUF_LEN(m_notify) = 0;
4081 strasoc = mtod(m_notify, struct sctp_assoc_reset_event *);
4082 memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
4083 strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
4084 strasoc->assocreset_flags = flag;
4085 strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
4086 strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
4087 strasoc->assocreset_local_tsn = sending_tsn;
4088 strasoc->assocreset_remote_tsn = recv_tsn;
4089 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
4090 SCTP_BUF_NEXT(m_notify) = NULL;
4091 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4092 /* no space */
4093 sctp_m_freem(m_notify);
4094 return;
4095 }
4096 /* append to socket */
4097 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4098 0, 0, stcb->asoc.context, 0, 0, 0,
4099 m_notify);
4100 if (control == NULL) {
4101 /* no memory */
4102 sctp_m_freem(m_notify);
4103 return;
4104 }
4105 control->length = SCTP_BUF_LEN(m_notify);
4106 control->spec_flags = M_NOTIFICATION;
4107 /* not that we need this */
4108 control->tail_mbuf = m_notify;
4109 sctp_add_to_readq(stcb->sctp_ep, stcb,
4110 control,
4111 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4112 }
4113
4114
4115
4116 static void
sctp_notify_stream_reset(struct sctp_tcb * stcb,int number_entries,uint16_t * list,int flag)4117 sctp_notify_stream_reset(struct sctp_tcb *stcb,
4118 int number_entries, uint16_t * list, int flag)
4119 {
4120 struct mbuf *m_notify;
4121 struct sctp_queued_to_read *control;
4122 struct sctp_stream_reset_event *strreset;
4123 int len;
4124
4125 if ((stcb == NULL) ||
4126 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) {
4127 /* event not enabled */
4128 return;
4129 }
4130
4131 m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
4132 if (m_notify == NULL)
4133 /* no space left */
4134 return;
4135 SCTP_BUF_LEN(m_notify) = 0;
4136 len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
4137 if (len > M_TRAILINGSPACE(m_notify)) {
4138 /* never enough room */
4139 sctp_m_freem(m_notify);
4140 return;
4141 }
4142 strreset = mtod(m_notify, struct sctp_stream_reset_event *);
4143 memset(strreset, 0, len);
4144 strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
4145 strreset->strreset_flags = flag;
4146 strreset->strreset_length = len;
4147 strreset->strreset_assoc_id = sctp_get_associd(stcb);
4148 if (number_entries) {
4149 int i;
4150
4151 for (i = 0; i < number_entries; i++) {
4152 strreset->strreset_stream_list[i] = ntohs(list[i]);
4153 }
4154 }
4155 SCTP_BUF_LEN(m_notify) = len;
4156 SCTP_BUF_NEXT(m_notify) = NULL;
4157 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4158 /* no space */
4159 sctp_m_freem(m_notify);
4160 return;
4161 }
4162 /* append to socket */
4163 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4164 0, 0, stcb->asoc.context, 0, 0, 0,
4165 m_notify);
4166 if (control == NULL) {
4167 /* no memory */
4168 sctp_m_freem(m_notify);
4169 return;
4170 }
4171 control->length = SCTP_BUF_LEN(m_notify);
4172 control->spec_flags = M_NOTIFICATION;
4173 /* not that we need this */
4174 control->tail_mbuf = m_notify;
4175 sctp_add_to_readq(stcb->sctp_ep, stcb,
4176 control,
4177 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4178 }
4179
4180
4181 static void
sctp_notify_remote_error(struct sctp_tcb * stcb,uint16_t error,struct sctp_error_chunk * chunk)4182 sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_error_chunk *chunk)
4183 {
4184 struct mbuf *m_notify;
4185 struct sctp_remote_error *sre;
4186 struct sctp_queued_to_read *control;
4187 unsigned int notif_len;
4188 uint16_t chunk_len;
4189
4190 if ((stcb == NULL) ||
4191 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) {
4192 return;
4193 }
4194 if (chunk != NULL) {
4195 chunk_len = ntohs(chunk->ch.chunk_length);
4196 /*
4197 * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
4198 * contiguous.
4199 */
4200 if (chunk_len > SCTP_CHUNK_BUFFER_SIZE) {
4201 chunk_len = SCTP_CHUNK_BUFFER_SIZE;
4202 }
4203 } else {
4204 chunk_len = 0;
4205 }
4206 notif_len = (unsigned int)(sizeof(struct sctp_remote_error) + chunk_len);
4207 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
4208 if (m_notify == NULL) {
4209 /* Retry with smaller value. */
4210 notif_len = (unsigned int)sizeof(struct sctp_remote_error);
4211 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
4212 if (m_notify == NULL) {
4213 return;
4214 }
4215 }
4216 SCTP_BUF_NEXT(m_notify) = NULL;
4217 sre = mtod(m_notify, struct sctp_remote_error *);
4218 memset(sre, 0, notif_len);
4219 sre->sre_type = SCTP_REMOTE_ERROR;
4220 sre->sre_flags = 0;
4221 sre->sre_length = sizeof(struct sctp_remote_error);
4222 sre->sre_error = error;
4223 sre->sre_assoc_id = sctp_get_associd(stcb);
4224 if (notif_len > sizeof(struct sctp_remote_error)) {
4225 memcpy(sre->sre_data, chunk, chunk_len);
4226 sre->sre_length += chunk_len;
4227 }
4228 SCTP_BUF_LEN(m_notify) = sre->sre_length;
4229 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4230 0, 0, stcb->asoc.context, 0, 0, 0,
4231 m_notify);
4232 if (control != NULL) {
4233 control->length = SCTP_BUF_LEN(m_notify);
4234 control->spec_flags = M_NOTIFICATION;
4235 /* not that we need this */
4236 control->tail_mbuf = m_notify;
4237 sctp_add_to_readq(stcb->sctp_ep, stcb,
4238 control,
4239 &stcb->sctp_socket->so_rcv, 1,
4240 SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED);
4241 } else {
4242 sctp_m_freem(m_notify);
4243 }
4244 }
4245
4246
4247 void
sctp_ulp_notify(uint32_t notification,struct sctp_tcb * stcb,uint32_t error,void * data,int so_locked SCTP_UNUSED)4248 sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
4249 uint32_t error, void *data, int so_locked
4250 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4251 SCTP_UNUSED
4252 #endif
4253 )
4254 {
4255 if ((stcb == NULL) ||
4256 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4257 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4258 (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
4259 /* If the socket is gone we are out of here */
4260 return;
4261 }
4262 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
4263 if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) {
4264 #else
4265 if (stcb->sctp_socket->so_state & SS_CANTRCVMORE) {
4266 #endif
4267 return;
4268 }
4269 #if defined(__APPLE__)
4270 if (so_locked) {
4271 sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4272 } else {
4273 sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4274 }
4275 #endif
4276 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4277 (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4278 if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
4279 (notification == SCTP_NOTIFY_INTERFACE_UP) ||
4280 (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
4281 /* Don't report these in front states */
4282 return;
4283 }
4284 }
4285 switch (notification) {
4286 case SCTP_NOTIFY_ASSOC_UP:
4287 if (stcb->asoc.assoc_up_sent == 0) {
4288 sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked);
4289 stcb->asoc.assoc_up_sent = 1;
4290 }
4291 if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
4292 sctp_notify_adaptation_layer(stcb);
4293 }
4294 if (stcb->asoc.auth_supported == 0) {
4295 sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
4296 NULL, so_locked);
4297 }
4298 break;
4299 case SCTP_NOTIFY_ASSOC_DOWN:
4300 sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked);
4301 #if defined(__Userspace__)
4302 if (stcb->sctp_ep->recv_callback) {
4303 if (stcb->sctp_socket) {
4304 union sctp_sockstore addr;
4305 struct sctp_rcvinfo rcv;
4306
4307 memset(&addr, 0, sizeof(union sctp_sockstore));
4308 memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
4309 atomic_add_int(&stcb->asoc.refcnt, 1);
4310 SCTP_TCB_UNLOCK(stcb);
4311 stcb->sctp_ep->recv_callback(stcb->sctp_socket, addr, NULL, 0, rcv, 0, stcb->sctp_ep->ulp_info);
4312 SCTP_TCB_LOCK(stcb);
4313 atomic_subtract_int(&stcb->asoc.refcnt, 1);
4314 }
4315 }
4316 #endif
4317 break;
4318 case SCTP_NOTIFY_INTERFACE_DOWN:
4319 {
4320 struct sctp_nets *net;
4321
4322 net = (struct sctp_nets *)data;
4323 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
4324 (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4325 break;
4326 }
4327 case SCTP_NOTIFY_INTERFACE_UP:
4328 {
4329 struct sctp_nets *net;
4330
4331 net = (struct sctp_nets *)data;
4332 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
4333 (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4334 break;
4335 }
4336 case SCTP_NOTIFY_INTERFACE_CONFIRMED:
4337 {
4338 struct sctp_nets *net;
4339
4340 net = (struct sctp_nets *)data;
4341 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
4342 (struct sockaddr *)&net->ro._l_addr, error, so_locked);
4343 break;
4344 }
4345 case SCTP_NOTIFY_SPECIAL_SP_FAIL:
4346 sctp_notify_send_failed2(stcb, error,
4347 (struct sctp_stream_queue_pending *)data, so_locked);
4348 break;
4349 case SCTP_NOTIFY_SENT_DG_FAIL:
4350 sctp_notify_send_failed(stcb, 1, error,
4351 (struct sctp_tmit_chunk *)data, so_locked);
4352 break;
4353 case SCTP_NOTIFY_UNSENT_DG_FAIL:
4354 sctp_notify_send_failed(stcb, 0, error,
4355 (struct sctp_tmit_chunk *)data, so_locked);
4356 break;
4357 case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
4358 {
4359 uint32_t val;
4360 val = *((uint32_t *)data);
4361
4362 sctp_notify_partial_delivery_indication(stcb, error, val, so_locked);
4363 break;
4364 }
4365 case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
4366 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4367 (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4368 sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked);
4369 } else {
4370 sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked);
4371 }
4372 break;
4373 case SCTP_NOTIFY_ASSOC_REM_ABORTED:
4374 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4375 (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4376 sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked);
4377 } else {
4378 sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked);
4379 }
4380 break;
4381 case SCTP_NOTIFY_ASSOC_RESTART:
4382 sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
4383 if (stcb->asoc.auth_supported == 0) {
4384 sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
4385 NULL, so_locked);
4386 }
4387 break;
4388 case SCTP_NOTIFY_STR_RESET_SEND:
4389 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN);
4390 break;
4391 case SCTP_NOTIFY_STR_RESET_RECV:
4392 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING);
4393 break;
4394 case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
4395 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4396 (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
4397 break;
4398 case SCTP_NOTIFY_STR_RESET_DENIED_OUT:
4399 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4400 (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_DENIED));
4401 break;
4402 case SCTP_NOTIFY_STR_RESET_FAILED_IN:
4403 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4404 (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
4405 break;
4406 case SCTP_NOTIFY_STR_RESET_DENIED_IN:
4407 sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
4408 (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED));
4409 break;
4410 case SCTP_NOTIFY_ASCONF_ADD_IP:
4411 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
4412 error, so_locked);
4413 break;
4414 case SCTP_NOTIFY_ASCONF_DELETE_IP:
4415 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
4416 error, so_locked);
4417 break;
4418 case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
4419 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
4420 error, so_locked);
4421 break;
4422 case SCTP_NOTIFY_PEER_SHUTDOWN:
4423 sctp_notify_shutdown_event(stcb);
4424 break;
4425 case SCTP_NOTIFY_AUTH_NEW_KEY:
4426 sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error,
4427 (uint16_t)(uintptr_t)data,
4428 so_locked);
4429 break;
4430 case SCTP_NOTIFY_AUTH_FREE_KEY:
4431 sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error,
4432 (uint16_t)(uintptr_t)data,
4433 so_locked);
4434 break;
4435 case SCTP_NOTIFY_NO_PEER_AUTH:
4436 sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error,
4437 (uint16_t)(uintptr_t)data,
4438 so_locked);
4439 break;
4440 case SCTP_NOTIFY_SENDER_DRY:
4441 sctp_notify_sender_dry_event(stcb, so_locked);
4442 break;
4443 case SCTP_NOTIFY_REMOTE_ERROR:
4444 sctp_notify_remote_error(stcb, error, data);
4445 break;
4446 default:
4447 SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n",
4448 __func__, notification, notification);
4449 break;
4450 } /* end switch */
4451 }
4452
4453 void
4454 sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
4455 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4456 SCTP_UNUSED
4457 #endif
4458 )
4459 {
4460 struct sctp_association *asoc;
4461 struct sctp_stream_out *outs;
4462 struct sctp_tmit_chunk *chk, *nchk;
4463 struct sctp_stream_queue_pending *sp, *nsp;
4464 int i;
4465
4466 if (stcb == NULL) {
4467 return;
4468 }
4469 asoc = &stcb->asoc;
4470 if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
4471 /* already being freed */
4472 return;
4473 }
4474 #if defined(__APPLE__)
4475 if (so_locked) {
4476 sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4477 } else {
4478 sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4479 }
4480 #endif
4481 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4482 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4483 (asoc->state & SCTP_STATE_CLOSED_SOCKET)) {
4484 return;
4485 }
4486 /* now through all the gunk freeing chunks */
4487 if (holds_lock == 0) {
4488 SCTP_TCB_SEND_LOCK(stcb);
4489 }
4490 /* sent queue SHOULD be empty */
4491 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
4492 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
4493 asoc->sent_queue_cnt--;
4494 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
4495 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4496 asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4497 #ifdef INVARIANTS
4498 } else {
4499 panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4500 #endif
4501 }
4502 }
4503 if (chk->data != NULL) {
4504 sctp_free_bufspace(stcb, asoc, chk, 1);
4505 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
4506 error, chk, so_locked);
4507 if (chk->data) {
4508 sctp_m_freem(chk->data);
4509 chk->data = NULL;
4510 }
4511 }
4512 sctp_free_a_chunk(stcb, chk, so_locked);
4513 /*sa_ignore FREED_MEMORY*/
4514 }
4515 /* pending send queue SHOULD be empty */
4516 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
4517 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
4518 asoc->send_queue_cnt--;
4519 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4520 asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4521 #ifdef INVARIANTS
4522 } else {
4523 panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4524 #endif
4525 }
4526 if (chk->data != NULL) {
4527 sctp_free_bufspace(stcb, asoc, chk, 1);
4528 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
4529 error, chk, so_locked);
4530 if (chk->data) {
4531 sctp_m_freem(chk->data);
4532 chk->data = NULL;
4533 }
4534 }
4535 sctp_free_a_chunk(stcb, chk, so_locked);
4536 /*sa_ignore FREED_MEMORY*/
4537 }
4538 for (i = 0; i < asoc->streamoutcnt; i++) {
4539 /* For each stream */
4540 outs = &asoc->strmout[i];
4541 /* clean up any sends there */
4542 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
4543 atomic_subtract_int(&asoc->stream_queue_cnt, 1);
4544 TAILQ_REMOVE(&outs->outqueue, sp, next);
4545 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 1);
4546 sctp_free_spbufspace(stcb, asoc, sp);
4547 if (sp->data) {
4548 sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
4549 error, (void *)sp, so_locked);
4550 if (sp->data) {
4551 sctp_m_freem(sp->data);
4552 sp->data = NULL;
4553 sp->tail_mbuf = NULL;
4554 sp->length = 0;
4555 }
4556 }
4557 if (sp->net) {
4558 sctp_free_remote_addr(sp->net);
4559 sp->net = NULL;
4560 }
4561 /* Free the chunk */
4562 sctp_free_a_strmoq(stcb, sp, so_locked);
4563 /*sa_ignore FREED_MEMORY*/
4564 }
4565 }
4566
4567 if (holds_lock == 0) {
4568 SCTP_TCB_SEND_UNLOCK(stcb);
4569 }
4570 }
4571
4572 void
4573 sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error,
4574 struct sctp_abort_chunk *abort, int so_locked
4575 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4576 SCTP_UNUSED
4577 #endif
4578 )
4579 {
4580 if (stcb == NULL) {
4581 return;
4582 }
4583 #if defined(__APPLE__)
4584 if (so_locked) {
4585 sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
4586 } else {
4587 sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
4588 }
4589 #endif
4590 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
4591 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4592 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
4593 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED;
4594 }
4595 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4596 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4597 (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
4598 return;
4599 }
4600 /* Tell them we lost the asoc */
4601 sctp_report_all_outbound(stcb, error, 0, so_locked);
4602 if (from_peer) {
4603 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
4604 } else {
4605 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked);
4606 }
4607 }
4608
4609 void
4610 sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
4611 struct mbuf *m, int iphlen,
4612 struct sockaddr *src, struct sockaddr *dst,
4613 struct sctphdr *sh, struct mbuf *op_err,
4614 #if defined(__FreeBSD__)
4615 uint8_t mflowtype, uint32_t mflowid,
4616 #endif
4617 uint32_t vrf_id, uint16_t port)
4618 {
4619 uint32_t vtag;
4620 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4621 struct socket *so;
4622 #endif
4623
4624 vtag = 0;
4625 if (stcb != NULL) {
4626 vtag = stcb->asoc.peer_vtag;
4627 vrf_id = stcb->asoc.vrf_id;
4628 }
4629 sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
4630 #if defined(__FreeBSD__)
4631 mflowtype, mflowid, inp->fibnum,
4632 #endif
4633 vrf_id, port);
4634 if (stcb != NULL) {
4635 /* We have a TCB to abort, send notification too */
4636 sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED);
4637 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
4638 /* Ok, now lets free it */
4639 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4640 so = SCTP_INP_SO(inp);
4641 atomic_add_int(&stcb->asoc.refcnt, 1);
4642 SCTP_TCB_UNLOCK(stcb);
4643 SCTP_SOCKET_LOCK(so, 1);
4644 SCTP_TCB_LOCK(stcb);
4645 atomic_subtract_int(&stcb->asoc.refcnt, 1);
4646 #endif
4647 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4648 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4649 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4650 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4651 }
4652 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4653 SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
4654 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4655 SCTP_SOCKET_UNLOCK(so, 1);
4656 #endif
4657 }
4658 }
4659 #ifdef SCTP_ASOCLOG_OF_TSNS
4660 void
4661 sctp_print_out_track_log(struct sctp_tcb *stcb)
4662 {
4663 #ifdef NOSIY_PRINTS
4664 int i;
4665 SCTP_PRINTF("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code);
4666 SCTP_PRINTF("IN bound TSN log-aaa\n");
4667 if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) {
4668 SCTP_PRINTF("None rcvd\n");
4669 goto none_in;
4670 }
4671 if (stcb->asoc.tsn_in_wrapped) {
4672 for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) {
4673 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4674 stcb->asoc.in_tsnlog[i].tsn,
4675 stcb->asoc.in_tsnlog[i].strm,
4676 stcb->asoc.in_tsnlog[i].seq,
4677 stcb->asoc.in_tsnlog[i].flgs,
4678 stcb->asoc.in_tsnlog[i].sz);
4679 }
4680 }
4681 if (stcb->asoc.tsn_in_at) {
4682 for (i = 0; i < stcb->asoc.tsn_in_at; i++) {
4683 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4684 stcb->asoc.in_tsnlog[i].tsn,
4685 stcb->asoc.in_tsnlog[i].strm,
4686 stcb->asoc.in_tsnlog[i].seq,
4687 stcb->asoc.in_tsnlog[i].flgs,
4688 stcb->asoc.in_tsnlog[i].sz);
4689 }
4690 }
4691 none_in:
4692 SCTP_PRINTF("OUT bound TSN log-aaa\n");
4693 if ((stcb->asoc.tsn_out_at == 0) &&
4694 (stcb->asoc.tsn_out_wrapped == 0)) {
4695 SCTP_PRINTF("None sent\n");
4696 }
4697 if (stcb->asoc.tsn_out_wrapped) {
4698 for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) {
4699 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4700 stcb->asoc.out_tsnlog[i].tsn,
4701 stcb->asoc.out_tsnlog[i].strm,
4702 stcb->asoc.out_tsnlog[i].seq,
4703 stcb->asoc.out_tsnlog[i].flgs,
4704 stcb->asoc.out_tsnlog[i].sz);
4705 }
4706 }
4707 if (stcb->asoc.tsn_out_at) {
4708 for (i = 0; i < stcb->asoc.tsn_out_at; i++) {
4709 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n",
4710 stcb->asoc.out_tsnlog[i].tsn,
4711 stcb->asoc.out_tsnlog[i].strm,
4712 stcb->asoc.out_tsnlog[i].seq,
4713 stcb->asoc.out_tsnlog[i].flgs,
4714 stcb->asoc.out_tsnlog[i].sz);
4715 }
4716 }
4717 #endif
4718 }
4719 #endif
4720
4721 void
4722 sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
4723 struct mbuf *op_err,
4724 int so_locked
4725 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
4726 SCTP_UNUSED
4727 #endif
4728 )
4729 {
4730 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4731 struct socket *so;
4732 #endif
4733
4734 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4735 so = SCTP_INP_SO(inp);
4736 #endif
4737 #if defined(__APPLE__)
4738 if (so_locked) {
4739 sctp_lock_assert(SCTP_INP_SO(inp));
4740 } else {
4741 sctp_unlock_assert(SCTP_INP_SO(inp));
4742 }
4743 #endif
4744 if (stcb == NULL) {
4745 /* Got to have a TCB */
4746 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
4747 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
4748 #if defined(__APPLE__)
4749 if (!so_locked) {
4750 SCTP_SOCKET_LOCK(so, 1);
4751 }
4752 #endif
4753 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
4754 SCTP_CALLED_DIRECTLY_NOCMPSET);
4755 #if defined(__APPLE__)
4756 if (!so_locked) {
4757 SCTP_SOCKET_UNLOCK(so, 1);
4758 }
4759 #endif
4760 }
4761 }
4762 return;
4763 } else {
4764 SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
4765 }
4766 /* notify the peer */
4767 sctp_send_abort_tcb(stcb, op_err, so_locked);
4768 SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4769 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4770 (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4771 SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4772 }
4773 /* notify the ulp */
4774 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
4775 sctp_abort_notification(stcb, 0, 0, NULL, so_locked);
4776 }
4777 /* now free the asoc */
4778 #ifdef SCTP_ASOCLOG_OF_TSNS
4779 sctp_print_out_track_log(stcb);
4780 #endif
4781 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4782 if (!so_locked) {
4783 atomic_add_int(&stcb->asoc.refcnt, 1);
4784 SCTP_TCB_UNLOCK(stcb);
4785 SCTP_SOCKET_LOCK(so, 1);
4786 SCTP_TCB_LOCK(stcb);
4787 atomic_subtract_int(&stcb->asoc.refcnt, 1);
4788 }
4789 #endif
4790 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4791 SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
4792 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
4793 if (!so_locked) {
4794 SCTP_SOCKET_UNLOCK(so, 1);
4795 }
4796 #endif
4797 }
4798
4799 void
4800 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
4801 struct sockaddr *src, struct sockaddr *dst,
4802 struct sctphdr *sh, struct sctp_inpcb *inp,
4803 struct mbuf *cause,
4804 #if defined(__FreeBSD__)
4805 uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum,
4806 #endif
4807 uint32_t vrf_id, uint16_t port)
4808 {
4809 struct sctp_chunkhdr *ch, chunk_buf;
4810 unsigned int chk_length;
4811 int contains_init_chunk;
4812
4813 SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
4814 /* Generate a TO address for future reference */
4815 if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
4816 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
4817 #if defined(__APPLE__)
4818 SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
4819 #endif
4820 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
4821 SCTP_CALLED_DIRECTLY_NOCMPSET);
4822 #if defined(__APPLE__)
4823 SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1);
4824 #endif
4825 }
4826 }
4827 contains_init_chunk = 0;
4828 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4829 sizeof(*ch), (uint8_t *) & chunk_buf);
4830 while (ch != NULL) {
4831 chk_length = ntohs(ch->chunk_length);
4832 if (chk_length < sizeof(*ch)) {
4833 /* break to abort land */
4834 break;
4835 }
4836 switch (ch->chunk_type) {
4837 case SCTP_INIT:
4838 contains_init_chunk = 1;
4839 break;
4840 case SCTP_PACKET_DROPPED:
4841 /* we don't respond to pkt-dropped */
4842 return;
4843 case SCTP_ABORT_ASSOCIATION:
4844 /* we don't respond with an ABORT to an ABORT */
4845 return;
4846 case SCTP_SHUTDOWN_COMPLETE:
4847 /*
4848 * we ignore it since we are not waiting for it and
4849 * peer is gone
4850 */
4851 return;
4852 case SCTP_SHUTDOWN_ACK:
4853 sctp_send_shutdown_complete2(src, dst, sh,
4854 #if defined(__FreeBSD__)
4855 mflowtype, mflowid, fibnum,
4856 #endif
4857 vrf_id, port);
4858 return;
4859 default:
4860 break;
4861 }
4862 offset += SCTP_SIZE32(chk_length);
4863 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4864 sizeof(*ch), (uint8_t *) & chunk_buf);
4865 }
4866 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
4867 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
4868 (contains_init_chunk == 0))) {
4869 sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
4870 #if defined(__FreeBSD__)
4871 mflowtype, mflowid, fibnum,
4872 #endif
4873 vrf_id, port);
4874 }
4875 }
4876
4877 /*
4878 * check the inbound datagram to make sure there is not an abort inside it,
4879 * if there is return 1, else return 0.
4880 */
4881 int
4882 sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t * vtagfill)
4883 {
4884 struct sctp_chunkhdr *ch;
4885 struct sctp_init_chunk *init_chk, chunk_buf;
4886 int offset;
4887 unsigned int chk_length;
4888
4889 offset = iphlen + sizeof(struct sctphdr);
4890 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
4891 (uint8_t *) & chunk_buf);
4892 while (ch != NULL) {
4893 chk_length = ntohs(ch->chunk_length);
4894 if (chk_length < sizeof(*ch)) {
4895 /* packet is probably corrupt */
4896 break;
4897 }
4898 /* we seem to be ok, is it an abort? */
4899 if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
4900 /* yep, tell them */
4901 return (1);
4902 }
4903 if (ch->chunk_type == SCTP_INITIATION) {
4904 /* need to update the Vtag */
4905 init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
4906 offset, sizeof(*init_chk), (uint8_t *) & chunk_buf);
4907 if (init_chk != NULL) {
4908 *vtagfill = ntohl(init_chk->init.initiate_tag);
4909 }
4910 }
4911 /* Nope, move to the next chunk */
4912 offset += SCTP_SIZE32(chk_length);
4913 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4914 sizeof(*ch), (uint8_t *) & chunk_buf);
4915 }
4916 return (0);
4917 }
4918
4919 /*
4920 * currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id
4921 * set (i.e. it's 0) so, create this function to compare link local scopes
4922 */
4923 #ifdef INET6
4924 uint32_t
4925 sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2)
4926 {
4927 #if defined(__Userspace__)
4928 /*__Userspace__ Returning 1 here always */
4929 #endif
4930 #if defined(SCTP_EMBEDDED_V6_SCOPE)
4931 struct sockaddr_in6 a, b;
4932
4933 /* save copies */
4934 a = *addr1;
4935 b = *addr2;
4936
4937 if (a.sin6_scope_id == 0)
4938 #ifdef SCTP_KAME
4939 if (sa6_recoverscope(&a)) {
4940 #else
4941 if (in6_recoverscope(&a, &a.sin6_addr, NULL)) {
4942 #endif /* SCTP_KAME */
4943 /* can't get scope, so can't match */
4944 return (0);
4945 }
4946 if (b.sin6_scope_id == 0)
4947 #ifdef SCTP_KAME
4948 if (sa6_recoverscope(&b)) {
4949 #else
4950 if (in6_recoverscope(&b, &b.sin6_addr, NULL)) {
4951 #endif /* SCTP_KAME */
4952 /* can't get scope, so can't match */
4953 return (0);
4954 }
4955 if (a.sin6_scope_id != b.sin6_scope_id)
4956 return (0);
4957 #else
4958 if (addr1->sin6_scope_id != addr2->sin6_scope_id)
4959 return (0);
4960 #endif /* SCTP_EMBEDDED_V6_SCOPE */
4961
4962 return (1);
4963 }
4964
4965 #if defined(SCTP_EMBEDDED_V6_SCOPE)
4966 /*
4967 * returns a sockaddr_in6 with embedded scope recovered and removed
4968 */
4969 struct sockaddr_in6 *
4970 sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
4971 {
4972 /* check and strip embedded scope junk */
4973 if (addr->sin6_family == AF_INET6) {
4974 if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
4975 if (addr->sin6_scope_id == 0) {
4976 *store = *addr;
4977 #ifdef SCTP_KAME
4978 if (!sa6_recoverscope(store)) {
4979 #else
4980 if (!in6_recoverscope(store, &store->sin6_addr,
4981 NULL)) {
4982 #endif /* SCTP_KAME */
4983 /* use the recovered scope */
4984 addr = store;
4985 }
4986 } else {
4987 /* else, return the original "to" addr */
4988 in6_clearscope(&addr->sin6_addr);
4989 }
4990 }
4991 }
4992 return (addr);
4993 }
4994 #endif /* SCTP_EMBEDDED_V6_SCOPE */
4995 #endif
4996
4997 /*
4998 * are the two addresses the same? currently a "scopeless" check returns: 1
4999 * if same, 0 if not
5000 */
5001 int
5002 sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
5003 {
5004
5005 /* must be valid */
5006 if (sa1 == NULL || sa2 == NULL)
5007 return (0);
5008
5009 /* must be the same family */
5010 if (sa1->sa_family != sa2->sa_family)
5011 return (0);
5012
5013 switch (sa1->sa_family) {
5014 #ifdef INET6
5015 case AF_INET6:
5016 {
5017 /* IPv6 addresses */
5018 struct sockaddr_in6 *sin6_1, *sin6_2;
5019
5020 sin6_1 = (struct sockaddr_in6 *)sa1;
5021 sin6_2 = (struct sockaddr_in6 *)sa2;
5022 return (SCTP6_ARE_ADDR_EQUAL(sin6_1,
5023 sin6_2));
5024 }
5025 #endif
5026 #ifdef INET
5027 case AF_INET:
5028 {
5029 /* IPv4 addresses */
5030 struct sockaddr_in *sin_1, *sin_2;
5031
5032 sin_1 = (struct sockaddr_in *)sa1;
5033 sin_2 = (struct sockaddr_in *)sa2;
5034 return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
5035 }
5036 #endif
5037 #if defined(__Userspace__)
5038 case AF_CONN:
5039 {
5040 struct sockaddr_conn *sconn_1, *sconn_2;
5041
5042 sconn_1 = (struct sockaddr_conn *)sa1;
5043 sconn_2 = (struct sockaddr_conn *)sa2;
5044 return (sconn_1->sconn_addr == sconn_2->sconn_addr);
5045 }
5046 #endif
5047 default:
5048 /* we don't do these... */
5049 return (0);
5050 }
5051 }
5052
5053 void
5054 sctp_print_address(struct sockaddr *sa)
5055 {
5056 #ifdef INET6
5057 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
5058 char ip6buf[INET6_ADDRSTRLEN];
5059 #endif
5060 #endif
5061
5062 switch (sa->sa_family) {
5063 #ifdef INET6
5064 case AF_INET6:
5065 {
5066 struct sockaddr_in6 *sin6;
5067
5068 sin6 = (struct sockaddr_in6 *)sa;
5069 #if defined(__Userspace__)
5070 SCTP_PRINTF("IPv6 address: %x:%x:%x:%x:%x:%x:%x:%x:port:%d scope:%u\n",
5071 ntohs(sin6->sin6_addr.s6_addr16[0]),
5072 ntohs(sin6->sin6_addr.s6_addr16[1]),
5073 ntohs(sin6->sin6_addr.s6_addr16[2]),
5074 ntohs(sin6->sin6_addr.s6_addr16[3]),
5075 ntohs(sin6->sin6_addr.s6_addr16[4]),
5076 ntohs(sin6->sin6_addr.s6_addr16[5]),
5077 ntohs(sin6->sin6_addr.s6_addr16[6]),
5078 ntohs(sin6->sin6_addr.s6_addr16[7]),
5079 ntohs(sin6->sin6_port),
5080 sin6->sin6_scope_id);
5081 #else
5082 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
5083 SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
5084 ip6_sprintf(ip6buf, &sin6->sin6_addr),
5085 ntohs(sin6->sin6_port),
5086 sin6->sin6_scope_id);
5087 #else
5088 SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
5089 ip6_sprintf(&sin6->sin6_addr),
5090 ntohs(sin6->sin6_port),
5091 sin6->sin6_scope_id);
5092 #endif
5093 #endif
5094 break;
5095 }
5096 #endif
5097 #ifdef INET
5098 case AF_INET:
5099 {
5100 struct sockaddr_in *sin;
5101 unsigned char *p;
5102
5103 sin = (struct sockaddr_in *)sa;
5104 p = (unsigned char *)&sin->sin_addr;
5105 SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n",
5106 p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
5107 break;
5108 }
5109 #endif
5110 #if defined(__Userspace__)
5111 case AF_CONN:
5112 {
5113 struct sockaddr_conn *sconn;
5114
5115 sconn = (struct sockaddr_conn *)sa;
5116 SCTP_PRINTF("AF_CONN address: %p\n", sconn->sconn_addr);
5117 break;
5118 }
5119 #endif
5120 default:
5121 SCTP_PRINTF("?\n");
5122 break;
5123 }
5124 }
5125
5126 void
5127 sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
5128 struct sctp_inpcb *new_inp,
5129 struct sctp_tcb *stcb,
5130 int waitflags)
5131 {
5132 /*
5133 * go through our old INP and pull off any control structures that
5134 * belong to stcb and move then to the new inp.
5135 */
5136 struct socket *old_so, *new_so;
5137 struct sctp_queued_to_read *control, *nctl;
5138 struct sctp_readhead tmp_queue;
5139 struct mbuf *m;
5140 #if defined(__FreeBSD__) || defined(__APPLE__)
5141 int error = 0;
5142 #endif
5143
5144 old_so = old_inp->sctp_socket;
5145 new_so = new_inp->sctp_socket;
5146 TAILQ_INIT(&tmp_queue);
5147 #if defined(__FreeBSD__) || defined(__APPLE__)
5148 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5149 SOCKBUF_LOCK(&(old_so->so_rcv));
5150 #endif
5151 error = sblock(&old_so->so_rcv, waitflags);
5152 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5153 SOCKBUF_UNLOCK(&(old_so->so_rcv));
5154 #endif
5155 if (error) {
5156 /* Gak, can't get sblock, we have a problem.
5157 * data will be left stranded.. and we
5158 * don't dare look at it since the
5159 * other thread may be reading something.
5160 * Oh well, its a screwed up app that does
5161 * a peeloff OR a accept while reading
5162 * from the main socket... actually its
5163 * only the peeloff() case, since I think
5164 * read will fail on a listening socket..
5165 */
5166 return;
5167 }
5168 #endif
5169 /* lock the socket buffers */
5170 SCTP_INP_READ_LOCK(old_inp);
5171 TAILQ_FOREACH_SAFE(control, &old_inp->read_queue, next, nctl) {
5172 /* Pull off all for out target stcb */
5173 if (control->stcb == stcb) {
5174 /* remove it we want it */
5175 TAILQ_REMOVE(&old_inp->read_queue, control, next);
5176 TAILQ_INSERT_TAIL(&tmp_queue, control, next);
5177 m = control->data;
5178 while (m) {
5179 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5180 sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE,SCTP_BUF_LEN(m));
5181 }
5182 sctp_sbfree(control, stcb, &old_so->so_rcv, m);
5183 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5184 sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5185 }
5186 m = SCTP_BUF_NEXT(m);
5187 }
5188 }
5189 }
5190 SCTP_INP_READ_UNLOCK(old_inp);
5191 /* Remove the sb-lock on the old socket */
5192 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5193 SOCKBUF_LOCK(&(old_so->so_rcv));
5194 #endif
5195 #if defined(__APPLE__)
5196 sbunlock(&old_so->so_rcv, 1);
5197 #endif
5198
5199 #if defined(__FreeBSD__)
5200 sbunlock(&old_so->so_rcv);
5201 #endif
5202 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
5203 SOCKBUF_UNLOCK(&(old_so->so_rcv));
5204 #endif
5205 /* Now we move them over to the new socket buffer */
5206 SCTP_INP_READ_LOCK(new_inp);
5207 TAILQ_FOREACH_SAFE(control, &tmp_queue, next, nctl) {
5208 TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next);
5209 m = control->data;
5210 while (m) {
5211 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5212 sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
5213 }
5214 sctp_sballoc(stcb, &new_so->so_rcv, m);
5215 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5216 sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5217 }
5218 m = SCTP_BUF_NEXT(m);
5219 }
5220 }
5221 SCTP_INP_READ_UNLOCK(new_inp);
5222 }
5223
5224 void
5225 sctp_wakeup_the_read_socket(struct sctp_inpcb *inp,
5226 struct sctp_tcb *stcb,
5227 int so_locked
5228 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5229 SCTP_UNUSED
5230 #endif
5231 )
5232 {
5233 if ((inp != NULL) && (inp->sctp_socket != NULL)) {
5234 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5235 struct socket *so;
5236
5237 so = SCTP_INP_SO(inp);
5238 if (!so_locked) {
5239 if (stcb) {
5240 atomic_add_int(&stcb->asoc.refcnt, 1);
5241 SCTP_TCB_UNLOCK(stcb);
5242 }
5243 SCTP_SOCKET_LOCK(so, 1);
5244 if (stcb) {
5245 SCTP_TCB_LOCK(stcb);
5246 atomic_subtract_int(&stcb->asoc.refcnt, 1);
5247 }
5248 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
5249 SCTP_SOCKET_UNLOCK(so, 1);
5250 return;
5251 }
5252 }
5253 #endif
5254 sctp_sorwakeup(inp, inp->sctp_socket);
5255 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5256 if (!so_locked) {
5257 SCTP_SOCKET_UNLOCK(so, 1);
5258 }
5259 #endif
5260 }
5261 }
5262 #if defined(__Userspace__)
5263
5264 void
5265 sctp_invoke_recv_callback(struct sctp_inpcb *inp,
5266 struct sctp_tcb *stcb,
5267 struct sctp_queued_to_read *control,
5268 int inp_read_lock_held)
5269 {
5270 uint32_t pd_point, length;
5271
5272 if ((inp->recv_callback == NULL) ||
5273 (stcb == NULL) ||
5274 (stcb->sctp_socket == NULL)) {
5275 return;
5276 }
5277
5278 length = control->length;
5279 if (stcb != NULL && stcb->sctp_socket != NULL) {
5280 pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
5281 stcb->sctp_ep->partial_delivery_point);
5282 } else {
5283 pd_point = inp->partial_delivery_point;
5284 }
5285 if ((control->end_added == 1) || (length >= pd_point)) {
5286 struct socket *so;
5287 struct mbuf *m;
5288 char *buffer;
5289 struct sctp_rcvinfo rcv;
5290 union sctp_sockstore addr;
5291 int flags;
5292
5293 if ((buffer = malloc(length)) == NULL) {
5294 return;
5295 }
5296 if (inp_read_lock_held == 0) {
5297 SCTP_INP_READ_LOCK(inp);
5298 }
5299 so = stcb->sctp_socket;
5300 for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
5301 sctp_sbfree(control, control->stcb, &so->so_rcv, m);
5302 }
5303 m_copydata(control->data, 0, length, buffer);
5304 memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
5305 rcv.rcv_sid = control->sinfo_stream;
5306 rcv.rcv_ssn = (uint16_t)control->mid;
5307 rcv.rcv_flags = control->sinfo_flags;
5308 rcv.rcv_ppid = control->sinfo_ppid;
5309 rcv.rcv_tsn = control->sinfo_tsn;
5310 rcv.rcv_cumtsn = control->sinfo_cumtsn;
5311 rcv.rcv_context = control->sinfo_context;
5312 rcv.rcv_assoc_id = control->sinfo_assoc_id;
5313 memset(&addr, 0, sizeof(union sctp_sockstore));
5314 switch (control->whoFrom->ro._l_addr.sa.sa_family) {
5315 #ifdef INET
5316 case AF_INET:
5317 addr.sin = control->whoFrom->ro._l_addr.sin;
5318 break;
5319 #endif
5320 #ifdef INET6
5321 case AF_INET6:
5322 addr.sin6 = control->whoFrom->ro._l_addr.sin6;
5323 break;
5324 #endif
5325 case AF_CONN:
5326 addr.sconn = control->whoFrom->ro._l_addr.sconn;
5327 break;
5328 default:
5329 addr.sa = control->whoFrom->ro._l_addr.sa;
5330 break;
5331 }
5332 flags = 0;
5333 if (control->end_added == 1) {
5334 flags |= MSG_EOR;
5335 }
5336 if (control->spec_flags & M_NOTIFICATION) {
5337 flags |= MSG_NOTIFICATION;
5338 }
5339 sctp_m_freem(control->data);
5340 control->data = NULL;
5341 control->tail_mbuf = NULL;
5342 control->length = 0;
5343 if (control->end_added) {
5344 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
5345 control->on_read_q = 0;
5346 sctp_free_remote_addr(control->whoFrom);
5347 control->whoFrom = NULL;
5348 sctp_free_a_readq(stcb, control);
5349 }
5350 atomic_add_int(&stcb->asoc.refcnt, 1);
5351 SCTP_TCB_UNLOCK(stcb);
5352 if (inp_read_lock_held == 0) {
5353 SCTP_INP_READ_UNLOCK(inp);
5354 }
5355 inp->recv_callback(so, addr, buffer, length, rcv, flags, inp->ulp_info);
5356 SCTP_TCB_LOCK(stcb);
5357 atomic_subtract_int(&stcb->asoc.refcnt, 1);
5358 }
5359 }
5360 #endif
5361
5362 void
5363 sctp_add_to_readq(struct sctp_inpcb *inp,
5364 struct sctp_tcb *stcb,
5365 struct sctp_queued_to_read *control,
5366 struct sockbuf *sb,
5367 int end,
5368 int inp_read_lock_held,
5369 int so_locked
5370 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5371 SCTP_UNUSED
5372 #endif
5373 )
5374 {
5375 /*
5376 * Here we must place the control on the end of the socket read
5377 * queue AND increment sb_cc so that select will work properly on
5378 * read.
5379 */
5380 struct mbuf *m, *prev = NULL;
5381
5382 if (inp == NULL) {
5383 /* Gak, TSNH!! */
5384 #ifdef INVARIANTS
5385 panic("Gak, inp NULL on add_to_readq");
5386 #endif
5387 return;
5388 }
5389 #if defined(__APPLE__)
5390 if (so_locked) {
5391 sctp_lock_assert(SCTP_INP_SO(inp));
5392 } else {
5393 sctp_unlock_assert(SCTP_INP_SO(inp));
5394 }
5395 #endif
5396 if (inp_read_lock_held == 0)
5397 SCTP_INP_READ_LOCK(inp);
5398 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) {
5399 if (!control->on_strm_q) {
5400 sctp_free_remote_addr(control->whoFrom);
5401 if (control->data) {
5402 sctp_m_freem(control->data);
5403 control->data = NULL;
5404 }
5405 sctp_free_a_readq(stcb, control);
5406 }
5407 if (inp_read_lock_held == 0)
5408 SCTP_INP_READ_UNLOCK(inp);
5409 return;
5410 }
5411 if (!(control->spec_flags & M_NOTIFICATION)) {
5412 atomic_add_int(&inp->total_recvs, 1);
5413 if (!control->do_not_ref_stcb) {
5414 atomic_add_int(&stcb->total_recvs, 1);
5415 }
5416 }
5417 m = control->data;
5418 control->held_length = 0;
5419 control->length = 0;
5420 while (m) {
5421 if (SCTP_BUF_LEN(m) == 0) {
5422 /* Skip mbufs with NO length */
5423 if (prev == NULL) {
5424 /* First one */
5425 control->data = sctp_m_free(m);
5426 m = control->data;
5427 } else {
5428 SCTP_BUF_NEXT(prev) = sctp_m_free(m);
5429 m = SCTP_BUF_NEXT(prev);
5430 }
5431 if (m == NULL) {
5432 control->tail_mbuf = prev;
5433 }
5434 continue;
5435 }
5436 prev = m;
5437 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5438 sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
5439 }
5440 sctp_sballoc(stcb, sb, m);
5441 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
5442 sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
5443 }
5444 atomic_add_int(&control->length, SCTP_BUF_LEN(m));
5445 m = SCTP_BUF_NEXT(m);
5446 }
5447 if (prev != NULL) {
5448 control->tail_mbuf = prev;
5449 } else {
5450 /* Everything got collapsed out?? */
5451 if (!control->on_strm_q) {
5452 sctp_free_remote_addr(control->whoFrom);
5453 sctp_free_a_readq(stcb, control);
5454 }
5455 if (inp_read_lock_held == 0)
5456 SCTP_INP_READ_UNLOCK(inp);
5457 return;
5458 }
5459 if (end) {
5460 control->end_added = 1;
5461 }
5462 TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
5463 control->on_read_q = 1;
5464 if (inp_read_lock_held == 0)
5465 SCTP_INP_READ_UNLOCK(inp);
5466 #if defined(__Userspace__)
5467 sctp_invoke_recv_callback(inp, stcb, control, inp_read_lock_held);
5468 #endif
5469 if (inp && inp->sctp_socket) {
5470 sctp_wakeup_the_read_socket(inp, stcb, so_locked);
5471 }
5472 }
5473
5474 /*************HOLD THIS COMMENT FOR PATCH FILE OF
5475 *************ALTERNATE ROUTING CODE
5476 */
5477
5478 /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
5479 *************ALTERNATE ROUTING CODE
5480 */
5481
5482 struct mbuf *
5483 sctp_generate_cause(uint16_t code, char *info)
5484 {
5485 struct mbuf *m;
5486 struct sctp_gen_error_cause *cause;
5487 size_t info_len;
5488 uint16_t len;
5489
5490 if ((code == 0) || (info == NULL)) {
5491 return (NULL);
5492 }
5493 info_len = strlen(info);
5494 if (info_len > (SCTP_MAX_CAUSE_LENGTH - sizeof(struct sctp_paramhdr))) {
5495 return (NULL);
5496 }
5497 len = (uint16_t)(sizeof(struct sctp_paramhdr) + info_len);
5498 m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5499 if (m != NULL) {
5500 SCTP_BUF_LEN(m) = len;
5501 cause = mtod(m, struct sctp_gen_error_cause *);
5502 cause->code = htons(code);
5503 cause->length = htons(len);
5504 memcpy(cause->info, info, info_len);
5505 }
5506 return (m);
5507 }
5508
5509 struct mbuf *
5510 sctp_generate_no_user_data_cause(uint32_t tsn)
5511 {
5512 struct mbuf *m;
5513 struct sctp_error_no_user_data *no_user_data_cause;
5514 uint16_t len;
5515
5516 len = (uint16_t)sizeof(struct sctp_error_no_user_data);
5517 m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5518 if (m != NULL) {
5519 SCTP_BUF_LEN(m) = len;
5520 no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
5521 no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
5522 no_user_data_cause->cause.length = htons(len);
5523 no_user_data_cause->tsn = htonl(tsn);
5524 }
5525 return (m);
5526 }
5527
5528 #ifdef SCTP_MBCNT_LOGGING
5529 void
5530 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
5531 struct sctp_tmit_chunk *tp1, int chk_cnt)
5532 {
5533 if (tp1->data == NULL) {
5534 return;
5535 }
5536 asoc->chunks_on_out_queue -= chk_cnt;
5537 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBCNT_LOGGING_ENABLE) {
5538 sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
5539 asoc->total_output_queue_size,
5540 tp1->book_size,
5541 0,
5542 tp1->mbcnt);
5543 }
5544 if (asoc->total_output_queue_size >= tp1->book_size) {
5545 atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size);
5546 } else {
5547 asoc->total_output_queue_size = 0;
5548 }
5549
5550 if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) ||
5551 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) {
5552 if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
5553 stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
5554 } else {
5555 stcb->sctp_socket->so_snd.sb_cc = 0;
5556
5557 }
5558 }
5559 }
5560
5561 #endif
5562
5563 int
5564 sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
5565 uint8_t sent, int so_locked
5566 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
5567 SCTP_UNUSED
5568 #endif
5569 )
5570 {
5571 struct sctp_stream_out *strq;
5572 struct sctp_tmit_chunk *chk = NULL, *tp2;
5573 struct sctp_stream_queue_pending *sp;
5574 uint32_t mid;
5575 uint16_t sid;
5576 uint8_t foundeom = 0;
5577 int ret_sz = 0;
5578 int notdone;
5579 int do_wakeup_routine = 0;
5580
5581 #if defined(__APPLE__)
5582 if (so_locked) {
5583 sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
5584 } else {
5585 sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
5586 }
5587 #endif
5588 sid = tp1->rec.data.sid;
5589 mid = tp1->rec.data.mid;
5590 if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
5591 stcb->asoc.abandoned_sent[0]++;
5592 stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
5593 stcb->asoc.strmout[sid].abandoned_sent[0]++;
5594 #if defined(SCTP_DETAILED_STR_STATS)
5595 stcb->asoc.strmout[sid].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
5596 #endif
5597 } else {
5598 stcb->asoc.abandoned_unsent[0]++;
5599 stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
5600 stcb->asoc.strmout[sid].abandoned_unsent[0]++;
5601 #if defined(SCTP_DETAILED_STR_STATS)
5602 stcb->asoc.strmout[sid].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
5603 #endif
5604 }
5605 do {
5606 ret_sz += tp1->book_size;
5607 if (tp1->data != NULL) {
5608 if (tp1->sent < SCTP_DATAGRAM_RESEND) {
5609 sctp_flight_size_decrease(tp1);
5610 sctp_total_flight_decrease(stcb, tp1);
5611 }
5612 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
5613 stcb->asoc.peers_rwnd += tp1->send_size;
5614 stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
5615 if (sent) {
5616 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
5617 } else {
5618 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
5619 }
5620 if (tp1->data) {
5621 sctp_m_freem(tp1->data);
5622 tp1->data = NULL;
5623 }
5624 do_wakeup_routine = 1;
5625 if (PR_SCTP_BUF_ENABLED(tp1->flags)) {
5626 stcb->asoc.sent_queue_cnt_removeable--;
5627 }
5628 }
5629 tp1->sent = SCTP_FORWARD_TSN_SKIP;
5630 if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
5631 SCTP_DATA_NOT_FRAG) {
5632 /* not frag'ed we ae done */
5633 notdone = 0;
5634 foundeom = 1;
5635 } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
5636 /* end of frag, we are done */
5637 notdone = 0;
5638 foundeom = 1;
5639 } else {
5640 /*
5641 * Its a begin or middle piece, we must mark all of
5642 * it
5643 */
5644 notdone = 1;
5645 tp1 = TAILQ_NEXT(tp1, sctp_next);
5646 }
5647 } while (tp1 && notdone);
5648 if (foundeom == 0) {
5649 /*
5650 * The multi-part message was scattered across the send and
5651 * sent queue.
5652 */
5653 TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
5654 if ((tp1->rec.data.sid != sid) ||
5655 (!SCTP_MID_EQ(stcb->asoc.idata_supported, tp1->rec.data.mid, mid))) {
5656 break;
5657 }
5658 /* save to chk in case we have some on stream out
5659 * queue. If so and we have an un-transmitted one
5660 * we don't have to fudge the TSN.
5661 */
5662 chk = tp1;
5663 ret_sz += tp1->book_size;
5664 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
5665 if (sent) {
5666 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
5667 } else {
5668 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
5669 }
5670 if (tp1->data) {
5671 sctp_m_freem(tp1->data);
5672 tp1->data = NULL;
5673 }
5674 /* No flight involved here book the size to 0 */
5675 tp1->book_size = 0;
5676 if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
5677 foundeom = 1;
5678 }
5679 do_wakeup_routine = 1;
5680 tp1->sent = SCTP_FORWARD_TSN_SKIP;
5681 TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
5682 /* on to the sent queue so we can wait for it to be passed by. */
5683 TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
5684 sctp_next);
5685 stcb->asoc.send_queue_cnt--;
5686 stcb->asoc.sent_queue_cnt++;
5687 }
5688 }
5689 if (foundeom == 0) {
5690 /*
5691 * Still no eom found. That means there
5692 * is stuff left on the stream out queue.. yuck.
5693 */
5694 SCTP_TCB_SEND_LOCK(stcb);
5695 strq = &stcb->asoc.strmout[sid];
5696 sp = TAILQ_FIRST(&strq->outqueue);
5697 if (sp != NULL) {
5698 sp->discard_rest = 1;
5699 /*
5700 * We may need to put a chunk on the
5701 * queue that holds the TSN that
5702 * would have been sent with the LAST
5703 * bit.
5704 */
5705 if (chk == NULL) {
5706 /* Yep, we have to */
5707 sctp_alloc_a_chunk(stcb, chk);
5708 if (chk == NULL) {
5709 /* we are hosed. All we can
5710 * do is nothing.. which will
5711 * cause an abort if the peer is
5712 * paying attention.
5713 */
5714 goto oh_well;
5715 }
5716 memset(chk, 0, sizeof(*chk));
5717 chk->rec.data.rcv_flags = 0;
5718 chk->sent = SCTP_FORWARD_TSN_SKIP;
5719 chk->asoc = &stcb->asoc;
5720 if (stcb->asoc.idata_supported == 0) {
5721 if (sp->sinfo_flags & SCTP_UNORDERED) {
5722 chk->rec.data.mid = 0;
5723 } else {
5724 chk->rec.data.mid = strq->next_mid_ordered;
5725 }
5726 } else {
5727 if (sp->sinfo_flags & SCTP_UNORDERED) {
5728 chk->rec.data.mid = strq->next_mid_unordered;
5729 } else {
5730 chk->rec.data.mid = strq->next_mid_ordered;
5731 }
5732 }
5733 chk->rec.data.sid = sp->sid;
5734 chk->rec.data.ppid = sp->ppid;
5735 chk->rec.data.context = sp->context;
5736 chk->flags = sp->act_flags;
5737 chk->whoTo = NULL;
5738 #if defined(__FreeBSD__) || defined(__Panda__)
5739 chk->rec.data.tsn = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
5740 #else
5741 chk->rec.data.tsn = stcb->asoc.sending_seq++;
5742 #endif
5743 strq->chunks_on_queues++;
5744 TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
5745 stcb->asoc.sent_queue_cnt++;
5746 stcb->asoc.pr_sctp_cnt++;
5747 }
5748 chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
5749 if (sp->sinfo_flags & SCTP_UNORDERED) {
5750 chk->rec.data.rcv_flags |= SCTP_DATA_UNORDERED;
5751 }
5752 if (stcb->asoc.idata_supported == 0) {
5753 if ((sp->sinfo_flags & SCTP_UNORDERED) == 0) {
5754 strq->next_mid_ordered++;
5755 }
5756 } else {
5757 if (sp->sinfo_flags & SCTP_UNORDERED) {
5758 strq->next_mid_unordered++;
5759 } else {
5760 strq->next_mid_ordered++;
5761 }
5762 }
5763 oh_well:
5764 if (sp->data) {
5765 /* Pull any data to free up the SB and
5766 * allow sender to "add more" while we
5767 * will throw away :-)
5768 */
5769 sctp_free_spbufspace(stcb, &stcb->asoc, sp);
5770 ret_sz += sp->length;
5771 do_wakeup_routine = 1;
5772 sp->some_taken = 1;
5773 sctp_m_freem(sp->data);
5774 sp->data = NULL;
5775 sp->tail_mbuf = NULL;
5776 sp->length = 0;
5777 }
5778 }
5779 SCTP_TCB_SEND_UNLOCK(stcb);
5780 }
5781 if (do_wakeup_routine) {
5782 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5783 struct socket *so;
5784
5785 so = SCTP_INP_SO(stcb->sctp_ep);
5786 if (!so_locked) {
5787 atomic_add_int(&stcb->asoc.refcnt, 1);
5788 SCTP_TCB_UNLOCK(stcb);
5789 SCTP_SOCKET_LOCK(so, 1);
5790 SCTP_TCB_LOCK(stcb);
5791 atomic_subtract_int(&stcb->asoc.refcnt, 1);
5792 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
5793 /* assoc was freed while we were unlocked */
5794 SCTP_SOCKET_UNLOCK(so, 1);
5795 return (ret_sz);
5796 }
5797 }
5798 #endif
5799 sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
5800 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
5801 if (!so_locked) {
5802 SCTP_SOCKET_UNLOCK(so, 1);
5803 }
5804 #endif
5805 }
5806 return (ret_sz);
5807 }
5808
5809 /*
5810 * checks to see if the given address, sa, is one that is currently known by
5811 * the kernel note: can't distinguish the same address on multiple interfaces
5812 * and doesn't handle multiple addresses with different zone/scope id's note:
5813 * ifa_ifwithaddr() compares the entire sockaddr struct
5814 */
5815 struct sctp_ifa *
5816 sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
5817 int holds_lock)
5818 {
5819 struct sctp_laddr *laddr;
5820
5821 if (holds_lock == 0) {
5822 SCTP_INP_RLOCK(inp);
5823 }
5824
5825 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
5826 if (laddr->ifa == NULL)
5827 continue;
5828 if (addr->sa_family != laddr->ifa->address.sa.sa_family)
5829 continue;
5830 #ifdef INET
5831 if (addr->sa_family == AF_INET) {
5832 if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
5833 laddr->ifa->address.sin.sin_addr.s_addr) {
5834 /* found him. */
5835 if (holds_lock == 0) {
5836 SCTP_INP_RUNLOCK(inp);
5837 }
5838 return (laddr->ifa);
5839 break;
5840 }
5841 }
5842 #endif
5843 #ifdef INET6
5844 if (addr->sa_family == AF_INET6) {
5845 if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
5846 &laddr->ifa->address.sin6)) {
5847 /* found him. */
5848 if (holds_lock == 0) {
5849 SCTP_INP_RUNLOCK(inp);
5850 }
5851 return (laddr->ifa);
5852 break;
5853 }
5854 }
5855 #endif
5856 #if defined(__Userspace__)
5857 if (addr->sa_family == AF_CONN) {
5858 if (((struct sockaddr_conn *)addr)->sconn_addr == laddr->ifa->address.sconn.sconn_addr) {
5859 /* found him. */
5860 if (holds_lock == 0) {
5861 SCTP_INP_RUNLOCK(inp);
5862 }
5863 return (laddr->ifa);
5864 break;
5865 }
5866 }
5867 #endif
5868 }
5869 if (holds_lock == 0) {
5870 SCTP_INP_RUNLOCK(inp);
5871 }
5872 return (NULL);
5873 }
5874
5875 uint32_t
5876 sctp_get_ifa_hash_val(struct sockaddr *addr)
5877 {
5878 switch (addr->sa_family) {
5879 #ifdef INET
5880 case AF_INET:
5881 {
5882 struct sockaddr_in *sin;
5883
5884 sin = (struct sockaddr_in *)addr;
5885 return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16));
5886 }
5887 #endif
5888 #ifdef INET6
5889 case AF_INET6:
5890 {
5891 struct sockaddr_in6 *sin6;
5892 uint32_t hash_of_addr;
5893
5894 sin6 = (struct sockaddr_in6 *)addr;
5895 #if !defined(__Windows__) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_Windows)
5896 hash_of_addr = (sin6->sin6_addr.s6_addr32[0] +
5897 sin6->sin6_addr.s6_addr32[1] +
5898 sin6->sin6_addr.s6_addr32[2] +
5899 sin6->sin6_addr.s6_addr32[3]);
5900 #else
5901 hash_of_addr = (((uint32_t *)&sin6->sin6_addr)[0] +
5902 ((uint32_t *)&sin6->sin6_addr)[1] +
5903 ((uint32_t *)&sin6->sin6_addr)[2] +
5904 ((uint32_t *)&sin6->sin6_addr)[3]);
5905 #endif
5906 hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16));
5907 return (hash_of_addr);
5908 }
5909 #endif
5910 #if defined(__Userspace__)
5911 case AF_CONN:
5912 {
5913 struct sockaddr_conn *sconn;
5914 uintptr_t temp;
5915
5916 sconn = (struct sockaddr_conn *)addr;
5917 temp = (uintptr_t)sconn->sconn_addr;
5918 return ((uint32_t)(temp ^ (temp >> 16)));
5919 }
5920 #endif
5921 default:
5922 break;
5923 }
5924 return (0);
5925 }
5926
5927 struct sctp_ifa *
5928 sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
5929 {
5930 struct sctp_ifa *sctp_ifap;
5931 struct sctp_vrf *vrf;
5932 struct sctp_ifalist *hash_head;
5933 uint32_t hash_of_addr;
5934
5935 if (holds_lock == 0)
5936 SCTP_IPI_ADDR_RLOCK();
5937
5938 vrf = sctp_find_vrf(vrf_id);
5939 if (vrf == NULL) {
5940 if (holds_lock == 0)
5941 SCTP_IPI_ADDR_RUNLOCK();
5942 return (NULL);
5943 }
5944
5945 hash_of_addr = sctp_get_ifa_hash_val(addr);
5946
5947 hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
5948 if (hash_head == NULL) {
5949 SCTP_PRINTF("hash_of_addr:%x mask:%x table:%x - ",
5950 hash_of_addr, (uint32_t)vrf->vrf_addr_hashmark,
5951 (uint32_t)(hash_of_addr & vrf->vrf_addr_hashmark));
5952 sctp_print_address(addr);
5953 SCTP_PRINTF("No such bucket for address\n");
5954 if (holds_lock == 0)
5955 SCTP_IPI_ADDR_RUNLOCK();
5956
5957 return (NULL);
5958 }
5959 LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
5960 if (addr->sa_family != sctp_ifap->address.sa.sa_family)
5961 continue;
5962 #ifdef INET
5963 if (addr->sa_family == AF_INET) {
5964 if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
5965 sctp_ifap->address.sin.sin_addr.s_addr) {
5966 /* found him. */
5967 if (holds_lock == 0)
5968 SCTP_IPI_ADDR_RUNLOCK();
5969 return (sctp_ifap);
5970 break;
5971 }
5972 }
5973 #endif
5974 #ifdef INET6
5975 if (addr->sa_family == AF_INET6) {
5976 if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
5977 &sctp_ifap->address.sin6)) {
5978 /* found him. */
5979 if (holds_lock == 0)
5980 SCTP_IPI_ADDR_RUNLOCK();
5981 return (sctp_ifap);
5982 break;
5983 }
5984 }
5985 #endif
5986 #if defined(__Userspace__)
5987 if (addr->sa_family == AF_CONN) {
5988 if (((struct sockaddr_conn *)addr)->sconn_addr == sctp_ifap->address.sconn.sconn_addr) {
5989 /* found him. */
5990 if (holds_lock == 0)
5991 SCTP_IPI_ADDR_RUNLOCK();
5992 return (sctp_ifap);
5993 break;
5994 }
5995 }
5996 #endif
5997 }
5998 if (holds_lock == 0)
5999 SCTP_IPI_ADDR_RUNLOCK();
6000 return (NULL);
6001 }
6002
6003 static void
6004 sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock,
6005 uint32_t rwnd_req)
6006 {
6007 /* User pulled some data, do we need a rwnd update? */
6008 #if defined(__FreeBSD__)
6009 struct epoch_tracker et;
6010 #endif
6011 int r_unlocked = 0;
6012 uint32_t dif, rwnd;
6013 struct socket *so = NULL;
6014
6015 if (stcb == NULL)
6016 return;
6017
6018 atomic_add_int(&stcb->asoc.refcnt, 1);
6019
6020 if ((SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
6021 (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED | SCTP_STATE_SHUTDOWN_RECEIVED))) {
6022 /* Pre-check If we are freeing no update */
6023 goto no_lock;
6024 }
6025 SCTP_INP_INCR_REF(stcb->sctp_ep);
6026 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6027 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
6028 goto out;
6029 }
6030 so = stcb->sctp_socket;
6031 if (so == NULL) {
6032 goto out;
6033 }
6034 atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far);
6035 /* Have you have freed enough to look */
6036 *freed_so_far = 0;
6037 /* Yep, its worth a look and the lock overhead */
6038
6039 /* Figure out what the rwnd would be */
6040 rwnd = sctp_calc_rwnd(stcb, &stcb->asoc);
6041 if (rwnd >= stcb->asoc.my_last_reported_rwnd) {
6042 dif = rwnd - stcb->asoc.my_last_reported_rwnd;
6043 } else {
6044 dif = 0;
6045 }
6046 if (dif >= rwnd_req) {
6047 if (hold_rlock) {
6048 SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
6049 r_unlocked = 1;
6050 }
6051 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6052 /*
6053 * One last check before we allow the guy possibly
6054 * to get in. There is a race, where the guy has not
6055 * reached the gate. In that case
6056 */
6057 goto out;
6058 }
6059 SCTP_TCB_LOCK(stcb);
6060 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6061 /* No reports here */
6062 SCTP_TCB_UNLOCK(stcb);
6063 goto out;
6064 }
6065 SCTP_STAT_INCR(sctps_wu_sacks_sent);
6066 #if defined(__FreeBSD__)
6067 NET_EPOCH_ENTER(et);
6068 #endif
6069 sctp_send_sack(stcb, SCTP_SO_LOCKED);
6070
6071 sctp_chunk_output(stcb->sctp_ep, stcb,
6072 SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
6073 /* make sure no timer is running */
6074 #if defined(__FreeBSD__)
6075 NET_EPOCH_EXIT(et);
6076 #endif
6077 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
6078 SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
6079 SCTP_TCB_UNLOCK(stcb);
6080 } else {
6081 /* Update how much we have pending */
6082 stcb->freed_by_sorcv_sincelast = dif;
6083 }
6084 out:
6085 if (so && r_unlocked && hold_rlock) {
6086 SCTP_INP_READ_LOCK(stcb->sctp_ep);
6087 }
6088
6089 SCTP_INP_DECR_REF(stcb->sctp_ep);
6090 no_lock:
6091 atomic_add_int(&stcb->asoc.refcnt, -1);
6092 return;
6093 }
6094
6095 int
6096 sctp_sorecvmsg(struct socket *so,
6097 struct uio *uio,
6098 struct mbuf **mp,
6099 struct sockaddr *from,
6100 int fromlen,
6101 int *msg_flags,
6102 struct sctp_sndrcvinfo *sinfo,
6103 int filling_sinfo)
6104 {
6105 /*
6106 * MSG flags we will look at MSG_DONTWAIT - non-blocking IO.
6107 * MSG_PEEK - Look don't touch :-D (only valid with OUT mbuf copy
6108 * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ??
6109 * On the way out we may send out any combination of:
6110 * MSG_NOTIFICATION MSG_EOR
6111 *
6112 */
6113 struct sctp_inpcb *inp = NULL;
6114 ssize_t my_len = 0;
6115 ssize_t cp_len = 0;
6116 int error = 0;
6117 struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL;
6118 struct mbuf *m = NULL;
6119 struct sctp_tcb *stcb = NULL;
6120 int wakeup_read_socket = 0;
6121 int freecnt_applied = 0;
6122 int out_flags = 0, in_flags = 0;
6123 int block_allowed = 1;
6124 uint32_t freed_so_far = 0;
6125 ssize_t copied_so_far = 0;
6126 int in_eeor_mode = 0;
6127 int no_rcv_needed = 0;
6128 uint32_t rwnd_req = 0;
6129 int hold_sblock = 0;
6130 int hold_rlock = 0;
6131 ssize_t slen = 0;
6132 uint32_t held_length = 0;
6133 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
6134 int sockbuf_lock = 0;
6135 #endif
6136
6137 if (uio == NULL) {
6138 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6139 return (EINVAL);
6140 }
6141
6142 if (msg_flags) {
6143 in_flags = *msg_flags;
6144 if (in_flags & MSG_PEEK)
6145 SCTP_STAT_INCR(sctps_read_peeks);
6146 } else {
6147 in_flags = 0;
6148 }
6149 #if defined(__APPLE__)
6150 #if defined(APPLE_LEOPARD)
6151 slen = uio->uio_resid;
6152 #else
6153 slen = uio_resid(uio);
6154 #endif
6155 #else
6156 slen = uio->uio_resid;
6157 #endif
6158
6159 /* Pull in and set up our int flags */
6160 if (in_flags & MSG_OOB) {
6161 /* Out of band's NOT supported */
6162 return (EOPNOTSUPP);
6163 }
6164 if ((in_flags & MSG_PEEK) && (mp != NULL)) {
6165 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6166 return (EINVAL);
6167 }
6168 if ((in_flags & (MSG_DONTWAIT
6169 #if defined(__FreeBSD__) && __FreeBSD_version > 500000
6170 | MSG_NBIO
6171 #endif
6172 )) ||
6173 SCTP_SO_IS_NBIO(so)) {
6174 block_allowed = 0;
6175 }
6176 /* setup the endpoint */
6177 inp = (struct sctp_inpcb *)so->so_pcb;
6178 if (inp == NULL) {
6179 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
6180 return (EFAULT);
6181 }
6182 rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
6183 /* Must be at least a MTU's worth */
6184 if (rwnd_req < SCTP_MIN_RWND)
6185 rwnd_req = SCTP_MIN_RWND;
6186 in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
6187 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) {
6188 #if defined(__APPLE__)
6189 #if defined(APPLE_LEOPARD)
6190 sctp_misc_ints(SCTP_SORECV_ENTER,
6191 rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid);
6192 #else
6193 sctp_misc_ints(SCTP_SORECV_ENTER,
6194 rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio_resid(uio));
6195 #endif
6196 #else
6197 sctp_misc_ints(SCTP_SORECV_ENTER,
6198 rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid);
6199 #endif
6200 }
6201 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
6202 SOCKBUF_LOCK(&so->so_rcv);
6203 hold_sblock = 1;
6204 #endif
6205 if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
6206 #if defined(__APPLE__)
6207 #if defined(APPLE_LEOPARD)
6208 sctp_misc_ints(SCTP_SORECV_ENTERPL,
6209 rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid);
6210 #else
6211 sctp_misc_ints(SCTP_SORECV_ENTERPL,
6212 rwnd_req, block_allowed, so->so_rcv.sb_cc, uio_resid(uio));
6213 #endif
6214 #else
6215 sctp_misc_ints(SCTP_SORECV_ENTERPL,
6216 rwnd_req, block_allowed, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid);
6217 #endif
6218 }
6219
6220 #if defined(__APPLE__)
6221 error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6222 #endif
6223
6224 #if defined(__FreeBSD__)
6225 error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0));
6226 #endif
6227 if (error) {
6228 goto release_unlocked;
6229 }
6230 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
6231 sockbuf_lock = 1;
6232 #endif
6233 restart:
6234 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
6235 if (hold_sblock == 0) {
6236 SOCKBUF_LOCK(&so->so_rcv);
6237 hold_sblock = 1;
6238 }
6239 #endif
6240 #if defined(__APPLE__)
6241 sbunlock(&so->so_rcv, 1);
6242 #endif
6243
6244 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
6245 sbunlock(&so->so_rcv);
6246 #endif
6247
6248 restart_nosblocks:
6249 if (hold_sblock == 0) {
6250 SOCKBUF_LOCK(&so->so_rcv);
6251 hold_sblock = 1;
6252 }
6253 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6254 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
6255 goto out;
6256 }
6257 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
6258 if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) {
6259 #else
6260 if ((so->so_state & SS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) {
6261 #endif
6262 if (so->so_error) {
6263 error = so->so_error;
6264 if ((in_flags & MSG_PEEK) == 0)
6265 so->so_error = 0;
6266 goto out;
6267 } else {
6268 if (so->so_rcv.sb_cc == 0) {
6269 /* indicate EOF */
6270 error = 0;
6271 goto out;
6272 }
6273 }
6274 }
6275 if (so->so_rcv.sb_cc <= held_length) {
6276 if (so->so_error) {
6277 error = so->so_error;
6278 if ((in_flags & MSG_PEEK) == 0) {
6279 so->so_error = 0;
6280 }
6281 goto out;
6282 }
6283 if ((so->so_rcv.sb_cc == 0) &&
6284 ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
6285 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
6286 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) {
6287 /* For active open side clear flags for re-use
6288 * passive open is blocked by connect.
6289 */
6290 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) {
6291 /* You were aborted, passive side always hits here */
6292 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
6293 error = ECONNRESET;
6294 }
6295 so->so_state &= ~(SS_ISCONNECTING |
6296 SS_ISDISCONNECTING |
6297 SS_ISCONFIRMING |
6298 SS_ISCONNECTED);
6299 if (error == 0) {
6300 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
6301 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
6302 error = ENOTCONN;
6303 }
6304 }
6305 goto out;
6306 }
6307 }
6308 if (block_allowed) {
6309 error = sbwait(&so->so_rcv);
6310 if (error) {
6311 goto out;
6312 }
6313 held_length = 0;
6314 goto restart_nosblocks;
6315 } else {
6316 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK);
6317 error = EWOULDBLOCK;
6318 goto out;
6319 }
6320 }
6321 if (hold_sblock == 1) {
6322 SOCKBUF_UNLOCK(&so->so_rcv);
6323 hold_sblock = 0;
6324 }
6325 #if defined(__APPLE__)
6326 error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6327 #endif
6328 #if defined(__FreeBSD__) && __FreeBSD_version < 700000
6329 error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0));
6330 #endif
6331 /* we possibly have data we can read */
6332 /*sa_ignore FREED_MEMORY*/
6333 control = TAILQ_FIRST(&inp->read_queue);
6334 if (control == NULL) {
6335 /* This could be happening since
6336 * the appender did the increment but as not
6337 * yet did the tailq insert onto the read_queue
6338 */
6339 if (hold_rlock == 0) {
6340 SCTP_INP_READ_LOCK(inp);
6341 }
6342 control = TAILQ_FIRST(&inp->read_queue);
6343 if ((control == NULL) && (so->so_rcv.sb_cc != 0)) {
6344 #ifdef INVARIANTS
6345 panic("Huh, its non zero and nothing on control?");
6346 #endif
6347 so->so_rcv.sb_cc = 0;
6348 }
6349 SCTP_INP_READ_UNLOCK(inp);
6350 hold_rlock = 0;
6351 goto restart;
6352 }
6353
6354 if ((control->length == 0) &&
6355 (control->do_not_ref_stcb)) {
6356 /* Clean up code for freeing assoc that left behind a pdapi..
6357 * maybe a peer in EEOR that just closed after sending and
6358 * never indicated a EOR.
6359 */
6360 if (hold_rlock == 0) {
6361 hold_rlock = 1;
6362 SCTP_INP_READ_LOCK(inp);
6363 }
6364 control->held_length = 0;
6365 if (control->data) {
6366 /* Hmm there is data here .. fix */
6367 struct mbuf *m_tmp;
6368 int cnt = 0;
6369 m_tmp = control->data;
6370 while (m_tmp) {
6371 cnt += SCTP_BUF_LEN(m_tmp);
6372 if (SCTP_BUF_NEXT(m_tmp) == NULL) {
6373 control->tail_mbuf = m_tmp;
6374 control->end_added = 1;
6375 }
6376 m_tmp = SCTP_BUF_NEXT(m_tmp);
6377 }
6378 control->length = cnt;
6379 } else {
6380 /* remove it */
6381 TAILQ_REMOVE(&inp->read_queue, control, next);
6382 /* Add back any hiddend data */
6383 sctp_free_remote_addr(control->whoFrom);
6384 sctp_free_a_readq(stcb, control);
6385 }
6386 if (hold_rlock) {
6387 hold_rlock = 0;
6388 SCTP_INP_READ_UNLOCK(inp);
6389 }
6390 goto restart;
6391 }
6392 if ((control->length == 0) &&
6393 (control->end_added == 1)) {
6394 /* Do we also need to check for (control->pdapi_aborted == 1)? */
6395 if (hold_rlock == 0) {
6396 hold_rlock = 1;
6397 SCTP_INP_READ_LOCK(inp);
6398 }
6399 TAILQ_REMOVE(&inp->read_queue, control, next);
6400 if (control->data) {
6401 #ifdef INVARIANTS
6402 panic("control->data not null but control->length == 0");
6403 #else
6404 SCTP_PRINTF("Strange, data left in the control buffer. Cleaning up.\n");
6405 sctp_m_freem(control->data);
6406 control->data = NULL;
6407 #endif
6408 }
6409 if (control->aux_data) {
6410 sctp_m_free (control->aux_data);
6411 control->aux_data = NULL;
6412 }
6413 #ifdef INVARIANTS
6414 if (control->on_strm_q) {
6415 panic("About to free ctl:%p so:%p and its in %d",
6416 control, so, control->on_strm_q);
6417 }
6418 #endif
6419 sctp_free_remote_addr(control->whoFrom);
6420 sctp_free_a_readq(stcb, control);
6421 if (hold_rlock) {
6422 hold_rlock = 0;
6423 SCTP_INP_READ_UNLOCK(inp);
6424 }
6425 goto restart;
6426 }
6427 if (control->length == 0) {
6428 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) &&
6429 (filling_sinfo)) {
6430 /* find a more suitable one then this */
6431 ctl = TAILQ_NEXT(control, next);
6432 while (ctl) {
6433 if ((ctl->stcb != control->stcb) && (ctl->length) &&
6434 (ctl->some_taken ||
6435 (ctl->spec_flags & M_NOTIFICATION) ||
6436 ((ctl->do_not_ref_stcb == 0) &&
6437 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
6438 ) {
6439 /*-
6440 * If we have a different TCB next, and there is data
6441 * present. If we have already taken some (pdapi), OR we can
6442 * ref the tcb and no delivery as started on this stream, we
6443 * take it. Note we allow a notification on a different
6444 * assoc to be delivered..
6445 */
6446 control = ctl;
6447 goto found_one;
6448 } else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) &&
6449 (ctl->length) &&
6450 ((ctl->some_taken) ||
6451 ((ctl->do_not_ref_stcb == 0) &&
6452 ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
6453 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) {
6454 /*-
6455 * If we have the same tcb, and there is data present, and we
6456 * have the strm interleave feature present. Then if we have
6457 * taken some (pdapi) or we can refer to tht tcb AND we have
6458 * not started a delivery for this stream, we can take it.
6459 * Note we do NOT allow a notificaiton on the same assoc to
6460 * be delivered.
6461 */
6462 control = ctl;
6463 goto found_one;
6464 }
6465 ctl = TAILQ_NEXT(ctl, next);
6466 }
6467 }
6468 /*
6469 * if we reach here, not suitable replacement is available
6470 * <or> fragment interleave is NOT on. So stuff the sb_cc
6471 * into the our held count, and its time to sleep again.
6472 */
6473 held_length = so->so_rcv.sb_cc;
6474 control->held_length = so->so_rcv.sb_cc;
6475 goto restart;
6476 }
6477 /* Clear the held length since there is something to read */
6478 control->held_length = 0;
6479 found_one:
6480 /*
6481 * If we reach here, control has a some data for us to read off.
6482 * Note that stcb COULD be NULL.
6483 */
6484 if (hold_rlock == 0) {
6485 hold_rlock = 1;
6486 SCTP_INP_READ_LOCK(inp);
6487 }
6488 control->some_taken++;
6489 stcb = control->stcb;
6490 if (stcb) {
6491 if ((control->do_not_ref_stcb == 0) &&
6492 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
6493 if (freecnt_applied == 0)
6494 stcb = NULL;
6495 } else if (control->do_not_ref_stcb == 0) {
6496 /* you can't free it on me please */
6497 /*
6498 * The lock on the socket buffer protects us so the
6499 * free code will stop. But since we used the socketbuf
6500 * lock and the sender uses the tcb_lock to increment,
6501 * we need to use the atomic add to the refcnt
6502 */
6503 if (freecnt_applied) {
6504 #ifdef INVARIANTS
6505 panic("refcnt already incremented");
6506 #else
6507 SCTP_PRINTF("refcnt already incremented?\n");
6508 #endif
6509 } else {
6510 atomic_add_int(&stcb->asoc.refcnt, 1);
6511 freecnt_applied = 1;
6512 }
6513 /*
6514 * Setup to remember how much we have not yet told
6515 * the peer our rwnd has opened up. Note we grab
6516 * the value from the tcb from last time.
6517 * Note too that sack sending clears this when a sack
6518 * is sent, which is fine. Once we hit the rwnd_req,
6519 * we then will go to the sctp_user_rcvd() that will
6520 * not lock until it KNOWs it MUST send a WUP-SACK.
6521 */
6522 freed_so_far = (uint32_t)stcb->freed_by_sorcv_sincelast;
6523 stcb->freed_by_sorcv_sincelast = 0;
6524 }
6525 }
6526 if (stcb &&
6527 ((control->spec_flags & M_NOTIFICATION) == 0) &&
6528 control->do_not_ref_stcb == 0) {
6529 stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
6530 }
6531
6532 /* First lets get off the sinfo and sockaddr info */
6533 if ((sinfo != NULL) && (filling_sinfo != 0)) {
6534 sinfo->sinfo_stream = control->sinfo_stream;
6535 sinfo->sinfo_ssn = (uint16_t)control->mid;
6536 sinfo->sinfo_flags = control->sinfo_flags;
6537 sinfo->sinfo_ppid = control->sinfo_ppid;
6538 sinfo->sinfo_context =control->sinfo_context;
6539 sinfo->sinfo_timetolive = control->sinfo_timetolive;
6540 sinfo->sinfo_tsn = control->sinfo_tsn;
6541 sinfo->sinfo_cumtsn = control->sinfo_cumtsn;
6542 sinfo->sinfo_assoc_id = control->sinfo_assoc_id;
6543 nxt = TAILQ_NEXT(control, next);
6544 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
6545 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) {
6546 struct sctp_extrcvinfo *s_extra;
6547 s_extra = (struct sctp_extrcvinfo *)sinfo;
6548 if ((nxt) &&
6549 (nxt->length)) {
6550 s_extra->serinfo_next_flags = SCTP_NEXT_MSG_AVAIL;
6551 if (nxt->sinfo_flags & SCTP_UNORDERED) {
6552 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED;
6553 }
6554 if (nxt->spec_flags & M_NOTIFICATION) {
6555 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION;
6556 }
6557 s_extra->serinfo_next_aid = nxt->sinfo_assoc_id;
6558 s_extra->serinfo_next_length = nxt->length;
6559 s_extra->serinfo_next_ppid = nxt->sinfo_ppid;
6560 s_extra->serinfo_next_stream = nxt->sinfo_stream;
6561 if (nxt->tail_mbuf != NULL) {
6562 if (nxt->end_added) {
6563 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE;
6564 }
6565 }
6566 } else {
6567 /* we explicitly 0 this, since the memcpy got
6568 * some other things beyond the older sinfo_
6569 * that is on the control's structure :-D
6570 */
6571 nxt = NULL;
6572 s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
6573 s_extra->serinfo_next_aid = 0;
6574 s_extra->serinfo_next_length = 0;
6575 s_extra->serinfo_next_ppid = 0;
6576 s_extra->serinfo_next_stream = 0;
6577 }
6578 }
6579 /*
6580 * update off the real current cum-ack, if we have an stcb.
6581 */
6582 if ((control->do_not_ref_stcb == 0) && stcb)
6583 sinfo->sinfo_cumtsn = stcb->asoc.cumulative_tsn;
6584 /*
6585 * mask off the high bits, we keep the actual chunk bits in
6586 * there.
6587 */
6588 sinfo->sinfo_flags &= 0x00ff;
6589 if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) {
6590 sinfo->sinfo_flags |= SCTP_UNORDERED;
6591 }
6592 }
6593 #ifdef SCTP_ASOCLOG_OF_TSNS
6594 {
6595 int index, newindex;
6596 struct sctp_pcbtsn_rlog *entry;
6597 do {
6598 index = inp->readlog_index;
6599 newindex = index + 1;
6600 if (newindex >= SCTP_READ_LOG_SIZE) {
6601 newindex = 0;
6602 }
6603 } while (atomic_cmpset_int(&inp->readlog_index, index, newindex) == 0);
6604 entry = &inp->readlog[index];
6605 entry->vtag = control->sinfo_assoc_id;
6606 entry->strm = control->sinfo_stream;
6607 entry->seq = (uint16_t)control->mid;
6608 entry->sz = control->length;
6609 entry->flgs = control->sinfo_flags;
6610 }
6611 #endif
6612 if ((fromlen > 0) && (from != NULL)) {
6613 union sctp_sockstore store;
6614 size_t len;
6615
6616 switch (control->whoFrom->ro._l_addr.sa.sa_family) {
6617 #ifdef INET6
6618 case AF_INET6:
6619 len = sizeof(struct sockaddr_in6);
6620 store.sin6 = control->whoFrom->ro._l_addr.sin6;
6621 store.sin6.sin6_port = control->port_from;
6622 break;
6623 #endif
6624 #ifdef INET
6625 case AF_INET:
6626 #ifdef INET6
6627 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
6628 len = sizeof(struct sockaddr_in6);
6629 in6_sin_2_v4mapsin6(&control->whoFrom->ro._l_addr.sin,
6630 &store.sin6);
6631 store.sin6.sin6_port = control->port_from;
6632 } else {
6633 len = sizeof(struct sockaddr_in);
6634 store.sin = control->whoFrom->ro._l_addr.sin;
6635 store.sin.sin_port = control->port_from;
6636 }
6637 #else
6638 len = sizeof(struct sockaddr_in);
6639 store.sin = control->whoFrom->ro._l_addr.sin;
6640 store.sin.sin_port = control->port_from;
6641 #endif
6642 break;
6643 #endif
6644 #if defined(__Userspace__)
6645 case AF_CONN:
6646 len = sizeof(struct sockaddr_conn);
6647 store.sconn = control->whoFrom->ro._l_addr.sconn;
6648 store.sconn.sconn_port = control->port_from;
6649 break;
6650 #endif
6651 default:
6652 len = 0;
6653 break;
6654 }
6655 memcpy(from, &store, min((size_t)fromlen, len));
6656 #if defined(SCTP_EMBEDDED_V6_SCOPE)
6657 #ifdef INET6
6658 {
6659 struct sockaddr_in6 lsa6, *from6;
6660
6661 from6 = (struct sockaddr_in6 *)from;
6662 sctp_recover_scope_mac(from6, (&lsa6));
6663 }
6664 #endif
6665 #endif
6666 }
6667 if (hold_rlock) {
6668 SCTP_INP_READ_UNLOCK(inp);
6669 hold_rlock = 0;
6670 }
6671 if (hold_sblock) {
6672 SOCKBUF_UNLOCK(&so->so_rcv);
6673 hold_sblock = 0;
6674 }
6675 /* now copy out what data we can */
6676 if (mp == NULL) {
6677 /* copy out each mbuf in the chain up to length */
6678 get_more_data:
6679 m = control->data;
6680 while (m) {
6681 /* Move out all we can */
6682 #if defined(__APPLE__)
6683 #if defined(APPLE_LEOPARD)
6684 cp_len = uio->uio_resid;
6685 #else
6686 cp_len = uio_resid(uio);
6687 #endif
6688 #else
6689 cp_len = uio->uio_resid;
6690 #endif
6691 my_len = SCTP_BUF_LEN(m);
6692 if (cp_len > my_len) {
6693 /* not enough in this buf */
6694 cp_len = my_len;
6695 }
6696 if (hold_rlock) {
6697 SCTP_INP_READ_UNLOCK(inp);
6698 hold_rlock = 0;
6699 }
6700 #if defined(__APPLE__)
6701 SCTP_SOCKET_UNLOCK(so, 0);
6702 #endif
6703 if (cp_len > 0)
6704 error = uiomove(mtod(m, char *), (int)cp_len, uio);
6705 #if defined(__APPLE__)
6706 SCTP_SOCKET_LOCK(so, 0);
6707 #endif
6708 /* re-read */
6709 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
6710 goto release;
6711 }
6712
6713 if ((control->do_not_ref_stcb == 0) && stcb &&
6714 stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6715 no_rcv_needed = 1;
6716 }
6717 if (error) {
6718 /* error we are out of here */
6719 goto release;
6720 }
6721 SCTP_INP_READ_LOCK(inp);
6722 hold_rlock = 1;
6723 if (cp_len == SCTP_BUF_LEN(m)) {
6724 if ((SCTP_BUF_NEXT(m)== NULL) &&
6725 (control->end_added)) {
6726 out_flags |= MSG_EOR;
6727 if ((control->do_not_ref_stcb == 0) &&
6728 (control->stcb != NULL) &&
6729 ((control->spec_flags & M_NOTIFICATION) == 0))
6730 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6731 }
6732 if (control->spec_flags & M_NOTIFICATION) {
6733 out_flags |= MSG_NOTIFICATION;
6734 }
6735 /* we ate up the mbuf */
6736 if (in_flags & MSG_PEEK) {
6737 /* just looking */
6738 m = SCTP_BUF_NEXT(m);
6739 copied_so_far += cp_len;
6740 } else {
6741 /* dispose of the mbuf */
6742 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6743 sctp_sblog(&so->so_rcv,
6744 control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
6745 }
6746 sctp_sbfree(control, stcb, &so->so_rcv, m);
6747 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6748 sctp_sblog(&so->so_rcv,
6749 control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
6750 }
6751 copied_so_far += cp_len;
6752 freed_so_far += (uint32_t)cp_len;
6753 freed_so_far += MSIZE;
6754 atomic_subtract_int(&control->length, cp_len);
6755 control->data = sctp_m_free(m);
6756 m = control->data;
6757 /* been through it all, must hold sb lock ok to null tail */
6758 if (control->data == NULL) {
6759 #ifdef INVARIANTS
6760 #if defined(__FreeBSD__)
6761 if ((control->end_added == 0) ||
6762 (TAILQ_NEXT(control, next) == NULL)) {
6763 /* If the end is not added, OR the
6764 * next is NOT null we MUST have the lock.
6765 */
6766 if (mtx_owned(&inp->inp_rdata_mtx) == 0) {
6767 panic("Hmm we don't own the lock?");
6768 }
6769 }
6770 #endif
6771 #endif
6772 control->tail_mbuf = NULL;
6773 #ifdef INVARIANTS
6774 if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) {
6775 panic("end_added, nothing left and no MSG_EOR");
6776 }
6777 #endif
6778 }
6779 }
6780 } else {
6781 /* Do we need to trim the mbuf? */
6782 if (control->spec_flags & M_NOTIFICATION) {
6783 out_flags |= MSG_NOTIFICATION;
6784 }
6785 if ((in_flags & MSG_PEEK) == 0) {
6786 SCTP_BUF_RESV_UF(m, cp_len);
6787 SCTP_BUF_LEN(m) -= (int)cp_len;
6788 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6789 sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, (int)cp_len);
6790 }
6791 atomic_subtract_int(&so->so_rcv.sb_cc, cp_len);
6792 if ((control->do_not_ref_stcb == 0) &&
6793 stcb) {
6794 atomic_subtract_int(&stcb->asoc.sb_cc, cp_len);
6795 }
6796 copied_so_far += cp_len;
6797 freed_so_far += (uint32_t)cp_len;
6798 freed_so_far += MSIZE;
6799 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
6800 sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb,
6801 SCTP_LOG_SBRESULT, 0);
6802 }
6803 atomic_subtract_int(&control->length, cp_len);
6804 } else {
6805 copied_so_far += cp_len;
6806 }
6807 }
6808 #if defined(__APPLE__)
6809 #if defined(APPLE_LEOPARD)
6810 if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
6811 #else
6812 if ((out_flags & MSG_EOR) || (uio_resid(uio) == 0)) {
6813 #endif
6814 #else
6815 if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
6816 #endif
6817 break;
6818 }
6819 if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
6820 (control->do_not_ref_stcb == 0) &&
6821 (freed_so_far >= rwnd_req)) {
6822 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6823 }
6824 } /* end while(m) */
6825 /*
6826 * At this point we have looked at it all and we either have
6827 * a MSG_EOR/or read all the user wants... <OR>
6828 * control->length == 0.
6829 */
6830 if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) {
6831 /* we are done with this control */
6832 if (control->length == 0) {
6833 if (control->data) {
6834 #ifdef INVARIANTS
6835 panic("control->data not null at read eor?");
6836 #else
6837 SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n");
6838 sctp_m_freem(control->data);
6839 control->data = NULL;
6840 #endif
6841 }
6842 done_with_control:
6843 if (hold_rlock == 0) {
6844 SCTP_INP_READ_LOCK(inp);
6845 hold_rlock = 1;
6846 }
6847 TAILQ_REMOVE(&inp->read_queue, control, next);
6848 /* Add back any hiddend data */
6849 if (control->held_length) {
6850 held_length = 0;
6851 control->held_length = 0;
6852 wakeup_read_socket = 1;
6853 }
6854 if (control->aux_data) {
6855 sctp_m_free (control->aux_data);
6856 control->aux_data = NULL;
6857 }
6858 no_rcv_needed = control->do_not_ref_stcb;
6859 sctp_free_remote_addr(control->whoFrom);
6860 control->data = NULL;
6861 #ifdef INVARIANTS
6862 if (control->on_strm_q) {
6863 panic("About to free ctl:%p so:%p and its in %d",
6864 control, so, control->on_strm_q);
6865 }
6866 #endif
6867 sctp_free_a_readq(stcb, control);
6868 control = NULL;
6869 if ((freed_so_far >= rwnd_req) &&
6870 (no_rcv_needed == 0))
6871 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6872
6873 } else {
6874 /*
6875 * The user did not read all of this
6876 * message, turn off the returned MSG_EOR
6877 * since we are leaving more behind on the
6878 * control to read.
6879 */
6880 #ifdef INVARIANTS
6881 if (control->end_added &&
6882 (control->data == NULL) &&
6883 (control->tail_mbuf == NULL)) {
6884 panic("Gak, control->length is corrupt?");
6885 }
6886 #endif
6887 no_rcv_needed = control->do_not_ref_stcb;
6888 out_flags &= ~MSG_EOR;
6889 }
6890 }
6891 if (out_flags & MSG_EOR) {
6892 goto release;
6893 }
6894 #if defined(__APPLE__)
6895 #if defined(APPLE_LEOPARD)
6896 if ((uio->uio_resid == 0) ||
6897 #else
6898 if ((uio_resid(uio) == 0) ||
6899 #endif
6900 #else
6901 if ((uio->uio_resid == 0) ||
6902 #endif
6903 ((in_eeor_mode) &&
6904 (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))) {
6905 goto release;
6906 }
6907 /*
6908 * If I hit here the receiver wants more and this message is
6909 * NOT done (pd-api). So two questions. Can we block? if not
6910 * we are done. Did the user NOT set MSG_WAITALL?
6911 */
6912 if (block_allowed == 0) {
6913 goto release;
6914 }
6915 /*
6916 * We need to wait for more data a few things: - We don't
6917 * sbunlock() so we don't get someone else reading. - We
6918 * must be sure to account for the case where what is added
6919 * is NOT to our control when we wakeup.
6920 */
6921
6922 /* Do we need to tell the transport a rwnd update might be
6923 * needed before we go to sleep?
6924 */
6925 if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
6926 ((freed_so_far >= rwnd_req) &&
6927 (control->do_not_ref_stcb == 0) &&
6928 (no_rcv_needed == 0))) {
6929 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6930 }
6931 wait_some_more:
6932 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
6933 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
6934 goto release;
6935 }
6936 #else
6937 if (so->so_state & SS_CANTRCVMORE) {
6938 goto release;
6939 }
6940 #endif
6941
6942 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)
6943 goto release;
6944
6945 if (hold_rlock == 1) {
6946 SCTP_INP_READ_UNLOCK(inp);
6947 hold_rlock = 0;
6948 }
6949 if (hold_sblock == 0) {
6950 SOCKBUF_LOCK(&so->so_rcv);
6951 hold_sblock = 1;
6952 }
6953 if ((copied_so_far) && (control->length == 0) &&
6954 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
6955 goto release;
6956 }
6957 #if defined(__APPLE__)
6958 sbunlock(&so->so_rcv, 1);
6959 #endif
6960 if (so->so_rcv.sb_cc <= control->held_length) {
6961 error = sbwait(&so->so_rcv);
6962 if (error) {
6963 #if defined(__FreeBSD__)
6964 goto release;
6965 #else
6966 goto release_unlocked;
6967 #endif
6968 }
6969 control->held_length = 0;
6970 }
6971 #if defined(__APPLE__)
6972 error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags));
6973 #endif
6974 if (hold_sblock) {
6975 SOCKBUF_UNLOCK(&so->so_rcv);
6976 hold_sblock = 0;
6977 }
6978 if (control->length == 0) {
6979 /* still nothing here */
6980 if (control->end_added == 1) {
6981 /* he aborted, or is done i.e.did a shutdown */
6982 out_flags |= MSG_EOR;
6983 if (control->pdapi_aborted) {
6984 if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
6985 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6986
6987 out_flags |= MSG_TRUNC;
6988 } else {
6989 if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0))
6990 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6991 }
6992 goto done_with_control;
6993 }
6994 if (so->so_rcv.sb_cc > held_length) {
6995 control->held_length = so->so_rcv.sb_cc;
6996 held_length = 0;
6997 }
6998 goto wait_some_more;
6999 } else if (control->data == NULL) {
7000 /* we must re-sync since data
7001 * is probably being added
7002 */
7003 SCTP_INP_READ_LOCK(inp);
7004 if ((control->length > 0) && (control->data == NULL)) {
7005 /* big trouble.. we have the lock and its corrupt? */
7006 #ifdef INVARIANTS
7007 panic ("Impossible data==NULL length !=0");
7008 #endif
7009 out_flags |= MSG_EOR;
7010 out_flags |= MSG_TRUNC;
7011 control->length = 0;
7012 SCTP_INP_READ_UNLOCK(inp);
7013 goto done_with_control;
7014 }
7015 SCTP_INP_READ_UNLOCK(inp);
7016 /* We will fall around to get more data */
7017 }
7018 goto get_more_data;
7019 } else {
7020 /*-
7021 * Give caller back the mbuf chain,
7022 * store in uio_resid the length
7023 */
7024 wakeup_read_socket = 0;
7025 if ((control->end_added == 0) ||
7026 (TAILQ_NEXT(control, next) == NULL)) {
7027 /* Need to get rlock */
7028 if (hold_rlock == 0) {
7029 SCTP_INP_READ_LOCK(inp);
7030 hold_rlock = 1;
7031 }
7032 }
7033 if (control->end_added) {
7034 out_flags |= MSG_EOR;
7035 if ((control->do_not_ref_stcb == 0) &&
7036 (control->stcb != NULL) &&
7037 ((control->spec_flags & M_NOTIFICATION) == 0))
7038 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
7039 }
7040 if (control->spec_flags & M_NOTIFICATION) {
7041 out_flags |= MSG_NOTIFICATION;
7042 }
7043 #if defined(__APPLE__)
7044 #if defined(APPLE_LEOPARD)
7045 uio->uio_resid = control->length;
7046 #else
7047 uio_setresid(uio, control->length);
7048 #endif
7049 #else
7050 uio->uio_resid = control->length;
7051 #endif
7052 *mp = control->data;
7053 m = control->data;
7054 while (m) {
7055 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
7056 sctp_sblog(&so->so_rcv,
7057 control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
7058 }
7059 sctp_sbfree(control, stcb, &so->so_rcv, m);
7060 freed_so_far += (uint32_t)SCTP_BUF_LEN(m);
7061 freed_so_far += MSIZE;
7062 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
7063 sctp_sblog(&so->so_rcv,
7064 control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0);
7065 }
7066 m = SCTP_BUF_NEXT(m);
7067 }
7068 control->data = control->tail_mbuf = NULL;
7069 control->length = 0;
7070 if (out_flags & MSG_EOR) {
7071 /* Done with this control */
7072 goto done_with_control;
7073 }
7074 }
7075 release:
7076 if (hold_rlock == 1) {
7077 SCTP_INP_READ_UNLOCK(inp);
7078 hold_rlock = 0;
7079 }
7080 #if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__)
7081 if (hold_sblock == 0) {
7082 SOCKBUF_LOCK(&so->so_rcv);
7083 hold_sblock = 1;
7084 }
7085 #else
7086 if (hold_sblock == 1) {
7087 SOCKBUF_UNLOCK(&so->so_rcv);
7088 hold_sblock = 0;
7089 }
7090 #endif
7091 #if defined(__APPLE__)
7092 sbunlock(&so->so_rcv, 1);
7093 #endif
7094
7095 #if defined(__FreeBSD__)
7096 sbunlock(&so->so_rcv);
7097 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
7098 sockbuf_lock = 0;
7099 #endif
7100 #endif
7101
7102 release_unlocked:
7103 if (hold_sblock) {
7104 SOCKBUF_UNLOCK(&so->so_rcv);
7105 hold_sblock = 0;
7106 }
7107 if ((stcb) && (in_flags & MSG_PEEK) == 0) {
7108 if ((freed_so_far >= rwnd_req) &&
7109 (control && (control->do_not_ref_stcb == 0)) &&
7110 (no_rcv_needed == 0))
7111 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
7112 }
7113 out:
7114 if (msg_flags) {
7115 *msg_flags = out_flags;
7116 }
7117 if (((out_flags & MSG_EOR) == 0) &&
7118 ((in_flags & MSG_PEEK) == 0) &&
7119 (sinfo) &&
7120 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
7121 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO))) {
7122 struct sctp_extrcvinfo *s_extra;
7123 s_extra = (struct sctp_extrcvinfo *)sinfo;
7124 s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
7125 }
7126 if (hold_rlock == 1) {
7127 SCTP_INP_READ_UNLOCK(inp);
7128 }
7129 if (hold_sblock) {
7130 SOCKBUF_UNLOCK(&so->so_rcv);
7131 }
7132 #if defined(__FreeBSD__) && __FreeBSD_version >= 700000
7133 if (sockbuf_lock) {
7134 sbunlock(&so->so_rcv);
7135 }
7136 #endif
7137
7138 if (freecnt_applied) {
7139 /*
7140 * The lock on the socket buffer protects us so the free
7141 * code will stop. But since we used the socketbuf lock and
7142 * the sender uses the tcb_lock to increment, we need to use
7143 * the atomic add to the refcnt.
7144 */
7145 if (stcb == NULL) {
7146 #ifdef INVARIANTS
7147 panic("stcb for refcnt has gone NULL?");
7148 goto stage_left;
7149 #else
7150 goto stage_left;
7151 #endif
7152 }
7153 /* Save the value back for next time */
7154 stcb->freed_by_sorcv_sincelast = freed_so_far;
7155 atomic_add_int(&stcb->asoc.refcnt, -1);
7156 }
7157 if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
7158 if (stcb) {
7159 sctp_misc_ints(SCTP_SORECV_DONE,
7160 freed_so_far,
7161 #if defined(__APPLE__)
7162 #if defined(APPLE_LEOPARD)
7163 ((uio) ? (slen - uio->uio_resid) : slen),
7164 #else
7165 ((uio) ? (slen - uio_resid(uio)) : slen),
7166 #endif
7167 #else
7168 (uint32_t)((uio) ? (slen - uio->uio_resid) : slen),
7169 #endif
7170 stcb->asoc.my_rwnd,
7171 so->so_rcv.sb_cc);
7172 } else {
7173 sctp_misc_ints(SCTP_SORECV_DONE,
7174 freed_so_far,
7175 #if defined(__APPLE__)
7176 #if defined(APPLE_LEOPARD)
7177 ((uio) ? (slen - uio->uio_resid) : slen),
7178 #else
7179 ((uio) ? (slen - uio_resid(uio)) : slen),
7180 #endif
7181 #else
7182 (uint32_t)((uio) ? (slen - uio->uio_resid) : slen),
7183 #endif
7184 0,
7185 so->so_rcv.sb_cc);
7186 }
7187 }
7188 stage_left:
7189 if (wakeup_read_socket) {
7190 sctp_sorwakeup(inp, so);
7191 }
7192 return (error);
7193 }
7194
7195
7196 #ifdef SCTP_MBUF_LOGGING
7197 struct mbuf *
7198 sctp_m_free(struct mbuf *m)
7199 {
7200 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
7201 sctp_log_mb(m, SCTP_MBUF_IFREE);
7202 }
7203 return (m_free(m));
7204 }
7205
7206 void
7207 sctp_m_freem(struct mbuf *mb)
7208 {
7209 while (mb != NULL)
7210 mb = sctp_m_free(mb);
7211 }
7212
7213 #endif
7214
7215 int
7216 sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
7217 {
7218 /* Given a local address. For all associations
7219 * that holds the address, request a peer-set-primary.
7220 */
7221 struct sctp_ifa *ifa;
7222 struct sctp_laddr *wi;
7223
7224 ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
7225 if (ifa == NULL) {
7226 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL);
7227 return (EADDRNOTAVAIL);
7228 }
7229 /* Now that we have the ifa we must awaken the
7230 * iterator with this message.
7231 */
7232 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
7233 if (wi == NULL) {
7234 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
7235 return (ENOMEM);
7236 }
7237 /* Now incr the count and int wi structure */
7238 SCTP_INCR_LADDR_COUNT();
7239 memset(wi, 0, sizeof(*wi));
7240 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time);
7241 wi->ifa = ifa;
7242 wi->action = SCTP_SET_PRIM_ADDR;
7243 atomic_add_int(&ifa->refcount, 1);
7244
7245 /* Now add it to the work queue */
7246 SCTP_WQ_ADDR_LOCK();
7247 /*
7248 * Should this really be a tailq? As it is we will process the
7249 * newest first :-0
7250 */
7251 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
7252 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
7253 (struct sctp_inpcb *)NULL,
7254 (struct sctp_tcb *)NULL,
7255 (struct sctp_nets *)NULL);
7256 SCTP_WQ_ADDR_UNLOCK();
7257 return (0);
7258 }
7259
7260 #if defined(__Userspace__)
7261 /* no sctp_soreceive for __Userspace__ now */
7262 #endif
7263
7264 #if !defined(__Userspace__)
7265 int
7266 sctp_soreceive( struct socket *so,
7267 struct sockaddr **psa,
7268 struct uio *uio,
7269 struct mbuf **mp0,
7270 struct mbuf **controlp,
7271 int *flagsp)
7272 {
7273 int error, fromlen;
7274 uint8_t sockbuf[256];
7275 struct sockaddr *from;
7276 struct sctp_extrcvinfo sinfo;
7277 int filling_sinfo = 1;
7278 int flags;
7279 struct sctp_inpcb *inp;
7280
7281 inp = (struct sctp_inpcb *)so->so_pcb;
7282 /* pickup the assoc we are reading from */
7283 if (inp == NULL) {
7284 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7285 return (EINVAL);
7286 }
7287 if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT) &&
7288 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
7289 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) ||
7290 (controlp == NULL)) {
7291 /* user does not want the sndrcv ctl */
7292 filling_sinfo = 0;
7293 }
7294 if (psa) {
7295 from = (struct sockaddr *)sockbuf;
7296 fromlen = sizeof(sockbuf);
7297 #ifdef HAVE_SA_LEN
7298 from->sa_len = 0;
7299 #endif
7300 } else {
7301 from = NULL;
7302 fromlen = 0;
7303 }
7304
7305 #if defined(__APPLE__)
7306 SCTP_SOCKET_LOCK(so, 1);
7307 #endif
7308 if (filling_sinfo) {
7309 memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
7310 }
7311 if (flagsp != NULL) {
7312 flags = *flagsp;
7313 } else {
7314 flags = 0;
7315 }
7316 error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, &flags,
7317 (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
7318 if (flagsp != NULL) {
7319 *flagsp = flags;
7320 }
7321 if (controlp != NULL) {
7322 /* copy back the sinfo in a CMSG format */
7323 if (filling_sinfo && ((flags & MSG_NOTIFICATION) == 0)) {
7324 *controlp = sctp_build_ctl_nchunk(inp,
7325 (struct sctp_sndrcvinfo *)&sinfo);
7326 } else {
7327 *controlp = NULL;
7328 }
7329 }
7330 if (psa) {
7331 /* copy back the address info */
7332 #ifdef HAVE_SA_LEN
7333 if (from && from->sa_len) {
7334 #else
7335 if (from) {
7336 #endif
7337 #if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__)
7338 *psa = sodupsockaddr(from, M_NOWAIT);
7339 #else
7340 *psa = dup_sockaddr(from, mp0 == 0);
7341 #endif
7342 } else {
7343 *psa = NULL;
7344 }
7345 }
7346 #if defined(__APPLE__)
7347 SCTP_SOCKET_UNLOCK(so, 1);
7348 #endif
7349 return (error);
7350 }
7351
7352
7353 #if (defined(__FreeBSD__) && __FreeBSD_version < 603000) || defined(__Windows__)
7354 /*
7355 * General routine to allocate a hash table with control of memory flags.
7356 * is in 7.0 and beyond for sure :-)
7357 */
7358 void *
7359 sctp_hashinit_flags(int elements, struct malloc_type *type,
7360 u_long *hashmask, int flags)
7361 {
7362 long hashsize;
7363 LIST_HEAD(generic, generic) *hashtbl;
7364 int i;
7365
7366
7367 if (elements <= 0) {
7368 #ifdef INVARIANTS
7369 panic("hashinit: bad elements");
7370 #else
7371 SCTP_PRINTF("hashinit: bad elements?");
7372 elements = 1;
7373 #endif
7374 }
7375 for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
7376 continue;
7377 hashsize >>= 1;
7378 if (flags & HASH_WAITOK)
7379 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
7380 else if (flags & HASH_NOWAIT)
7381 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_NOWAIT);
7382 else {
7383 #ifdef INVARIANTS
7384 panic("flag incorrect in hashinit_flags");
7385 #else
7386 return (NULL);
7387 #endif
7388 }
7389
7390 /* no memory? */
7391 if (hashtbl == NULL)
7392 return (NULL);
7393
7394 for (i = 0; i < hashsize; i++)
7395 LIST_INIT(&hashtbl[i]);
7396 *hashmask = hashsize - 1;
7397 return (hashtbl);
7398 }
7399 #endif
7400
7401 #else /* __Userspace__ ifdef above sctp_soreceive */
7402 /*
7403 * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland.
7404 * NOTE: We don't want multiple definitions here. So sctp_hashinit_flags() above for
7405 *__FreeBSD__ must be excluded.
7406 *
7407 */
7408
7409 void *
7410 sctp_hashinit_flags(int elements, struct malloc_type *type,
7411 u_long *hashmask, int flags)
7412 {
7413 long hashsize;
7414 LIST_HEAD(generic, generic) *hashtbl;
7415 int i;
7416
7417 if (elements <= 0) {
7418 SCTP_PRINTF("hashinit: bad elements?");
7419 #ifdef INVARIANTS
7420 return (NULL);
7421 #else
7422 elements = 1;
7423 #endif
7424 }
7425 for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
7426 continue;
7427 hashsize >>= 1;
7428 /*cannot use MALLOC here because it has to be declared or defined
7429 using MALLOC_DECLARE or MALLOC_DEFINE first. */
7430 if (flags & HASH_WAITOK)
7431 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
7432 else if (flags & HASH_NOWAIT)
7433 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
7434 else {
7435 #ifdef INVARIANTS
7436 SCTP_PRINTF("flag incorrect in hashinit_flags.\n");
7437 #endif
7438 return (NULL);
7439 }
7440
7441 /* no memory? */
7442 if (hashtbl == NULL)
7443 return (NULL);
7444
7445 for (i = 0; i < hashsize; i++)
7446 LIST_INIT(&hashtbl[i]);
7447 *hashmask = hashsize - 1;
7448 return (hashtbl);
7449 }
7450
7451
7452 void
7453 sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
7454 {
7455 LIST_HEAD(generic, generic) *hashtbl, *hp;
7456
7457 hashtbl = vhashtbl;
7458 for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
7459 if (!LIST_EMPTY(hp)) {
7460 SCTP_PRINTF("hashdestroy: hash not empty.\n");
7461 return;
7462 }
7463 FREE(hashtbl, type);
7464 }
7465
7466
7467 void
7468 sctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
7469 {
7470 LIST_HEAD(generic, generic) *hashtbl/*, *hp*/;
7471 /*
7472 LIST_ENTRY(type) *start, *temp;
7473 */
7474 hashtbl = vhashtbl;
7475 /* Apparently temp is not dynamically allocated, so attempts to
7476 free it results in error.
7477 for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
7478 if (!LIST_EMPTY(hp)) {
7479 start = LIST_FIRST(hp);
7480 while (start != NULL) {
7481 temp = start;
7482 start = start->le_next;
7483 SCTP_PRINTF("%s: %p \n", __func__, (void *)temp);
7484 FREE(temp, type);
7485 }
7486 }
7487 */
7488 FREE(hashtbl, type);
7489 }
7490
7491
7492 #endif
7493
7494
7495 int
7496 sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
7497 int totaddr, int *error)
7498 {
7499 int added = 0;
7500 int i;
7501 struct sctp_inpcb *inp;
7502 struct sockaddr *sa;
7503 size_t incr = 0;
7504 #ifdef INET
7505 struct sockaddr_in *sin;
7506 #endif
7507 #ifdef INET6
7508 struct sockaddr_in6 *sin6;
7509 #endif
7510
7511 sa = addr;
7512 inp = stcb->sctp_ep;
7513 *error = 0;
7514 for (i = 0; i < totaddr; i++) {
7515 switch (sa->sa_family) {
7516 #ifdef INET
7517 case AF_INET:
7518 incr = sizeof(struct sockaddr_in);
7519 sin = (struct sockaddr_in *)sa;
7520 if ((sin->sin_addr.s_addr == INADDR_ANY) ||
7521 (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
7522 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
7523 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7524 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7525 SCTP_FROM_SCTPUTIL + SCTP_LOC_7);
7526 *error = EINVAL;
7527 goto out_now;
7528 }
7529 if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7530 SCTP_DONOT_SETSCOPE,
7531 SCTP_ADDR_IS_CONFIRMED)) {
7532 /* assoc gone no un-lock */
7533 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7534 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7535 SCTP_FROM_SCTPUTIL + SCTP_LOC_8);
7536 *error = ENOBUFS;
7537 goto out_now;
7538 }
7539 added++;
7540 break;
7541 #endif
7542 #ifdef INET6
7543 case AF_INET6:
7544 incr = sizeof(struct sockaddr_in6);
7545 sin6 = (struct sockaddr_in6 *)sa;
7546 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
7547 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
7548 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7549 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7550 SCTP_FROM_SCTPUTIL + SCTP_LOC_9);
7551 *error = EINVAL;
7552 goto out_now;
7553 }
7554 if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7555 SCTP_DONOT_SETSCOPE,
7556 SCTP_ADDR_IS_CONFIRMED)) {
7557 /* assoc gone no un-lock */
7558 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7559 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7560 SCTP_FROM_SCTPUTIL + SCTP_LOC_10);
7561 *error = ENOBUFS;
7562 goto out_now;
7563 }
7564 added++;
7565 break;
7566 #endif
7567 #if defined(__Userspace__)
7568 case AF_CONN:
7569 incr = sizeof(struct sockaddr_conn);
7570 if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port,
7571 SCTP_DONOT_SETSCOPE,
7572 SCTP_ADDR_IS_CONFIRMED)) {
7573 /* assoc gone no un-lock */
7574 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
7575 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
7576 SCTP_FROM_SCTPUTIL + SCTP_LOC_11);
7577 *error = ENOBUFS;
7578 goto out_now;
7579 }
7580 added++;
7581 break;
7582 #endif
7583 default:
7584 break;
7585 }
7586 sa = (struct sockaddr *)((caddr_t)sa + incr);
7587 }
7588 out_now:
7589 return (added);
7590 }
7591
7592 int
7593 sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
7594 unsigned int totaddr,
7595 unsigned int *num_v4, unsigned int *num_v6,
7596 unsigned int limit)
7597 {
7598 struct sockaddr *sa;
7599 struct sctp_tcb *stcb;
7600 unsigned int incr, at, i;
7601
7602 at = 0;
7603 sa = addr;
7604 *num_v6 = *num_v4 = 0;
7605 /* account and validate addresses */
7606 if (totaddr == 0) {
7607 return (EINVAL);
7608 }
7609 for (i = 0; i < totaddr; i++) {
7610 if (at + sizeof(struct sockaddr) > limit) {
7611 return (EINVAL);
7612 }
7613 switch (sa->sa_family) {
7614 #ifdef INET
7615 case AF_INET:
7616 incr = (unsigned int)sizeof(struct sockaddr_in);
7617 #ifdef HAVE_SA_LEN
7618 if (sa->sa_len != incr) {
7619 return (EINVAL);
7620 }
7621 #endif
7622 (*num_v4) += 1;
7623 break;
7624 #endif
7625 #ifdef INET6
7626 case AF_INET6:
7627 {
7628 struct sockaddr_in6 *sin6;
7629
7630 sin6 = (struct sockaddr_in6 *)sa;
7631 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7632 /* Must be non-mapped for connectx */
7633 return (EINVAL);
7634 }
7635 incr = (unsigned int)sizeof(struct sockaddr_in6);
7636 #ifdef HAVE_SA_LEN
7637 if (sa->sa_len != incr) {
7638 return (EINVAL);
7639 }
7640 #endif
7641 (*num_v6) += 1;
7642 break;
7643 }
7644 #endif
7645 default:
7646 return (EINVAL);
7647 }
7648 if ((at + incr) > limit) {
7649 return (EINVAL);
7650 }
7651 SCTP_INP_INCR_REF(inp);
7652 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
7653 if (stcb != NULL) {
7654 SCTP_TCB_UNLOCK(stcb);
7655 return (EALREADY);
7656 } else {
7657 SCTP_INP_DECR_REF(inp);
7658 }
7659 at += incr;
7660 sa = (struct sockaddr *)((caddr_t)sa + incr);
7661 }
7662 return (0);
7663 }
7664
7665 /*
7666 * sctp_bindx(ADD) for one address.
7667 * assumes all arguments are valid/checked by caller.
7668 */
7669 void
7670 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
7671 struct sockaddr *sa, sctp_assoc_t assoc_id,
7672 uint32_t vrf_id, int *error, void *p)
7673 {
7674 struct sockaddr *addr_touse;
7675 #if defined(INET) && defined(INET6)
7676 struct sockaddr_in sin;
7677 #endif
7678 #ifdef SCTP_MVRF
7679 int i, fnd = 0;
7680 #endif
7681
7682 /* see if we're bound all already! */
7683 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7684 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7685 *error = EINVAL;
7686 return;
7687 }
7688 #ifdef SCTP_MVRF
7689 /* Is the VRF one we have */
7690 for (i = 0; i < inp->num_vrfs; i++) {
7691 if (vrf_id == inp->m_vrf_ids[i]) {
7692 fnd = 1;
7693 break;
7694 }
7695 }
7696 if (!fnd) {
7697 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7698 *error = EINVAL;
7699 return;
7700 }
7701 #endif
7702 addr_touse = sa;
7703 #ifdef INET6
7704 if (sa->sa_family == AF_INET6) {
7705 #ifdef INET
7706 struct sockaddr_in6 *sin6;
7707
7708 #endif
7709 #ifdef HAVE_SA_LEN
7710 if (sa->sa_len != sizeof(struct sockaddr_in6)) {
7711 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7712 *error = EINVAL;
7713 return;
7714 }
7715 #endif
7716 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
7717 /* can only bind v6 on PF_INET6 sockets */
7718 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7719 *error = EINVAL;
7720 return;
7721 }
7722 #ifdef INET
7723 sin6 = (struct sockaddr_in6 *)addr_touse;
7724 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7725 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7726 SCTP_IPV6_V6ONLY(inp)) {
7727 /* can't bind v4-mapped on PF_INET sockets */
7728 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7729 *error = EINVAL;
7730 return;
7731 }
7732 in6_sin6_2_sin(&sin, sin6);
7733 addr_touse = (struct sockaddr *)&sin;
7734 }
7735 #endif
7736 }
7737 #endif
7738 #ifdef INET
7739 if (sa->sa_family == AF_INET) {
7740 #ifdef HAVE_SA_LEN
7741 if (sa->sa_len != sizeof(struct sockaddr_in)) {
7742 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7743 *error = EINVAL;
7744 return;
7745 }
7746 #endif
7747 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7748 SCTP_IPV6_V6ONLY(inp)) {
7749 /* can't bind v4 on PF_INET sockets */
7750 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7751 *error = EINVAL;
7752 return;
7753 }
7754 }
7755 #endif
7756 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
7757 #if !(defined(__Panda__) || defined(__Windows__) || defined(__Userspace__))
7758 if (p == NULL) {
7759 /* Can't get proc for Net/Open BSD */
7760 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7761 *error = EINVAL;
7762 return;
7763 }
7764 #endif
7765 *error = sctp_inpcb_bind(so, addr_touse, NULL, p);
7766 return;
7767 }
7768 /*
7769 * No locks required here since bind and mgmt_ep_sa
7770 * all do their own locking. If we do something for
7771 * the FIX: below we may need to lock in that case.
7772 */
7773 if (assoc_id == 0) {
7774 /* add the address */
7775 struct sctp_inpcb *lep;
7776 struct sockaddr_in *lsin = (struct sockaddr_in *)addr_touse;
7777
7778 /* validate the incoming port */
7779 if ((lsin->sin_port != 0) &&
7780 (lsin->sin_port != inp->sctp_lport)) {
7781 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7782 *error = EINVAL;
7783 return;
7784 } else {
7785 /* user specified 0 port, set it to existing port */
7786 lsin->sin_port = inp->sctp_lport;
7787 }
7788
7789 lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id);
7790 if (lep != NULL) {
7791 /*
7792 * We must decrement the refcount
7793 * since we have the ep already and
7794 * are binding. No remove going on
7795 * here.
7796 */
7797 SCTP_INP_DECR_REF(lep);
7798 }
7799 if (lep == inp) {
7800 /* already bound to it.. ok */
7801 return;
7802 } else if (lep == NULL) {
7803 ((struct sockaddr_in *)addr_touse)->sin_port = 0;
7804 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
7805 SCTP_ADD_IP_ADDRESS,
7806 vrf_id, NULL);
7807 } else {
7808 *error = EADDRINUSE;
7809 }
7810 if (*error)
7811 return;
7812 } else {
7813 /*
7814 * FIX: decide whether we allow assoc based
7815 * bindx
7816 */
7817 }
7818 }
7819
7820 /*
7821 * sctp_bindx(DELETE) for one address.
7822 * assumes all arguments are valid/checked by caller.
7823 */
7824 void
7825 sctp_bindx_delete_address(struct sctp_inpcb *inp,
7826 struct sockaddr *sa, sctp_assoc_t assoc_id,
7827 uint32_t vrf_id, int *error)
7828 {
7829 struct sockaddr *addr_touse;
7830 #if defined(INET) && defined(INET6)
7831 struct sockaddr_in sin;
7832 #endif
7833 #ifdef SCTP_MVRF
7834 int i, fnd = 0;
7835 #endif
7836
7837 /* see if we're bound all already! */
7838 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7839 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7840 *error = EINVAL;
7841 return;
7842 }
7843 #ifdef SCTP_MVRF
7844 /* Is the VRF one we have */
7845 for (i = 0; i < inp->num_vrfs; i++) {
7846 if (vrf_id == inp->m_vrf_ids[i]) {
7847 fnd = 1;
7848 break;
7849 }
7850 }
7851 if (!fnd) {
7852 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7853 *error = EINVAL;
7854 return;
7855 }
7856 #endif
7857 addr_touse = sa;
7858 #ifdef INET6
7859 if (sa->sa_family == AF_INET6) {
7860 #ifdef INET
7861 struct sockaddr_in6 *sin6;
7862 #endif
7863
7864 #ifdef HAVE_SA_LEN
7865 if (sa->sa_len != sizeof(struct sockaddr_in6)) {
7866 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7867 *error = EINVAL;
7868 return;
7869 }
7870 #endif
7871 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
7872 /* can only bind v6 on PF_INET6 sockets */
7873 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7874 *error = EINVAL;
7875 return;
7876 }
7877 #ifdef INET
7878 sin6 = (struct sockaddr_in6 *)addr_touse;
7879 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
7880 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7881 SCTP_IPV6_V6ONLY(inp)) {
7882 /* can't bind mapped-v4 on PF_INET sockets */
7883 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7884 *error = EINVAL;
7885 return;
7886 }
7887 in6_sin6_2_sin(&sin, sin6);
7888 addr_touse = (struct sockaddr *)&sin;
7889 }
7890 #endif
7891 }
7892 #endif
7893 #ifdef INET
7894 if (sa->sa_family == AF_INET) {
7895 #ifdef HAVE_SA_LEN
7896 if (sa->sa_len != sizeof(struct sockaddr_in)) {
7897 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7898 *error = EINVAL;
7899 return;
7900 }
7901 #endif
7902 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
7903 SCTP_IPV6_V6ONLY(inp)) {
7904 /* can't bind v4 on PF_INET sockets */
7905 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
7906 *error = EINVAL;
7907 return;
7908 }
7909 }
7910 #endif
7911 /*
7912 * No lock required mgmt_ep_sa does its own locking.
7913 * If the FIX: below is ever changed we may need to
7914 * lock before calling association level binding.
7915 */
7916 if (assoc_id == 0) {
7917 /* delete the address */
7918 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
7919 SCTP_DEL_IP_ADDRESS,
7920 vrf_id, NULL);
7921 } else {
7922 /*
7923 * FIX: decide whether we allow assoc based
7924 * bindx
7925 */
7926 }
7927 }
7928
7929 /*
7930 * returns the valid local address count for an assoc, taking into account
7931 * all scoping rules
7932 */
7933 int
7934 sctp_local_addr_count(struct sctp_tcb *stcb)
7935 {
7936 int loopback_scope;
7937 #if defined(INET)
7938 int ipv4_local_scope, ipv4_addr_legal;
7939 #endif
7940 #if defined (INET6)
7941 int local_scope, site_scope, ipv6_addr_legal;
7942 #endif
7943 #if defined(__Userspace__)
7944 int conn_addr_legal;
7945 #endif
7946 struct sctp_vrf *vrf;
7947 struct sctp_ifn *sctp_ifn;
7948 struct sctp_ifa *sctp_ifa;
7949 int count = 0;
7950
7951 /* Turn on all the appropriate scopes */
7952 loopback_scope = stcb->asoc.scope.loopback_scope;
7953 #if defined(INET)
7954 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
7955 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
7956 #endif
7957 #if defined(INET6)
7958 local_scope = stcb->asoc.scope.local_scope;
7959 site_scope = stcb->asoc.scope.site_scope;
7960 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
7961 #endif
7962 #if defined(__Userspace__)
7963 conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
7964 #endif
7965 SCTP_IPI_ADDR_RLOCK();
7966 vrf = sctp_find_vrf(stcb->asoc.vrf_id);
7967 if (vrf == NULL) {
7968 /* no vrf, no addresses */
7969 SCTP_IPI_ADDR_RUNLOCK();
7970 return (0);
7971 }
7972
7973 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
7974 /*
7975 * bound all case: go through all ifns on the vrf
7976 */
7977 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
7978 if ((loopback_scope == 0) &&
7979 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
7980 continue;
7981 }
7982 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
7983 if (sctp_is_addr_restricted(stcb, sctp_ifa))
7984 continue;
7985 switch (sctp_ifa->address.sa.sa_family) {
7986 #ifdef INET
7987 case AF_INET:
7988 if (ipv4_addr_legal) {
7989 struct sockaddr_in *sin;
7990
7991 sin = &sctp_ifa->address.sin;
7992 if (sin->sin_addr.s_addr == 0) {
7993 /* skip unspecified addrs */
7994 continue;
7995 }
7996 #if defined(__FreeBSD__)
7997 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
7998 &sin->sin_addr) != 0) {
7999 continue;
8000 }
8001 #endif
8002 if ((ipv4_local_scope == 0) &&
8003 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
8004 continue;
8005 }
8006 /* count this one */
8007 count++;
8008 } else {
8009 continue;
8010 }
8011 break;
8012 #endif
8013 #ifdef INET6
8014 case AF_INET6:
8015 if (ipv6_addr_legal) {
8016 struct sockaddr_in6 *sin6;
8017
8018 #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
8019 struct sockaddr_in6 lsa6;
8020 #endif
8021 sin6 = &sctp_ifa->address.sin6;
8022 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
8023 continue;
8024 }
8025 #if defined(__FreeBSD__)
8026 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
8027 &sin6->sin6_addr) != 0) {
8028 continue;
8029 }
8030 #endif
8031 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
8032 if (local_scope == 0)
8033 continue;
8034 #if defined(SCTP_EMBEDDED_V6_SCOPE)
8035 if (sin6->sin6_scope_id == 0) {
8036 #ifdef SCTP_KAME
8037 if (sa6_recoverscope(sin6) != 0)
8038 /*
8039 * bad link
8040 * local
8041 * address
8042 */
8043 continue;
8044 #else
8045 lsa6 = *sin6;
8046 if (in6_recoverscope(&lsa6,
8047 &lsa6.sin6_addr,
8048 NULL))
8049 /*
8050 * bad link
8051 * local
8052 * address
8053 */
8054 continue;
8055 sin6 = &lsa6;
8056 #endif /* SCTP_KAME */
8057 }
8058 #endif /* SCTP_EMBEDDED_V6_SCOPE */
8059 }
8060 if ((site_scope == 0) &&
8061 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
8062 continue;
8063 }
8064 /* count this one */
8065 count++;
8066 }
8067 break;
8068 #endif
8069 #if defined(__Userspace__)
8070 case AF_CONN:
8071 if (conn_addr_legal) {
8072 count++;
8073 }
8074 break;
8075 #endif
8076 default:
8077 /* TSNH */
8078 break;
8079 }
8080 }
8081 }
8082 } else {
8083 /*
8084 * subset bound case
8085 */
8086 struct sctp_laddr *laddr;
8087 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list,
8088 sctp_nxt_addr) {
8089 if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
8090 continue;
8091 }
8092 /* count this one */
8093 count++;
8094 }
8095 }
8096 SCTP_IPI_ADDR_RUNLOCK();
8097 return (count);
8098 }
8099
8100 #if defined(SCTP_LOCAL_TRACE_BUF)
8101
8102 void
8103 sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f)
8104 {
8105 uint32_t saveindex, newindex;
8106
8107 #if defined(__Windows__)
8108 if (SCTP_BASE_SYSCTL(sctp_log) == NULL) {
8109 return;
8110 }
8111 do {
8112 saveindex = SCTP_BASE_SYSCTL(sctp_log)->index;
8113 if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8114 newindex = 1;
8115 } else {
8116 newindex = saveindex + 1;
8117 }
8118 } while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log)->index, saveindex, newindex) == 0);
8119 if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8120 saveindex = 0;
8121 }
8122 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
8123 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].subsys = subsys;
8124 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[0] = a;
8125 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[1] = b;
8126 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[2] = c;
8127 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[3] = d;
8128 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[4] = e;
8129 SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[5] = f;
8130 #else
8131 do {
8132 saveindex = SCTP_BASE_SYSCTL(sctp_log).index;
8133 if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8134 newindex = 1;
8135 } else {
8136 newindex = saveindex + 1;
8137 }
8138 } while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log).index, saveindex, newindex) == 0);
8139 if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
8140 saveindex = 0;
8141 }
8142 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
8143 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].subsys = subsys;
8144 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[0] = a;
8145 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[1] = b;
8146 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[2] = c;
8147 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[3] = d;
8148 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[4] = e;
8149 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[5] = f;
8150 #endif
8151 }
8152
8153 #endif
8154 #if defined(__FreeBSD__)
8155 #if __FreeBSD_version >= 800044
8156 static void
8157 sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp,
8158 const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED)
8159 {
8160 struct ip *iph;
8161 #ifdef INET6
8162 struct ip6_hdr *ip6;
8163 #endif
8164 struct mbuf *sp, *last;
8165 struct udphdr *uhdr;
8166 uint16_t port;
8167
8168 if ((m->m_flags & M_PKTHDR) == 0) {
8169 /* Can't handle one that is not a pkt hdr */
8170 goto out;
8171 }
8172 /* Pull the src port */
8173 iph = mtod(m, struct ip *);
8174 uhdr = (struct udphdr *)((caddr_t)iph + off);
8175 port = uhdr->uh_sport;
8176 /* Split out the mbuf chain. Leave the
8177 * IP header in m, place the
8178 * rest in the sp.
8179 */
8180 sp = m_split(m, off, M_NOWAIT);
8181 if (sp == NULL) {
8182 /* Gak, drop packet, we can't do a split */
8183 goto out;
8184 }
8185 if (sp->m_pkthdr.len < sizeof(struct udphdr) + sizeof(struct sctphdr)) {
8186 /* Gak, packet can't have an SCTP header in it - too small */
8187 m_freem(sp);
8188 goto out;
8189 }
8190 /* Now pull up the UDP header and SCTP header together */
8191 sp = m_pullup(sp, sizeof(struct udphdr) + sizeof(struct sctphdr));
8192 if (sp == NULL) {
8193 /* Gak pullup failed */
8194 goto out;
8195 }
8196 /* Trim out the UDP header */
8197 m_adj(sp, sizeof(struct udphdr));
8198
8199 /* Now reconstruct the mbuf chain */
8200 for (last = m; last->m_next; last = last->m_next);
8201 last->m_next = sp;
8202 m->m_pkthdr.len += sp->m_pkthdr.len;
8203 /*
8204 * The CSUM_DATA_VALID flags indicates that the HW checked the
8205 * UDP checksum and it was valid.
8206 * Since CSUM_DATA_VALID == CSUM_SCTP_VALID this would imply that
8207 * the HW also verified the SCTP checksum. Therefore, clear the bit.
8208 */
8209 #if __FreeBSD_version > 1000049
8210 SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
8211 "sctp_recv_udp_tunneled_packet(): Packet of length %d received on %s with csum_flags 0x%b.\n",
8212 m->m_pkthdr.len,
8213 if_name(m->m_pkthdr.rcvif),
8214 (int)m->m_pkthdr.csum_flags, CSUM_BITS);
8215 #else
8216 SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
8217 "sctp_recv_udp_tunneled_packet(): Packet of length %d received on %s with csum_flags 0x%x.\n",
8218 m->m_pkthdr.len,
8219 if_name(m->m_pkthdr.rcvif),
8220 m->m_pkthdr.csum_flags);
8221 #endif
8222 m->m_pkthdr.csum_flags &= ~CSUM_DATA_VALID;
8223 iph = mtod(m, struct ip *);
8224 switch (iph->ip_v) {
8225 #ifdef INET
8226 case IPVERSION:
8227 #if __FreeBSD_version >= 1000000
8228 iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr));
8229 #else
8230 iph->ip_len -= sizeof(struct udphdr);
8231 #endif
8232 sctp_input_with_port(m, off, port);
8233 break;
8234 #endif
8235 #ifdef INET6
8236 case IPV6_VERSION >> 4:
8237 ip6 = mtod(m, struct ip6_hdr *);
8238 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr));
8239 sctp6_input_with_port(&m, &off, port);
8240 break;
8241 #endif
8242 default:
8243 goto out;
8244 break;
8245 }
8246 return;
8247 out:
8248 m_freem(m);
8249 }
8250 #endif
8251
8252 #if __FreeBSD_version >= 1100000
8253 #ifdef INET
8254 static void
8255 sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ctx SCTP_UNUSED)
8256 {
8257 struct ip *outer_ip, *inner_ip;
8258 struct sctphdr *sh;
8259 struct icmp *icmp;
8260 struct udphdr *udp;
8261 struct sctp_inpcb *inp;
8262 struct sctp_tcb *stcb;
8263 struct sctp_nets *net;
8264 struct sctp_init_chunk *ch;
8265 struct sockaddr_in src, dst;
8266 uint8_t type, code;
8267
8268 inner_ip = (struct ip *)vip;
8269 icmp = (struct icmp *)((caddr_t)inner_ip -
8270 (sizeof(struct icmp) - sizeof(struct ip)));
8271 outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
8272 if (ntohs(outer_ip->ip_len) <
8273 sizeof(struct ip) + 8 + (inner_ip->ip_hl << 2) + sizeof(struct udphdr) + 8) {
8274 return;
8275 }
8276 udp = (struct udphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
8277 sh = (struct sctphdr *)(udp + 1);
8278 memset(&src, 0, sizeof(struct sockaddr_in));
8279 src.sin_family = AF_INET;
8280 #ifdef HAVE_SIN_LEN
8281 src.sin_len = sizeof(struct sockaddr_in);
8282 #endif
8283 src.sin_port = sh->src_port;
8284 src.sin_addr = inner_ip->ip_src;
8285 memset(&dst, 0, sizeof(struct sockaddr_in));
8286 dst.sin_family = AF_INET;
8287 #ifdef HAVE_SIN_LEN
8288 dst.sin_len = sizeof(struct sockaddr_in);
8289 #endif
8290 dst.sin_port = sh->dest_port;
8291 dst.sin_addr = inner_ip->ip_dst;
8292 /*
8293 * 'dst' holds the dest of the packet that failed to be sent.
8294 * 'src' holds our local endpoint address. Thus we reverse
8295 * the dst and the src in the lookup.
8296 */
8297 inp = NULL;
8298 net = NULL;
8299 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
8300 (struct sockaddr *)&src,
8301 &inp, &net, 1,
8302 SCTP_DEFAULT_VRFID);
8303 if ((stcb != NULL) &&
8304 (net != NULL) &&
8305 (inp != NULL)) {
8306 /* Check the UDP port numbers */
8307 if ((udp->uh_dport != net->port) ||
8308 (udp->uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) {
8309 SCTP_TCB_UNLOCK(stcb);
8310 return;
8311 }
8312 /* Check the verification tag */
8313 if (ntohl(sh->v_tag) != 0) {
8314 /*
8315 * This must be the verification tag used
8316 * for sending out packets. We don't
8317 * consider packets reflecting the
8318 * verification tag.
8319 */
8320 if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
8321 SCTP_TCB_UNLOCK(stcb);
8322 return;
8323 }
8324 } else {
8325 if (ntohs(outer_ip->ip_len) >=
8326 sizeof(struct ip) +
8327 8 + (inner_ip->ip_hl << 2) + 8 + 20) {
8328 /*
8329 * In this case we can check if we
8330 * got an INIT chunk and if the
8331 * initiate tag matches.
8332 */
8333 ch = (struct sctp_init_chunk *)(sh + 1);
8334 if ((ch->ch.chunk_type != SCTP_INITIATION) ||
8335 (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
8336 SCTP_TCB_UNLOCK(stcb);
8337 return;
8338 }
8339 } else {
8340 SCTP_TCB_UNLOCK(stcb);
8341 return;
8342 }
8343 }
8344 type = icmp->icmp_type;
8345 code = icmp->icmp_code;
8346 if ((type == ICMP_UNREACH) &&
8347 (code == ICMP_UNREACH_PORT)) {
8348 code = ICMP_UNREACH_PROTOCOL;
8349 }
8350 sctp_notify(inp, stcb, net, type, code,
8351 ntohs(inner_ip->ip_len),
8352 (uint32_t)ntohs(icmp->icmp_nextmtu));
8353 #if defined(__Userspace__)
8354 if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
8355 (stcb->sctp_socket != NULL)) {
8356 struct socket *upcall_socket;
8357
8358 upcall_socket = stcb->sctp_socket;
8359 SOCK_LOCK(upcall_socket);
8360 soref(upcall_socket);
8361 SOCK_UNLOCK(upcall_socket);
8362 if ((upcall_socket->so_upcall != NULL) &&
8363 (upcall_socket->so_error != 0)) {
8364 (*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
8365 }
8366 ACCEPT_LOCK();
8367 SOCK_LOCK(upcall_socket);
8368 sorele(upcall_socket);
8369 }
8370 #endif
8371 } else {
8372 #if defined(__FreeBSD__) && __FreeBSD_version < 500000
8373 /*
8374 * XXX must be fixed for 5.x and higher, leave for
8375 * 4.x
8376 */
8377 if (PRC_IS_REDIRECT(cmd) && (inp != NULL)) {
8378 in_rtchange((struct inpcb *)inp,
8379 inetctlerrmap[cmd]);
8380 }
8381 #endif
8382 if ((stcb == NULL) && (inp != NULL)) {
8383 /* reduce ref-count */
8384 SCTP_INP_WLOCK(inp);
8385 SCTP_INP_DECR_REF(inp);
8386 SCTP_INP_WUNLOCK(inp);
8387 }
8388 if (stcb) {
8389 SCTP_TCB_UNLOCK(stcb);
8390 }
8391 }
8392 return;
8393 }
8394 #endif
8395
8396 #ifdef INET6
8397 static void
8398 sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx SCTP_UNUSED)
8399 {
8400 struct ip6ctlparam *ip6cp;
8401 struct sctp_inpcb *inp;
8402 struct sctp_tcb *stcb;
8403 struct sctp_nets *net;
8404 struct sctphdr sh;
8405 struct udphdr udp;
8406 struct sockaddr_in6 src, dst;
8407 uint8_t type, code;
8408
8409 ip6cp = (struct ip6ctlparam *)d;
8410 /*
8411 * XXX: We assume that when IPV6 is non NULL, M and OFF are
8412 * valid.
8413 */
8414 if (ip6cp->ip6c_m == NULL) {
8415 return;
8416 }
8417 /* Check if we can safely examine the ports and the
8418 * verification tag of the SCTP common header.
8419 */
8420 if (ip6cp->ip6c_m->m_pkthdr.len <
8421 ip6cp->ip6c_off + sizeof(struct udphdr)+ offsetof(struct sctphdr, checksum)) {
8422 return;
8423 }
8424 /* Copy out the UDP header. */
8425 memset(&udp, 0, sizeof(struct udphdr));
8426 m_copydata(ip6cp->ip6c_m,
8427 ip6cp->ip6c_off,
8428 sizeof(struct udphdr),
8429 (caddr_t)&udp);
8430 /* Copy out the port numbers and the verification tag. */
8431 memset(&sh, 0, sizeof(struct sctphdr));
8432 m_copydata(ip6cp->ip6c_m,
8433 ip6cp->ip6c_off + sizeof(struct udphdr),
8434 sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
8435 (caddr_t)&sh);
8436 memset(&src, 0, sizeof(struct sockaddr_in6));
8437 src.sin6_family = AF_INET6;
8438 #ifdef HAVE_SIN6_LEN
8439 src.sin6_len = sizeof(struct sockaddr_in6);
8440 #endif
8441 src.sin6_port = sh.src_port;
8442 src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
8443 #if defined(__FreeBSD__)
8444 if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
8445 return;
8446 }
8447 #endif
8448 memset(&dst, 0, sizeof(struct sockaddr_in6));
8449 dst.sin6_family = AF_INET6;
8450 #ifdef HAVE_SIN6_LEN
8451 dst.sin6_len = sizeof(struct sockaddr_in6);
8452 #endif
8453 dst.sin6_port = sh.dest_port;
8454 dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
8455 #if defined(__FreeBSD__)
8456 if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
8457 return;
8458 }
8459 #endif
8460 inp = NULL;
8461 net = NULL;
8462 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
8463 (struct sockaddr *)&src,
8464 &inp, &net, 1, SCTP_DEFAULT_VRFID);
8465 if ((stcb != NULL) &&
8466 (net != NULL) &&
8467 (inp != NULL)) {
8468 /* Check the UDP port numbers */
8469 if ((udp.uh_dport != net->port) ||
8470 (udp.uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) {
8471 SCTP_TCB_UNLOCK(stcb);
8472 return;
8473 }
8474 /* Check the verification tag */
8475 if (ntohl(sh.v_tag) != 0) {
8476 /*
8477 * This must be the verification tag used for
8478 * sending out packets. We don't consider
8479 * packets reflecting the verification tag.
8480 */
8481 if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
8482 SCTP_TCB_UNLOCK(stcb);
8483 return;
8484 }
8485 } else {
8486 #if defined(__FreeBSD__)
8487 if (ip6cp->ip6c_m->m_pkthdr.len >=
8488 ip6cp->ip6c_off + sizeof(struct udphdr) +
8489 sizeof(struct sctphdr) +
8490 sizeof(struct sctp_chunkhdr) +
8491 offsetof(struct sctp_init, a_rwnd)) {
8492 /*
8493 * In this case we can check if we
8494 * got an INIT chunk and if the
8495 * initiate tag matches.
8496 */
8497 uint32_t initiate_tag;
8498 uint8_t chunk_type;
8499
8500 m_copydata(ip6cp->ip6c_m,
8501 ip6cp->ip6c_off +
8502 sizeof(struct udphdr) +
8503 sizeof(struct sctphdr),
8504 sizeof(uint8_t),
8505 (caddr_t)&chunk_type);
8506 m_copydata(ip6cp->ip6c_m,
8507 ip6cp->ip6c_off +
8508 sizeof(struct udphdr) +
8509 sizeof(struct sctphdr) +
8510 sizeof(struct sctp_chunkhdr),
8511 sizeof(uint32_t),
8512 (caddr_t)&initiate_tag);
8513 if ((chunk_type != SCTP_INITIATION) ||
8514 (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
8515 SCTP_TCB_UNLOCK(stcb);
8516 return;
8517 }
8518 } else {
8519 SCTP_TCB_UNLOCK(stcb);
8520 return;
8521 }
8522 #else
8523 SCTP_TCB_UNLOCK(stcb);
8524 return;
8525 #endif
8526 }
8527 type = ip6cp->ip6c_icmp6->icmp6_type;
8528 code = ip6cp->ip6c_icmp6->icmp6_code;
8529 if ((type == ICMP6_DST_UNREACH) &&
8530 (code == ICMP6_DST_UNREACH_NOPORT)) {
8531 type = ICMP6_PARAM_PROB;
8532 code = ICMP6_PARAMPROB_NEXTHEADER;
8533 }
8534 sctp6_notify(inp, stcb, net, type, code,
8535 ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
8536 #if defined(__Userspace__)
8537 if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) &&
8538 (stcb->sctp_socket != NULL)) {
8539 struct socket *upcall_socket;
8540
8541 upcall_socket = stcb->sctp_socket;
8542 SOCK_LOCK(upcall_socket);
8543 soref(upcall_socket);
8544 SOCK_UNLOCK(upcall_socket);
8545 if ((upcall_socket->so_upcall != NULL) &&
8546 (upcall_socket->so_error != 0)) {
8547 (*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
8548 }
8549 ACCEPT_LOCK();
8550 SOCK_LOCK(upcall_socket);
8551 sorele(upcall_socket);
8552 }
8553 #endif
8554 } else {
8555 #if defined(__FreeBSD__) && __FreeBSD_version < 500000
8556 if (PRC_IS_REDIRECT(cmd) && (inp != NULL)) {
8557 in6_rtchange(inp, inet6ctlerrmap[cmd]);
8558 }
8559 #endif
8560 if ((stcb == NULL) && (inp != NULL)) {
8561 /* reduce inp's ref-count */
8562 SCTP_INP_WLOCK(inp);
8563 SCTP_INP_DECR_REF(inp);
8564 SCTP_INP_WUNLOCK(inp);
8565 }
8566 if (stcb) {
8567 SCTP_TCB_UNLOCK(stcb);
8568 }
8569 }
8570 }
8571 #endif
8572 #endif
8573
8574 void
8575 sctp_over_udp_stop(void)
8576 {
8577 /*
8578 * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting!
8579 */
8580 #ifdef INET
8581 if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) {
8582 soclose(SCTP_BASE_INFO(udp4_tun_socket));
8583 SCTP_BASE_INFO(udp4_tun_socket) = NULL;
8584 }
8585 #endif
8586 #ifdef INET6
8587 if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) {
8588 soclose(SCTP_BASE_INFO(udp6_tun_socket));
8589 SCTP_BASE_INFO(udp6_tun_socket) = NULL;
8590 }
8591 #endif
8592 }
8593
8594 int
8595 sctp_over_udp_start(void)
8596 {
8597 #if __FreeBSD_version >= 800044
8598 uint16_t port;
8599 int ret;
8600 #ifdef INET
8601 struct sockaddr_in sin;
8602 #endif
8603 #ifdef INET6
8604 struct sockaddr_in6 sin6;
8605 #endif
8606 /*
8607 * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting!
8608 */
8609 port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
8610 if (ntohs(port) == 0) {
8611 /* Must have a port set */
8612 return (EINVAL);
8613 }
8614 #ifdef INET
8615 if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) {
8616 /* Already running -- must stop first */
8617 return (EALREADY);
8618 }
8619 #endif
8620 #ifdef INET6
8621 if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) {
8622 /* Already running -- must stop first */
8623 return (EALREADY);
8624 }
8625 #endif
8626 #ifdef INET
8627 if ((ret = socreate(PF_INET, &SCTP_BASE_INFO(udp4_tun_socket),
8628 SOCK_DGRAM, IPPROTO_UDP,
8629 curthread->td_ucred, curthread))) {
8630 sctp_over_udp_stop();
8631 return (ret);
8632 }
8633 /* Call the special UDP hook. */
8634 if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket),
8635 sctp_recv_udp_tunneled_packet,
8636 #if __FreeBSD_version >= 1100000
8637 sctp_recv_icmp_tunneled_packet,
8638 #endif
8639 NULL))) {
8640 sctp_over_udp_stop();
8641 return (ret);
8642 }
8643 /* Ok, we have a socket, bind it to the port. */
8644 memset(&sin, 0, sizeof(struct sockaddr_in));
8645 sin.sin_len = sizeof(struct sockaddr_in);
8646 sin.sin_family = AF_INET;
8647 sin.sin_port = htons(port);
8648 if ((ret = sobind(SCTP_BASE_INFO(udp4_tun_socket),
8649 (struct sockaddr *)&sin, curthread))) {
8650 sctp_over_udp_stop();
8651 return (ret);
8652 }
8653 #endif
8654 #ifdef INET6
8655 if ((ret = socreate(PF_INET6, &SCTP_BASE_INFO(udp6_tun_socket),
8656 SOCK_DGRAM, IPPROTO_UDP,
8657 curthread->td_ucred, curthread))) {
8658 sctp_over_udp_stop();
8659 return (ret);
8660 }
8661 /* Call the special UDP hook. */
8662 if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket),
8663 sctp_recv_udp_tunneled_packet,
8664 #if __FreeBSD_version >= 1100000
8665 sctp_recv_icmp6_tunneled_packet,
8666 #endif
8667 NULL))) {
8668 sctp_over_udp_stop();
8669 return (ret);
8670 }
8671 /* Ok, we have a socket, bind it to the port. */
8672 memset(&sin6, 0, sizeof(struct sockaddr_in6));
8673 sin6.sin6_len = sizeof(struct sockaddr_in6);
8674 sin6.sin6_family = AF_INET6;
8675 sin6.sin6_port = htons(port);
8676 if ((ret = sobind(SCTP_BASE_INFO(udp6_tun_socket),
8677 (struct sockaddr *)&sin6, curthread))) {
8678 sctp_over_udp_stop();
8679 return (ret);
8680 }
8681 #endif
8682 return (0);
8683 #else
8684 return (ENOTSUP);
8685 #endif
8686 }
8687 #endif
8688
8689 /*
8690 * sctp_min_mtu ()returns the minimum of all non-zero arguments.
8691 * If all arguments are zero, zero is returned.
8692 */
8693 uint32_t
8694 sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3)
8695 {
8696 if (mtu1 > 0) {
8697 if (mtu2 > 0) {
8698 if (mtu3 > 0) {
8699 return (min(mtu1, min(mtu2, mtu3)));
8700 } else {
8701 return (min(mtu1, mtu2));
8702 }
8703 } else {
8704 if (mtu3 > 0) {
8705 return (min(mtu1, mtu3));
8706 } else {
8707 return (mtu1);
8708 }
8709 }
8710 } else {
8711 if (mtu2 > 0) {
8712 if (mtu3 > 0) {
8713 return (min(mtu2, mtu3));
8714 } else {
8715 return (mtu2);
8716 }
8717 } else {
8718 return (mtu3);
8719 }
8720 }
8721 }
8722
8723 #if defined(__FreeBSD__)
8724 void
8725 sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu)
8726 {
8727 struct in_conninfo inc;
8728
8729 memset(&inc, 0, sizeof(struct in_conninfo));
8730 inc.inc_fibnum = fibnum;
8731 switch (addr->sa.sa_family) {
8732 #ifdef INET
8733 case AF_INET:
8734 inc.inc_faddr = addr->sin.sin_addr;
8735 break;
8736 #endif
8737 #ifdef INET6
8738 case AF_INET6:
8739 inc.inc_flags |= INC_ISIPV6;
8740 inc.inc6_faddr = addr->sin6.sin6_addr;
8741 break;
8742 #endif
8743 default:
8744 return;
8745 }
8746 tcp_hc_updatemtu(&inc, (u_long)mtu);
8747 }
8748
8749 uint32_t
8750 sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum)
8751 {
8752 struct in_conninfo inc;
8753
8754 memset(&inc, 0, sizeof(struct in_conninfo));
8755 inc.inc_fibnum = fibnum;
8756 switch (addr->sa.sa_family) {
8757 #ifdef INET
8758 case AF_INET:
8759 inc.inc_faddr = addr->sin.sin_addr;
8760 break;
8761 #endif
8762 #ifdef INET6
8763 case AF_INET6:
8764 inc.inc_flags |= INC_ISIPV6;
8765 inc.inc6_faddr = addr->sin6.sin6_addr;
8766 break;
8767 #endif
8768 default:
8769 return (0);
8770 }
8771 return ((uint32_t)tcp_hc_getmtu(&inc));
8772 }
8773 #endif
8774
8775 void
8776 sctp_set_state(struct sctp_tcb *stcb, int new_state)
8777 {
8778 #if defined(KDTRACE_HOOKS)
8779 int old_state = stcb->asoc.state;
8780 #endif
8781
8782 KASSERT((new_state & ~SCTP_STATE_MASK) == 0,
8783 ("sctp_set_state: Can't set substate (new_state = %x)",
8784 new_state));
8785 stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state;
8786 if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) ||
8787 (new_state == SCTP_STATE_SHUTDOWN_SENT) ||
8788 (new_state == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
8789 SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
8790 }
8791 #if defined(KDTRACE_HOOKS)
8792 if (((old_state & SCTP_STATE_MASK) != new_state) &&
8793 !(((old_state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY) &&
8794 (new_state == SCTP_STATE_INUSE))) {
8795 SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
8796 }
8797 #endif
8798 }
8799
8800 void
8801 sctp_add_substate(struct sctp_tcb *stcb, int substate)
8802 {
8803 #if defined(KDTRACE_HOOKS)
8804 int old_state = stcb->asoc.state;
8805 #endif
8806
8807 KASSERT((substate & SCTP_STATE_MASK) == 0,
8808 ("sctp_add_substate: Can't set state (substate = %x)",
8809 substate));
8810 stcb->asoc.state |= substate;
8811 #if defined(KDTRACE_HOOKS)
8812 if (((substate & SCTP_STATE_ABOUT_TO_BE_FREED) &&
8813 ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) ||
8814 ((substate & SCTP_STATE_SHUTDOWN_PENDING) &&
8815 ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) {
8816 SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state);
8817 }
8818 #endif
8819 }
8820
8821