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