Coverage Report

Created: 2025-11-24 06:20

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