Coverage Report

Created: 2026-09-14 06:38

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
16.4k
{
804
16.4k
  uint64_t temp;
805
16.4k
  uint32_t ticks;
806
807
16.4k
  if (hz == 1000) {
808
16.4k
    ticks = msecs;
809
16.4k
  } 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
16.4k
  return (ticks);
818
16.4k
}
819
820
uint32_t
821
sctp_ticks_to_msecs(uint32_t ticks)
822
17.4k
{
823
17.4k
  uint64_t temp;
824
17.4k
  uint32_t msecs;
825
826
17.4k
  if (hz == 1000) {
827
17.4k
    msecs = ticks;
828
17.4k
  } 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
17.4k
  return (msecs);
837
17.4k
}
838
839
uint32_t
840
sctp_secs_to_ticks(uint32_t secs)
841
8.74k
{
842
8.74k
  uint64_t temp;
843
8.74k
  uint32_t ticks;
844
845
8.74k
  temp = (uint64_t)secs * hz;
846
8.74k
  if (temp > UINT32_MAX) {
847
0
    ticks = UINT32_MAX;
848
8.74k
  } else {
849
8.74k
    ticks = (uint32_t)temp;
850
8.74k
  }
851
8.74k
  return (ticks);
852
8.74k
}
853
854
uint32_t
855
sctp_ticks_to_secs(uint32_t ticks)
856
7.68k
{
857
7.68k
  uint64_t temp;
858
7.68k
  uint32_t secs;
859
860
7.68k
  temp = ((uint64_t)ticks + (hz - 1)) / hz;
861
7.68k
  if (temp > UINT32_MAX) {
862
0
    secs = UINT32_MAX;
863
7.68k
  } else {
864
7.68k
    secs = (uint32_t)temp;
865
7.68k
  }
866
7.68k
  return (secs);
867
7.68k
}
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
0
{
877
0
  struct sctp_inpcb *inp;
878
0
  struct sctp_nets *net;
879
880
0
  inp = stcb->sctp_ep;
881
882
0
  sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
883
0
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_12);
884
0
  sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
885
0
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_13);
886
0
  sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
887
0
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_14);
888
0
  sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
889
0
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_15);
890
0
  TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
891
0
    sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
892
0
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_16);
893
0
    sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
894
0
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_17);
895
0
  }
896
0
}
897
898
void
899
sctp_stop_association_timers(struct sctp_tcb *stcb, bool stop_assoc_kill_timer)
900
3.49k
{
901
3.49k
  struct sctp_inpcb *inp;
902
3.49k
  struct sctp_nets *net;
903
904
3.49k
  inp = stcb->sctp_ep;
905
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_RECV, inp, stcb, NULL,
906
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_18);
907
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, inp, stcb, NULL,
908
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_19);
909
3.49k
  if (stop_assoc_kill_timer) {
910
1.74k
    sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
911
1.74k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_20);
912
1.74k
  }
913
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, inp, stcb, NULL,
914
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_21);
915
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL,
916
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_22);
917
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNGUARD, inp, stcb, NULL,
918
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_23);
919
  /* Mobility adaptation */
920
3.49k
  sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, inp, stcb, NULL,
921
3.49k
                  SCTP_FROM_SCTPUTIL + SCTP_LOC_24);
922
3.49k
  TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
923
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
924
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_25);
925
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
926
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_26);
927
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, net,
928
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_27);
929
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net,
930
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_28);
931
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, inp, stcb, net,
932
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_29);
933
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
934
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_30);
935
3.49k
    sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
936
3.49k
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_31);
937
3.49k
  }
938
3.49k
}
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
5.24k
{
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
5.24k
  m->store_at = 0;
1026
5.24k
#if defined(__Userspace__) && defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
1027
110k
  for (int i = 0; i < (int) (sizeof(m->random_store) / sizeof(m->random_store[0])); i++) {
1028
104k
    m->random_store[i] = (uint8_t) rand();
1029
104k
  }
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
5.24k
  m->random_counter++;
1036
5.24k
}
1037
1038
uint32_t
1039
sctp_select_initial_TSN(struct sctp_pcb *inp)
1040
24.4k
{
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
24.4k
  uint32_t x, *xp;
1047
24.4k
  uint8_t *p;
1048
24.4k
  int store_at, new_store;
1049
1050
24.4k
  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
24.4k
 retry:
1058
24.4k
  store_at = inp->store_at;
1059
24.4k
  new_store = store_at + sizeof(uint32_t);
1060
24.4k
  if (new_store >= (SCTP_SIGNATURE_SIZE-3)) {
1061
3.49k
    new_store = 0;
1062
3.49k
  }
1063
24.4k
  if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) {
1064
0
    goto retry;
1065
0
  }
1066
24.4k
  if (new_store == 0) {
1067
    /* Refill the random store */
1068
3.49k
    sctp_fill_random_store(inp);
1069
3.49k
  }
1070
24.4k
  p = &inp->random_store[store_at];
1071
24.4k
  xp = (uint32_t *)p;
1072
24.4k
  x = *xp;
1073
24.4k
  return (x);
1074
24.4k
}
1075
1076
uint32_t
1077
sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check)
1078
5.24k
{
1079
5.24k
  uint32_t x;
1080
5.24k
  struct timeval now;
1081
1082
5.24k
  if (check) {
1083
1.74k
    (void)SCTP_GETTIME_TIMEVAL(&now);
1084
1.74k
  }
1085
5.24k
  for (;;) {
1086
5.24k
    x = sctp_select_initial_TSN(&inp->sctp_ep);
1087
5.24k
    if (x == 0) {
1088
      /* we never use 0 */
1089
0
      continue;
1090
0
    }
1091
5.24k
    if (!check || sctp_is_vtag_good(x, lport, rport, &now)) {
1092
5.24k
      break;
1093
5.24k
    }
1094
5.24k
  }
1095
5.24k
  return (x);
1096
5.24k
}
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
1.74k
{
1146
1.74k
  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
1.74k
  int i;
1159
#if defined(SCTP_DETAILED_STR_STATS)
1160
  int j;
1161
#endif
1162
1163
1.74k
  asoc = &stcb->asoc;
1164
  /* init all variables to a known value. */
1165
1.74k
  SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
1166
1.74k
  asoc->max_burst = inp->sctp_ep.max_burst;
1167
1.74k
  asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
1168
1.74k
  asoc->heart_beat_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
1169
1.74k
  asoc->cookie_life = inp->sctp_ep.def_cookie_life;
1170
1.74k
  asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
1171
1.74k
  asoc->ecn_supported = inp->ecn_supported;
1172
1.74k
  asoc->prsctp_supported = inp->prsctp_supported;
1173
1.74k
  asoc->auth_supported = inp->auth_supported;
1174
1.74k
  asoc->asconf_supported = inp->asconf_supported;
1175
1.74k
  asoc->reconfig_supported = inp->reconfig_supported;
1176
1.74k
  asoc->nrsack_supported = inp->nrsack_supported;
1177
1.74k
  asoc->pktdrop_supported = inp->pktdrop_supported;
1178
1.74k
  asoc->idata_supported = inp->idata_supported;
1179
1.74k
  asoc->rcv_edmid = inp->rcv_edmid;
1180
1.74k
  asoc->snd_edmid = SCTP_EDMID_NONE;
1181
1.74k
  asoc->sctp_cmt_pf = (uint8_t)0;
1182
1.74k
  asoc->sctp_frag_point = inp->sctp_frag_point;
1183
1.74k
  asoc->sctp_features = inp->sctp_features;
1184
1.74k
  asoc->default_dscp = inp->sctp_ep.default_dscp;
1185
1.74k
  asoc->max_cwnd = inp->max_cwnd;
1186
1.74k
#ifdef INET6
1187
1.74k
  if (inp->sctp_ep.default_flowlabel) {
1188
0
    asoc->default_flowlabel = inp->sctp_ep.default_flowlabel;
1189
1.74k
  } else {
1190
1.74k
    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
1.74k
    } else {
1195
1.74k
      asoc->default_flowlabel = 0;
1196
1.74k
    }
1197
1.74k
  }
1198
1.74k
#endif
1199
1.74k
  asoc->sb_send_resv = 0;
1200
1.74k
  if (override_tag) {
1201
0
    asoc->my_vtag = override_tag;
1202
1.74k
  } else {
1203
1.74k
    asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport,  1);
1204
1.74k
  }
1205
  /* Get the nonce tags */
1206
1.74k
  asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1207
1.74k
  asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0);
1208
1.74k
  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
1.74k
  asoc->refcnt = 0;
1222
1.74k
  asoc->assoc_up_sent = 0;
1223
1.74k
  if (override_tag) {
1224
0
    asoc->init_seq_number = initial_tsn;
1225
1.74k
  } else {
1226
1.74k
    asoc->init_seq_number = sctp_select_initial_TSN(&inp->sctp_ep);
1227
1.74k
  }
1228
1.74k
  asoc->asconf_seq_out = asoc->init_seq_number;
1229
1.74k
  asoc->str_reset_seq_out = asoc->init_seq_number;
1230
1.74k
  asoc->sending_seq = asoc->init_seq_number;
1231
1.74k
  asoc->asconf_seq_out_acked = asoc->init_seq_number - 1;
1232
  /* we are optimistic here */
1233
1.74k
  asoc->peer_supports_nat = 0;
1234
1.74k
  asoc->sent_queue_retran_cnt = 0;
1235
1236
  /* for CMT */
1237
1.74k
  asoc->last_net_cmt_send_started = NULL;
1238
1239
1.74k
  asoc->last_acked_seq = asoc->init_seq_number - 1;
1240
1.74k
  asoc->advanced_peer_ack_point = asoc->init_seq_number - 1;
1241
1.74k
  asoc->asconf_seq_in = asoc->init_seq_number - 1;
1242
1243
  /* here we are different, we hold the next one we expect */
1244
1.74k
  asoc->str_reset_seq_in = asoc->init_seq_number;
1245
1246
1.74k
  asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max;
1247
1.74k
  asoc->initial_rto = inp->sctp_ep.initial_rto;
1248
1249
1.74k
  asoc->default_mtu = inp->sctp_ep.default_mtu;
1250
1.74k
  asoc->max_init_times = inp->sctp_ep.max_init_times;
1251
1.74k
  asoc->max_send_times = inp->sctp_ep.max_send_times;
1252
1.74k
  asoc->def_net_failure = inp->sctp_ep.def_net_failure;
1253
1.74k
  asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold;
1254
1.74k
  asoc->free_chunk_cnt = 0;
1255
1256
1.74k
  asoc->iam_blocking = 0;
1257
1.74k
  asoc->context = inp->sctp_context;
1258
1.74k
  asoc->local_strreset_support = inp->local_strreset_support;
1259
1.74k
  asoc->def_send = inp->def_send;
1260
1.74k
  asoc->delayed_ack = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1261
1.74k
  asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
1262
1.74k
  asoc->pr_sctp_cnt = 0;
1263
1.74k
  asoc->total_output_queue_size = 0;
1264
1265
1.74k
  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
1.74k
  } else {
1276
1.74k
    asoc->scope.ipv6_addr_legal = 0;
1277
1.74k
#if defined(__Userspace__)
1278
1.74k
    if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
1279
1.74k
      asoc->scope.conn_addr_legal = 1;
1280
1.74k
      asoc->scope.ipv4_addr_legal = 0;
1281
1.74k
    } 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
1.74k
  }
1289
1290
1.74k
  asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND);
1291
1.74k
  asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket);
1292
1293
1.74k
  asoc->smallest_mtu = 0;
1294
1.74k
  asoc->minrto = inp->sctp_ep.sctp_minrto;
1295
1.74k
  asoc->maxrto = inp->sctp_ep.sctp_maxrto;
1296
1297
1.74k
  asoc->stream_locked_on = 0;
1298
1.74k
  asoc->ecn_echo_cnt_onq = 0;
1299
1.74k
  asoc->stream_locked = 0;
1300
1301
1.74k
  asoc->send_sack = 1;
1302
1303
1.74k
  LIST_INIT(&asoc->sctp_restricted_addrs);
1304
1305
1.74k
  TAILQ_INIT(&asoc->nets);
1306
1.74k
  TAILQ_INIT(&asoc->pending_reply_queue);
1307
1.74k
  TAILQ_INIT(&asoc->asconf_ack_sent);
1308
  /* Setup to fill the hb random cache at first HB */
1309
1.74k
  asoc->hb_random_idx = 4;
1310
1311
1.74k
  asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time;
1312
1313
1.74k
  stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module;
1314
1.74k
  stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module];
1315
1316
1.74k
  stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module;
1317
1.74k
  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
1.74k
  asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
1324
1.74k
      o_strms;
1325
1.74k
  SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
1326
1.74k
        asoc->streamoutcnt * sizeof(struct sctp_stream_out),
1327
1.74k
        SCTP_M_STRMO);
1328
1.74k
  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
1.74k
  SCTP_TCB_LOCK(stcb);
1334
451k
  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
449k
    TAILQ_INIT(&asoc->strmout[i].outqueue);
1344
449k
    asoc->ss_functions.sctp_ss_init_stream(stcb, &asoc->strmout[i], NULL);
1345
449k
    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
449k
    asoc->strmout[i].abandoned_sent[0] = 0;
1353
449k
    asoc->strmout[i].abandoned_unsent[0] = 0;
1354
449k
#endif
1355
449k
    asoc->strmout[i].next_mid_ordered = 0;
1356
449k
    asoc->strmout[i].next_mid_unordered = 0;
1357
449k
    asoc->strmout[i].sid = i;
1358
449k
    asoc->strmout[i].last_msg_incomplete = 0;
1359
449k
    asoc->strmout[i].state = SCTP_STREAM_OPENING;
1360
449k
  }
1361
1.74k
  asoc->ss_functions.sctp_ss_init(stcb, asoc);
1362
1.74k
  SCTP_TCB_UNLOCK(stcb);
1363
1364
  /* Now the mapping array */
1365
1.74k
  asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
1366
1.74k
  SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1367
1.74k
        SCTP_M_MAP);
1368
1.74k
  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
1.74k
  memset(asoc->mapping_array, 0, asoc->mapping_array_size);
1374
1.74k
  SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
1375
1.74k
      SCTP_M_MAP);
1376
1.74k
  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
1.74k
  memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
1383
1384
  /* Now the init of the other outqueues */
1385
1.74k
  TAILQ_INIT(&asoc->free_chunks);
1386
1.74k
  TAILQ_INIT(&asoc->control_send_queue);
1387
1.74k
  TAILQ_INIT(&asoc->asconf_send_queue);
1388
1.74k
  TAILQ_INIT(&asoc->send_queue);
1389
1.74k
  TAILQ_INIT(&asoc->sent_queue);
1390
1.74k
  TAILQ_INIT(&asoc->resetHead);
1391
1.74k
  asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome;
1392
1.74k
  TAILQ_INIT(&asoc->asconf_queue);
1393
  /* authentication fields */
1394
1.74k
  asoc->authinfo.random = NULL;
1395
1.74k
  asoc->authinfo.active_keyid = 0;
1396
1.74k
  asoc->authinfo.assoc_key = NULL;
1397
1.74k
  asoc->authinfo.assoc_keyid = 0;
1398
1.74k
  asoc->authinfo.recv_key = NULL;
1399
1.74k
  asoc->authinfo.recv_keyid = 0;
1400
1.74k
  LIST_INIT(&asoc->shared_keys);
1401
1.74k
  asoc->marked_retrans = 0;
1402
1.74k
  asoc->port = inp->sctp_ep.port;
1403
1.74k
  asoc->timoinit = 0;
1404
1.74k
  asoc->timodata = 0;
1405
1.74k
  asoc->timosack = 0;
1406
1.74k
  asoc->timoshutdown = 0;
1407
1.74k
  asoc->timoheartbeat = 0;
1408
1.74k
  asoc->timocookie = 0;
1409
1.74k
  asoc->timoshutdownack = 0;
1410
1.74k
  (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
1411
1.74k
  asoc->discontinuity_time = asoc->start_time;
1412
8.74k
  for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
1413
6.99k
    asoc->abandoned_unsent[i] = 0;
1414
6.99k
    asoc->abandoned_sent[i] = 0;
1415
6.99k
  }
1416
  /* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
1417
   * the association is freed.
1418
   */
1419
1.74k
  return (0);
1420
1.74k
}
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
0
{
1460
  /* mapping array needs to grow */
1461
0
  uint8_t *new_array1, *new_array2;
1462
0
  uint32_t new_size;
1463
1464
0
  new_size = asoc->mapping_array_size + ((needed+7)/8 + SCTP_MAPPING_ARRAY_INCR);
1465
0
  SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
1466
0
  SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
1467
0
  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
0
  memset(new_array1, 0, new_size);
1479
0
  memset(new_array2, 0, new_size);
1480
0
  memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
1481
0
  memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
1482
0
  SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1483
0
  SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
1484
0
  asoc->mapping_array = new_array1;
1485
0
  asoc->nr_mapping_array = new_array2;
1486
0
  asoc->mapping_array_size = new_size;
1487
0
  return (0);
1488
0
}
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
0
{
1780
#if defined(__FreeBSD__) && !defined(__Userspace__)
1781
  struct epoch_tracker et;
1782
#endif
1783
0
  struct timeval tv;
1784
0
  struct sctp_inpcb *inp;
1785
0
  struct sctp_tcb *stcb;
1786
0
  struct sctp_nets *net;
1787
0
  struct sctp_timer *tmr;
1788
0
  struct mbuf *op_err;
1789
#if defined(__APPLE__) && !defined(__Userspace__)
1790
  struct socket *so;
1791
#endif
1792
0
#if defined(__Userspace__)
1793
0
  struct socket *upcall_socket = NULL;
1794
0
#endif
1795
0
  int type;
1796
0
  int i, secret;
1797
0
  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
0
  tmr = (struct sctp_timer *)t;
1805
0
  inp = (struct sctp_inpcb *)tmr->ep;
1806
0
  stcb = (struct sctp_tcb *)tmr->tcb;
1807
0
  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
0
  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
0
  KASSERT(tmr->self == NULL || tmr->self == tmr,
1821
0
          ("sctp_timeout_handler: tmr->self corrupted"));
1822
0
  KASSERT(SCTP_IS_TIMER_TYPE_VALID(tmr->type),
1823
0
          ("sctp_timeout_handler: invalid timer type %d", tmr->type));
1824
0
  type = tmr->type;
1825
0
  KASSERT(stcb == NULL || stcb->sctp_ep == inp,
1826
0
          ("sctp_timeout_handler of type %d: inp = %p, stcb->sctp_ep %p",
1827
0
           type, stcb, stcb->sctp_ep));
1828
0
  tmr->stopped_from = 0xa001;
1829
0
  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
0
  tmr->stopped_from = 0xa002;
1836
0
  SCTPDBG(SCTP_DEBUG_TIMER2, "Timer type %d goes off.\n", type);
1837
0
  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
0
  tmr->stopped_from = 0xa003;
1845
0
  if (stcb) {
1846
0
    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
0
    atomic_subtract_int(&stcb->asoc.refcnt, 1);
1853
0
    released_asoc_reference = true;
1854
0
    if ((type != SCTP_TIMER_TYPE_ASOCKILL) &&
1855
0
        ((stcb->asoc.state == SCTP_STATE_EMPTY) ||
1856
0
         (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) {
1857
0
      SCTPDBG(SCTP_DEBUG_TIMER2,
1858
0
              "Timer type %d handler exiting due to CLOSED association.\n",
1859
0
              type);
1860
0
      goto out;
1861
0
    }
1862
0
  } else if (inp != NULL) {
1863
0
    SCTP_INP_WLOCK(inp);
1864
0
  } else {
1865
0
    SCTP_WQ_ADDR_LOCK();
1866
0
  }
1867
1868
  /* Record in stopped_from which timeout occurred. */
1869
0
  tmr->stopped_from = type;
1870
  /* mark as being serviced now */
1871
0
  if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
1872
    /*
1873
     * Callout has been rescheduled.
1874
     */
1875
0
    goto out;
1876
0
  }
1877
0
  if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
1878
    /*
1879
     * Not active, so no action.
1880
     */
1881
0
    goto out;
1882
0
  }
1883
0
  SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);
1884
1885
0
#if defined(__Userspace__)
1886
0
  if ((stcb != NULL) &&
1887
0
      ((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
0
#endif
1895
  /* call the handler for the appropriate timer type */
1896
0
  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
0
  case SCTP_TIMER_TYPE_INPKILL:
2114
0
    KASSERT(inp != NULL && stcb == NULL && net == NULL,
2115
0
            ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2116
0
             type, inp, stcb, net));
2117
0
    SCTP_STAT_INCR(sctps_timoinpkill);
2118
    /*
2119
     * special case, take away our increment since WE are the
2120
     * killer
2121
     */
2122
0
    sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL,
2123
0
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
2124
#if defined(__APPLE__) && !defined(__Userspace__)
2125
    SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
2126
#endif
2127
0
    SCTP_INP_DECR_REF(inp);
2128
0
    SCTP_INP_WUNLOCK(inp);
2129
0
    sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
2130
0
                    SCTP_CALLED_FROM_INPKILL_TIMER);
2131
#if defined(__APPLE__) && !defined(__Userspace__)
2132
    SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1);
2133
#endif
2134
0
    inp = NULL;
2135
0
    goto out_decr;
2136
0
  case SCTP_TIMER_TYPE_ASOCKILL:
2137
0
    KASSERT(inp != NULL && stcb != NULL && net == NULL,
2138
0
            ("timeout of type %d: inp = %p, stcb = %p, net = %p",
2139
0
             type, inp, stcb, net));
2140
0
    SCTP_STAT_INCR(sctps_timoassockill);
2141
    /* Can we free it yet? */
2142
0
    sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
2143
0
                    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
0
    (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
2153
0
                          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
0
    stcb = NULL;
2162
0
    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
0
  }
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
0
out:
2201
0
  if (stcb != NULL) {
2202
0
    SCTP_TCB_UNLOCK(stcb);
2203
0
  } else if (inp != NULL) {
2204
0
    SCTP_INP_WUNLOCK(inp);
2205
0
  } else {
2206
0
    SCTP_WQ_ADDR_UNLOCK();
2207
0
  }
2208
2209
0
out_decr:
2210
0
#if defined(__Userspace__)
2211
0
  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
0
#endif
2221
  /* These reference counts were incremented in sctp_timer_start(). */
2222
0
  if (inp != NULL) {
2223
0
    SCTP_INP_DECR_REF(inp);
2224
0
  }
2225
0
  if ((stcb != NULL) && !released_asoc_reference) {
2226
0
    atomic_subtract_int(&stcb->asoc.refcnt, 1);
2227
0
  }
2228
0
  if (net != NULL) {
2229
0
    sctp_free_remote_addr(net);
2230
0
  }
2231
0
  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
0
}
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
13.7k
{
2269
13.7k
  struct sctp_timer *tmr;
2270
13.7k
  uint32_t to_ticks;
2271
13.7k
  uint32_t rndval, jitter;
2272
2273
13.7k
  KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2274
13.7k
          ("sctp_timer_start of type %d: inp = %p, stcb->sctp_ep %p",
2275
13.7k
           t_type, stcb, stcb->sctp_ep));
2276
13.7k
  tmr = NULL;
2277
13.7k
  if (stcb != NULL) {
2278
12.0k
    SCTP_TCB_LOCK_ASSERT(stcb);
2279
12.0k
  } else if (inp != NULL) {
2280
1.74k
    SCTP_INP_WLOCK_ASSERT(inp);
2281
1.74k
  } else {
2282
0
    SCTP_WQ_ADDR_LOCK_ASSERT();
2283
0
  }
2284
13.7k
  if (stcb != NULL) {
2285
    /* Don't restart timer on association that's about to be killed. */
2286
12.0k
    if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) &&
2287
0
        (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
12.0k
    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
12.0k
  }
2301
13.7k
  switch (t_type) {
2302
1.55k
  case SCTP_TIMER_TYPE_SEND:
2303
    /* Here we use the RTO timer. */
2304
1.55k
    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
1.55k
    tmr = &net->rxt_timer;
2313
1.55k
    if (net->RTO == 0) {
2314
0
      to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2315
1.55k
    } else {
2316
1.55k
      to_ticks = sctp_msecs_to_ticks(net->RTO);
2317
1.55k
    }
2318
1.55k
    break;
2319
1.74k
  case SCTP_TIMER_TYPE_INIT:
2320
    /*
2321
     * Here we use the INIT timer default usually about 1
2322
     * second.
2323
     */
2324
1.74k
    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
1.74k
    tmr = &net->rxt_timer;
2333
1.74k
    if (net->RTO == 0) {
2334
1.74k
      to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2335
1.74k
    } else {
2336
0
      to_ticks = sctp_msecs_to_ticks(net->RTO);
2337
0
    }
2338
1.74k
    break;
2339
0
  case SCTP_TIMER_TYPE_RECV:
2340
    /*
2341
     * Here we use the Delayed-Ack timer value from the inp,
2342
     * usually about 200ms.
2343
     */
2344
0
    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
0
    tmr = &stcb->asoc.dack_timer;
2353
0
    to_ticks = sctp_msecs_to_ticks(stcb->asoc.delayed_ack);
2354
0
    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
3.49k
  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
3.49k
    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
3.49k
    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
3.49k
    tmr = &net->hb_timer;
2394
3.49k
    if (net->RTO == 0) {
2395
0
      to_ticks = stcb->asoc.initial_rto;
2396
3.49k
    } else {
2397
3.49k
      to_ticks = net->RTO;
2398
3.49k
    }
2399
3.49k
    if (!((net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
2400
0
          (net->dest_state & SCTP_ADDR_REACHABLE)) &&
2401
3.49k
        ((net->dest_state & SCTP_ADDR_PF) == 0)) {
2402
3.49k
      if (to_ticks > 1) {
2403
3.49k
        rndval = sctp_select_initial_TSN(&inp->sctp_ep);
2404
3.49k
        jitter = rndval % to_ticks;
2405
3.49k
        to_ticks >>= 1;
2406
3.49k
        if (jitter < (UINT32_MAX - to_ticks)) {
2407
3.49k
          to_ticks += jitter;
2408
3.49k
        } else {
2409
0
          to_ticks = UINT32_MAX;
2410
0
        }
2411
3.49k
      }
2412
3.49k
      if (net->heart_beat_delay < (UINT32_MAX - to_ticks)) {
2413
3.49k
        to_ticks += net->heart_beat_delay;
2414
3.49k
      } else {
2415
0
        to_ticks = UINT32_MAX;
2416
0
      }
2417
3.49k
    }
2418
    /*
2419
     * Now we must convert the to_ticks that are now in
2420
     * ms to ticks.
2421
     */
2422
3.49k
    to_ticks = sctp_msecs_to_ticks(to_ticks);
2423
3.49k
    break;
2424
3.49k
  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
3.49k
    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
3.49k
    tmr = &net->rxt_timer;
2439
3.49k
    if (net->RTO == 0) {
2440
0
      to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2441
3.49k
    } else {
2442
3.49k
      to_ticks = sctp_msecs_to_ticks(net->RTO);
2443
3.49k
    }
2444
3.49k
    break;
2445
1.74k
  case SCTP_TIMER_TYPE_NEWCOOKIE:
2446
    /*
2447
     * Nothing needed but the endpoint here usually about 60
2448
     * minutes.
2449
     */
2450
1.74k
    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
1.74k
    tmr = &inp->sctp_ep.signature_change;
2459
1.74k
    to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
2460
1.74k
    break;
2461
1.74k
  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
1.74k
    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
1.74k
    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
1.74k
    tmr = &net->pmtu_timer;
2481
1.74k
    to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
2482
1.74k
    break;
2483
0
  case SCTP_TIMER_TYPE_SHUTDOWNACK:
2484
    /* Here we use the RTO of the destination. */
2485
0
    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
0
    tmr = &net->rxt_timer;
2494
0
    if (net->RTO == 0) {
2495
0
      to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2496
0
    } else {
2497
0
      to_ticks = sctp_msecs_to_ticks(net->RTO);
2498
0
    }
2499
0
    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
0
  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
0
    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
0
    tmr = &stcb->asoc.strreset_timer;
2570
0
    if (net->RTO == 0) {
2571
0
      to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
2572
0
    } else {
2573
0
      to_ticks = sctp_msecs_to_ticks(net->RTO);
2574
0
    }
2575
0
    break;
2576
0
  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
0
    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
0
    tmr = &inp->sctp_ep.signature_change;
2591
0
    to_ticks = sctp_msecs_to_ticks(SCTP_INP_KILL_TIMEOUT);
2592
0
    break;
2593
0
  case SCTP_TIMER_TYPE_ASOCKILL:
2594
0
    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
0
    tmr = &stcb->asoc.strreset_timer;
2603
0
    to_ticks = sctp_msecs_to_ticks(SCTP_ASOC_KILL_TIMEOUT);
2604
0
    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
13.7k
  }
2637
13.7k
  KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2638
13.7k
  KASSERT(to_ticks > 0, ("to_ticks == 0 for timer type %d", t_type));
2639
13.7k
  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
3.49k
    SCTPDBG(SCTP_DEBUG_TIMER2,
2645
3.49k
            "Timer type %d already running: inp=%p, stcb=%p, net=%p.\n",
2646
3.49k
             t_type, inp, stcb, net);
2647
3.49k
    return;
2648
3.49k
  }
2649
  /* At this point we can proceed. */
2650
10.3k
  if (t_type == SCTP_TIMER_TYPE_SEND) {
2651
1.55k
    stcb->asoc.num_send_timers_up++;
2652
1.55k
  }
2653
10.3k
  tmr->stopped_from = 0;
2654
10.3k
  tmr->type = t_type;
2655
10.3k
  tmr->ep = (void *)inp;
2656
10.3k
  tmr->tcb = (void *)stcb;
2657
10.3k
  if (t_type == SCTP_TIMER_TYPE_STRRESET) {
2658
0
    tmr->net = NULL;
2659
10.3k
  } else {
2660
10.3k
    tmr->net = (void *)net;
2661
10.3k
  }
2662
10.3k
  tmr->self = (void *)tmr;
2663
#if defined(__FreeBSD__) && !defined(__Userspace__)
2664
  tmr->vnet = (void *)curvnet;
2665
#endif
2666
10.3k
  tmr->ticks = sctp_get_tick_count();
2667
10.3k
  if (SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr) == 0) {
2668
10.3k
    SCTPDBG(SCTP_DEBUG_TIMER2,
2669
10.3k
            "Timer type %d started: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2670
10.3k
             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
10.3k
    if (tmr->ep != NULL) {
2676
10.3k
      SCTP_INP_INCR_REF(inp);
2677
10.3k
    }
2678
10.3k
    if (tmr->tcb != NULL) {
2679
8.55k
      atomic_add_int(&stcb->asoc.refcnt, 1);
2680
8.55k
    }
2681
10.3k
    if (tmr->net != NULL) {
2682
8.55k
      atomic_add_int(&net->ref_count, 1);
2683
8.55k
    }
2684
10.3k
  } else {
2685
    /*
2686
     * This should not happen, since we checked for pending
2687
     * above.
2688
     */
2689
0
    SCTPDBG(SCTP_DEBUG_TIMER2,
2690
0
            "Timer type %d restarted: ticks=%u, inp=%p, stcb=%p, net=%p.\n",
2691
0
             t_type, to_ticks, inp, stcb, net);
2692
0
  }
2693
10.3k
  return;
2694
13.7k
}
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
52.4k
{
2727
52.4k
  struct sctp_timer *tmr;
2728
2729
52.4k
  KASSERT(stcb == NULL || stcb->sctp_ep == inp,
2730
52.4k
          ("sctp_timer_stop of type %d: inp = %p, stcb->sctp_ep %p",
2731
52.4k
           t_type, stcb, stcb->sctp_ep));
2732
52.4k
  if (stcb != NULL) {
2733
50.7k
    SCTP_TCB_LOCK_ASSERT(stcb);
2734
50.7k
  } else if (inp != NULL) {
2735
1.74k
    SCTP_INP_WLOCK_ASSERT(inp);
2736
1.74k
  } else {
2737
0
    SCTP_WQ_ADDR_LOCK_ASSERT();
2738
0
  }
2739
52.4k
  tmr = NULL;
2740
52.4k
  switch (t_type) {
2741
3.49k
  case SCTP_TIMER_TYPE_SEND:
2742
3.49k
    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
3.49k
    tmr = &net->rxt_timer;
2751
3.49k
    break;
2752
5.24k
  case SCTP_TIMER_TYPE_INIT:
2753
5.24k
    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
5.24k
    tmr = &net->rxt_timer;
2762
5.24k
    break;
2763
3.49k
  case SCTP_TIMER_TYPE_RECV:
2764
3.49k
    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
3.49k
    tmr = &stcb->asoc.dack_timer;
2773
3.49k
    break;
2774
3.49k
  case SCTP_TIMER_TYPE_SHUTDOWN:
2775
3.49k
    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
3.49k
    tmr = &net->rxt_timer;
2784
3.49k
    break;
2785
3.49k
  case SCTP_TIMER_TYPE_HEARTBEAT:
2786
3.49k
    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
3.49k
    tmr = &net->hb_timer;
2795
3.49k
    break;
2796
5.24k
  case SCTP_TIMER_TYPE_COOKIE:
2797
5.24k
    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
5.24k
    tmr = &net->rxt_timer;
2806
5.24k
    break;
2807
1.74k
  case SCTP_TIMER_TYPE_NEWCOOKIE:
2808
1.74k
    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
1.74k
    tmr = &inp->sctp_ep.signature_change;
2817
1.74k
    break;
2818
3.49k
  case SCTP_TIMER_TYPE_PATHMTURAISE:
2819
3.49k
    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
3.49k
    tmr = &net->pmtu_timer;
2828
3.49k
    break;
2829
3.49k
  case SCTP_TIMER_TYPE_SHUTDOWNACK:
2830
3.49k
    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
3.49k
    tmr = &net->rxt_timer;
2839
3.49k
    break;
2840
3.49k
  case SCTP_TIMER_TYPE_ASCONF:
2841
3.49k
    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
3.49k
    tmr = &stcb->asoc.asconf_timer;
2850
3.49k
    break;
2851
3.49k
  case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
2852
3.49k
    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
3.49k
    tmr = &stcb->asoc.shut_guard_timer;
2861
3.49k
    break;
2862
3.49k
  case SCTP_TIMER_TYPE_AUTOCLOSE:
2863
3.49k
    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
3.49k
    tmr = &stcb->asoc.autoclose_timer;
2872
3.49k
    break;
2873
3.49k
  case SCTP_TIMER_TYPE_STRRESET:
2874
3.49k
    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
3.49k
    tmr = &stcb->asoc.strreset_timer;
2883
3.49k
    break;
2884
0
  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
0
    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
0
    tmr = &inp->sctp_ep.signature_change;
2899
0
    break;
2900
1.74k
  case SCTP_TIMER_TYPE_ASOCKILL:
2901
1.74k
    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
1.74k
    tmr = &stcb->asoc.strreset_timer;
2910
1.74k
    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
3.49k
  case SCTP_TIMER_TYPE_PRIM_DELETED:
2923
3.49k
    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
3.49k
    tmr = &stcb->asoc.delete_prim_timer;
2932
3.49k
    break;
2933
0
  default:
2934
0
#ifdef INVARIANTS
2935
0
    panic("Unknown timer type %d", t_type);
2936
#else
2937
    return;
2938
#endif
2939
52.4k
  }
2940
52.4k
  KASSERT(tmr != NULL, ("tmr is NULL for timer type %d", t_type));
2941
52.4k
  if ((tmr->type != SCTP_TIMER_TYPE_NONE) &&
2942
29.7k
      (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
13.9k
    SCTPDBG(SCTP_DEBUG_TIMER2,
2950
13.9k
            "Shared timer type %d not running: inp=%p, stcb=%p, net=%p.\n",
2951
13.9k
             t_type, inp, stcb, net);
2952
13.9k
    return;
2953
13.9k
  }
2954
38.4k
  if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) {
2955
3.11k
    stcb->asoc.num_send_timers_up--;
2956
3.11k
    if (stcb->asoc.num_send_timers_up < 0) {
2957
1.55k
      stcb->asoc.num_send_timers_up = 0;
2958
1.55k
    }
2959
3.11k
  }
2960
38.4k
  tmr->self = NULL;
2961
38.4k
  tmr->stopped_from = from;
2962
38.4k
  if (SCTP_OS_TIMER_STOP(&tmr->timer) == 1) {
2963
10.3k
    KASSERT(tmr->ep == inp,
2964
10.3k
            ("sctp_timer_stop of type %d: inp = %p, tmr->inp = %p",
2965
10.3k
             t_type, inp, tmr->ep));
2966
10.3k
    KASSERT(tmr->tcb == stcb,
2967
10.3k
            ("sctp_timer_stop of type %d: stcb = %p, tmr->stcb = %p",
2968
10.3k
             t_type, stcb, tmr->tcb));
2969
10.3k
    KASSERT(((t_type == SCTP_TIMER_TYPE_ASCONF) && (tmr->net != NULL)) ||
2970
10.3k
            ((t_type != SCTP_TIMER_TYPE_ASCONF) && (tmr->net == net)),
2971
10.3k
            ("sctp_timer_stop of type %d: net = %p, tmr->net = %p",
2972
10.3k
             t_type, net, tmr->net));
2973
10.3k
    SCTPDBG(SCTP_DEBUG_TIMER2,
2974
10.3k
            "Timer type %d stopped: inp=%p, stcb=%p, net=%p.\n",
2975
10.3k
            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
10.3k
    if (tmr->ep != NULL) {
2981
10.3k
      tmr->ep = NULL;
2982
10.3k
      SCTP_INP_DECR_REF(inp);
2983
10.3k
    }
2984
10.3k
    if (tmr->tcb != NULL) {
2985
8.55k
      tmr->tcb = NULL;
2986
8.55k
      atomic_subtract_int(&stcb->asoc.refcnt, 1);
2987
8.55k
    }
2988
10.3k
    if (tmr->net != NULL) {
2989
8.55k
      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
8.55k
      tmr_net = tmr->net;
2996
8.55k
      tmr->net = NULL;
2997
8.55k
      sctp_free_remote_addr(tmr_net);
2998
8.55k
    }
2999
28.1k
  } else {
3000
28.1k
    SCTPDBG(SCTP_DEBUG_TIMER2,
3001
28.1k
            "Timer type %d not stopped: inp=%p, stcb=%p, net=%p.\n",
3002
28.1k
             t_type, inp, stcb, net);
3003
28.1k
  }
3004
38.4k
  return;
3005
38.4k
}
3006
3007
uint32_t
3008
sctp_calculate_len(struct mbuf *m)
3009
9.91k
{
3010
9.91k
  struct mbuf *at;
3011
9.91k
  uint32_t tlen;
3012
3013
9.91k
  tlen = 0;
3014
37.7k
  for (at = m; at != NULL; at = SCTP_BUF_NEXT(at)) {
3015
27.7k
    tlen += SCTP_BUF_LEN(at);
3016
27.7k
  }
3017
9.91k
  return (tlen);
3018
9.91k
}
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
3.49k
{
3034
3.49k
  struct timeval now;
3035
3.49k
  uint64_t rtt_us;  /* RTT in us */
3036
3.49k
  int32_t rtt;    /* RTT in ms */
3037
3.49k
  uint32_t new_rto;
3038
3.49k
  int first_measure = 0;
3039
3040
  /************************/
3041
  /* 1. calculate new RTT */
3042
  /************************/
3043
  /* get the current time */
3044
3.49k
  if (stcb->asoc.use_precise_time) {
3045
0
    (void)SCTP_GETPTIME_TIMEVAL(&now);
3046
3.49k
  } else {
3047
3.49k
    (void)SCTP_GETTIME_TIMEVAL(&now);
3048
3.49k
  }
3049
3.49k
  if ((old->tv_sec > now.tv_sec) ||
3050
3.49k
      ((old->tv_sec == now.tv_sec) && (old->tv_usec > now.tv_usec))) {
3051
    /* The starting point is in the future. */
3052
0
    return (0);
3053
0
  }
3054
3.49k
  timevalsub(&now, old);
3055
3.49k
  rtt_us = (uint64_t)1000000 * (uint64_t)now.tv_sec + (uint64_t)now.tv_usec;
3056
3.49k
  if (rtt_us > SCTP_RTO_UPPER_BOUND * 1000) {
3057
    /* The RTT is larger than a sane value. */
3058
0
    return (0);
3059
0
  }
3060
  /* store the current RTT in us */
3061
3.49k
  net->rtt = rtt_us;
3062
  /* compute rtt in ms */
3063
3.49k
  rtt = (int32_t)(net->rtt / 1000);
3064
3.49k
  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
3.49k
  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
3.49k
  if (net->RTO_measured) {
3093
1.74k
    rtt -= (net->lastsa >> SCTP_RTT_SHIFT);
3094
1.74k
    net->lastsa += rtt;
3095
1.74k
    if (rtt < 0) {
3096
0
      rtt = -rtt;
3097
0
    }
3098
1.74k
    rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT);
3099
1.74k
    net->lastsv += rtt;
3100
1.74k
    if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3101
0
      rto_logging(net, SCTP_LOG_RTTVAR);
3102
0
    }
3103
1.74k
  } else {
3104
    /* First RTO measurement */
3105
1.74k
    net->RTO_measured = 1;
3106
1.74k
    first_measure = 1;
3107
1.74k
    net->lastsa = rtt << SCTP_RTT_SHIFT;
3108
1.74k
    net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT;
3109
1.74k
    if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) {
3110
0
      rto_logging(net, SCTP_LOG_INITIAL_RTT);
3111
0
    }
3112
1.74k
  }
3113
3.49k
  if (net->lastsv == 0) {
3114
1.74k
    net->lastsv = SCTP_CLOCK_GRANULARITY;
3115
1.74k
  }
3116
3.49k
  new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv;
3117
3.49k
  if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
3118
0
      (stcb->asoc.sat_network_lockout == 0)) {
3119
0
    stcb->asoc.sat_network = 1;
3120
3.49k
  } 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
3.49k
  if (new_rto < stcb->asoc.minrto) {
3126
3.49k
    new_rto = stcb->asoc.minrto;
3127
3.49k
  }
3128
3.49k
  if (new_rto > stcb->asoc.maxrto) {
3129
0
    new_rto = stcb->asoc.maxrto;
3130
0
  }
3131
3.49k
  net->RTO = new_rto;
3132
3.49k
  return (1);
3133
3.49k
}
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
93.3k
{
3144
93.3k
  uint32_t count;
3145
93.3k
  uint8_t *ptr;
3146
3147
93.3k
  ptr = in_ptr;
3148
93.3k
  if ((off < 0) || (len <= 0))
3149
0
    return (NULL);
3150
3151
  /* find the desired start location */
3152
98.5k
  while ((m != NULL) && (off > 0)) {
3153
82.8k
    if (off < SCTP_BUF_LEN(m))
3154
77.6k
      break;
3155
5.24k
    off -= SCTP_BUF_LEN(m);
3156
5.24k
    m = SCTP_BUF_NEXT(m);
3157
5.24k
  }
3158
93.3k
  if (m == NULL)
3159
1.74k
    return (NULL);
3160
3161
  /* is the current mbuf large enough (eg. contiguous)? */
3162
91.5k
  if ((SCTP_BUF_LEN(m) - off) >= len) {
3163
68.7k
    return (mtod(m, caddr_t) + off);
3164
68.7k
  } else {
3165
    /* else, it spans more than one mbuf, so save a temp copy... */
3166
70.5k
    while ((m != NULL) && (len > 0)) {
3167
47.6k
      count = min(SCTP_BUF_LEN(m) - off, len);
3168
47.6k
      memcpy(ptr, mtod(m, caddr_t) + off, count);
3169
47.6k
      len -= count;
3170
47.6k
      ptr += count;
3171
47.6k
      off = 0;
3172
47.6k
      m = SCTP_BUF_NEXT(m);
3173
47.6k
    }
3174
22.8k
    if ((m == NULL) && (len > 0))
3175
0
      return (NULL);
3176
22.8k
    else
3177
22.8k
      return ((caddr_t)in_ptr);
3178
22.8k
  }
3179
91.5k
}
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
52.4k
{
3187
  /* This just provides a typed signature to Peter's Pull routine */
3188
52.4k
  return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
3189
52.4k
      (uint8_t *) pull));
3190
52.4k
}
3191
3192
struct mbuf *
3193
sctp_add_pad_tombuf(struct mbuf *m, int padlen)
3194
1.74k
{
3195
1.74k
  struct mbuf *m_last;
3196
1.74k
  caddr_t dp;
3197
3198
1.74k
  if (padlen > 3) {
3199
0
    return (NULL);
3200
0
  }
3201
1.74k
  if (padlen <= M_TRAILINGSPACE(m)) {
3202
    /*
3203
     * The easy way. We hope the majority of the time we hit
3204
     * here :)
3205
     */
3206
1.74k
    m_last = m;
3207
1.74k
  } else {
3208
    /* Hard way we must grow the mbuf chain */
3209
0
    m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
3210
0
    if (m_last == NULL) {
3211
0
      return (NULL);
3212
0
    }
3213
0
    SCTP_BUF_LEN(m_last) = 0;
3214
0
    SCTP_BUF_NEXT(m_last) = NULL;
3215
0
    SCTP_BUF_NEXT(m) = m_last;
3216
0
  }
3217
1.74k
  dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
3218
1.74k
  SCTP_BUF_LEN(m_last) += padlen;
3219
1.74k
  memset(dp, 0, padlen);
3220
1.74k
  return (m_last);
3221
1.74k
}
3222
3223
struct mbuf *
3224
sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
3225
0
{
3226
  /* find the last mbuf in chain and pad it */
3227
0
  struct mbuf *m_at;
3228
3229
0
  if (last_mbuf != NULL) {
3230
0
    return (sctp_add_pad_tombuf(last_mbuf, padval));
3231
0
  } else {
3232
0
    for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
3233
0
      if (SCTP_BUF_NEXT(m_at) == NULL) {
3234
0
        return (sctp_add_pad_tombuf(m_at, padval));
3235
0
      }
3236
0
    }
3237
0
  }
3238
0
  return (NULL);
3239
0
}
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
1.74k
{
3246
1.74k
  struct mbuf *m_notify;
3247
1.74k
  struct sctp_assoc_change *sac;
3248
1.74k
  struct sctp_queued_to_read *control;
3249
1.74k
  struct sctp_inpcb *inp;
3250
1.74k
  unsigned int notif_len;
3251
1.74k
  unsigned int i;
3252
1.74k
  uint16_t abort_len;
3253
#if defined(__APPLE__) && !defined(__Userspace__)
3254
  struct socket *so;
3255
#endif
3256
3257
1.74k
  KASSERT(abort == NULL || from_peer,
3258
1.74k
          ("sctp_notify_assoc_change: ABORT chunk provided for local termination"));
3259
1.74k
  KASSERT(!from_peer || !timedout,
3260
1.74k
          ("sctp_notify_assoc_change: timeouts can only be local"));
3261
1.74k
  KASSERT(stcb != NULL, ("stcb == NULL"));
3262
1.74k
  SCTP_TCB_LOCK_ASSERT(stcb);
3263
1.74k
  inp = stcb->sctp_ep;
3264
1.74k
  SCTP_INP_READ_LOCK_ASSERT(inp);
3265
3266
1.74k
  if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
3267
1.74k
    notif_len = (unsigned int)sizeof(struct sctp_assoc_change);
3268
1.74k
    if (abort != NULL) {
3269
0
      abort_len = ntohs(abort->ch.chunk_length);
3270
      /*
3271
       * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
3272
       * contiguous.
3273
       */
3274
0
      if (abort_len > SCTP_CHUNK_BUFFER_SIZE) {
3275
0
        abort_len = SCTP_CHUNK_BUFFER_SIZE;
3276
0
      }
3277
1.74k
    } else {
3278
1.74k
      abort_len = 0;
3279
1.74k
    }
3280
1.74k
    if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3281
1.74k
      notif_len += SCTP_ASSOC_SUPPORTS_MAX;
3282
1.74k
    } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3283
0
      notif_len += abort_len;
3284
0
    }
3285
1.74k
    m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
3286
1.74k
    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
1.74k
    SCTP_BUF_NEXT(m_notify) = NULL;
3295
1.74k
    sac = mtod(m_notify, struct sctp_assoc_change *);
3296
1.74k
    memset(sac, 0, notif_len);
3297
1.74k
    sac->sac_type = SCTP_ASSOC_CHANGE;
3298
1.74k
    sac->sac_flags = 0;
3299
1.74k
    sac->sac_length = sizeof(struct sctp_assoc_change);
3300
1.74k
    sac->sac_state = state;
3301
1.74k
    sac->sac_error = error;
3302
1.74k
    if (state == SCTP_CANT_STR_ASSOC) {
3303
0
      sac->sac_outbound_streams = 0;
3304
0
      sac->sac_inbound_streams = 0;
3305
1.74k
    } else {
3306
1.74k
      sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
3307
1.74k
      sac->sac_inbound_streams = stcb->asoc.streamincnt;
3308
1.74k
    }
3309
1.74k
    sac->sac_assoc_id = sctp_get_associd(stcb);
3310
1.74k
    if (notif_len > sizeof(struct sctp_assoc_change)) {
3311
1.74k
      if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
3312
1.74k
        i = 0;
3313
1.74k
        if (stcb->asoc.prsctp_supported == 1) {
3314
1.74k
          sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
3315
1.74k
        }
3316
1.74k
        if (stcb->asoc.auth_supported == 1) {
3317
1.74k
          sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
3318
1.74k
        }
3319
1.74k
        if (stcb->asoc.asconf_supported == 1) {
3320
1.74k
          sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
3321
1.74k
        }
3322
1.74k
        if (stcb->asoc.idata_supported == 1) {
3323
193
          sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_INTERLEAVING;
3324
193
        }
3325
1.74k
        sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
3326
1.74k
        if (stcb->asoc.reconfig_supported == 1) {
3327
1.74k
          sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
3328
1.74k
        }
3329
1.74k
        sac->sac_length += i;
3330
1.74k
      } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) {
3331
0
        memcpy(sac->sac_info, abort, abort_len);
3332
0
        sac->sac_length += abort_len;
3333
0
      }
3334
1.74k
    }
3335
1.74k
    SCTP_BUF_LEN(m_notify) = sac->sac_length;
3336
1.74k
    control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3337
1.74k
                                     0, 0, stcb->asoc.context, 0, 0, 0,
3338
1.74k
                                     m_notify);
3339
1.74k
    if (control != NULL) {
3340
1.74k
      control->length = SCTP_BUF_LEN(m_notify);
3341
1.74k
      control->spec_flags = M_NOTIFICATION;
3342
      /* not that we need this */
3343
1.74k
      control->tail_mbuf = m_notify;
3344
1.74k
      sctp_add_to_readq(inp, stcb, control,
3345
1.74k
                        &stcb->sctp_socket->so_rcv, 1,
3346
1.74k
                        SCTP_READ_LOCK_HELD, so_locked);
3347
1.74k
    } else {
3348
0
      sctp_m_freem(m_notify);
3349
0
    }
3350
1.74k
  }
3351
  /*
3352
   * For 1-to-1 style sockets, we send up and error when an ABORT
3353
   * comes in.
3354
   */
3355
1.74k
set_error:
3356
1.74k
  if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3357
0
       (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3358
1.74k
      ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3359
0
    SOCK_LOCK(stcb->sctp_socket);
3360
0
    if (from_peer) {
3361
0
      if (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) {
3362
0
        SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
3363
0
        stcb->sctp_socket->so_error = ECONNREFUSED;
3364
0
      } else {
3365
0
        SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
3366
0
        stcb->sctp_socket->so_error = ECONNRESET;
3367
0
      }
3368
0
    } else {
3369
0
      if (timedout) {
3370
0
        SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT);
3371
0
        stcb->sctp_socket->so_error = ETIMEDOUT;
3372
0
      } else {
3373
0
        SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
3374
0
        stcb->sctp_socket->so_error = ECONNABORTED;
3375
0
      }
3376
0
    }
3377
0
    SOCK_UNLOCK(stcb->sctp_socket);
3378
0
  }
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
1.74k
  if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3395
0
       (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
3396
1.74k
      ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) {
3397
0
    socantrcvmore(stcb->sctp_socket);
3398
0
  }
3399
1.74k
  sorwakeup(stcb->sctp_socket);
3400
1.74k
  sowwakeup(stcb->sctp_socket);
3401
#if defined(__APPLE__) && !defined(__Userspace__)
3402
  if (!so_locked) {
3403
    SCTP_SOCKET_UNLOCK(so, 1);
3404
  }
3405
#endif
3406
1.74k
}
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
0
{
3412
0
  struct mbuf *m_notify;
3413
0
  struct sctp_paddr_change *spc;
3414
0
  struct sctp_queued_to_read *control;
3415
3416
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3417
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3418
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3419
3420
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA);
3426
0
  if (m_notify == NULL)
3427
0
    return;
3428
0
  SCTP_BUF_LEN(m_notify) = 0;
3429
0
  spc = mtod(m_notify, struct sctp_paddr_change *);
3430
0
  memset(spc, 0, sizeof(struct sctp_paddr_change));
3431
0
  spc->spc_type = SCTP_PEER_ADDR_CHANGE;
3432
0
  spc->spc_flags = 0;
3433
0
  spc->spc_length = sizeof(struct sctp_paddr_change);
3434
0
  switch (sa->sa_family) {
3435
0
#ifdef INET
3436
0
  case AF_INET:
3437
0
#ifdef INET6
3438
0
    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
0
    } else {
3442
0
      memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3443
0
    }
3444
#else
3445
    memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
3446
#endif
3447
0
    break;
3448
0
#endif
3449
0
#ifdef INET6
3450
0
  case AF_INET6:
3451
0
  {
3452
#ifdef SCTP_EMBEDDED_V6_SCOPE
3453
    struct sockaddr_in6 *sin6;
3454
#endif /* SCTP_EMBEDDED_V6_SCOPE */
3455
0
    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
0
    break;
3475
0
  }
3476
0
#endif
3477
0
#if defined(__Userspace__)
3478
0
  case AF_CONN:
3479
0
    memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_conn));
3480
0
    break;
3481
0
#endif
3482
0
  default:
3483
    /* TSNH */
3484
0
    break;
3485
0
  }
3486
0
  spc->spc_state = state;
3487
0
  spc->spc_error = error;
3488
0
  spc->spc_assoc_id = sctp_get_associd(stcb);
3489
3490
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change);
3491
0
  SCTP_BUF_NEXT(m_notify) = NULL;
3492
3493
  /* append to socket */
3494
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3495
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3496
0
                                   m_notify);
3497
0
  if (control == NULL) {
3498
    /* no memory */
3499
0
    sctp_m_freem(m_notify);
3500
0
    return;
3501
0
  }
3502
0
  control->length = SCTP_BUF_LEN(m_notify);
3503
0
  control->spec_flags = M_NOTIFICATION;
3504
  /* not that we need this */
3505
0
  control->tail_mbuf = m_notify;
3506
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
3507
0
                    &stcb->sctp_socket->so_rcv, 1,
3508
0
                    SCTP_READ_LOCK_HELD, so_locked);
3509
0
}
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
0
{
3515
0
  struct mbuf *m_notify;
3516
0
  struct sctp_send_failed *ssf;
3517
0
  struct sctp_send_failed_event *ssfe;
3518
0
  struct sctp_queued_to_read *control;
3519
0
  struct sctp_chunkhdr *chkhdr;
3520
0
  int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len;
3521
3522
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3523
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3524
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3525
3526
0
  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
0
  if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3533
0
    notifhdr_len = sizeof(struct sctp_send_failed_event);
3534
0
  } else {
3535
0
    notifhdr_len = sizeof(struct sctp_send_failed);
3536
0
  }
3537
0
  m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3538
0
  if (m_notify == NULL)
3539
    /* no space left */
3540
0
    return;
3541
0
  SCTP_BUF_LEN(m_notify) = notifhdr_len;
3542
0
  if (stcb->asoc.idata_supported) {
3543
0
    chkhdr_len = sizeof(struct sctp_idata_chunk);
3544
0
  } else {
3545
0
    chkhdr_len = sizeof(struct sctp_data_chunk);
3546
0
  }
3547
  /* Use some defaults in case we can't access the chunk header */
3548
0
  if (chk->send_size >= chkhdr_len) {
3549
0
    payload_len = chk->send_size - chkhdr_len;
3550
0
  } else {
3551
0
    payload_len = 0;
3552
0
  }
3553
0
  padding_len = 0;
3554
0
  if (chk->data != NULL) {
3555
0
    chkhdr = mtod(chk->data, struct sctp_chunkhdr *);
3556
0
    if (chkhdr != NULL) {
3557
0
      chk_len = ntohs(chkhdr->chunk_length);
3558
0
      if ((chk_len >= chkhdr_len) &&
3559
0
          (chk->send_size >= chk_len) &&
3560
0
          (chk->send_size - chk_len < 4)) {
3561
0
        padding_len = chk->send_size - chk_len;
3562
0
        payload_len = chk->send_size - chkhdr_len - padding_len;
3563
0
      }
3564
0
    }
3565
0
  }
3566
0
  if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3567
0
    ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3568
0
    memset(ssfe, 0, notifhdr_len);
3569
0
    ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3570
0
    if (sent) {
3571
0
      ssfe->ssfe_flags = SCTP_DATA_SENT;
3572
0
    } else {
3573
0
      ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3574
0
    }
3575
0
    ssfe->ssfe_length = (uint32_t)(notifhdr_len + payload_len);
3576
0
    ssfe->ssfe_error = error;
3577
    /* not exactly what the user sent in, but should be close :) */
3578
0
    ssfe->ssfe_info.snd_sid = chk->rec.data.sid;
3579
0
    ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
3580
0
    ssfe->ssfe_info.snd_ppid = chk->rec.data.ppid;
3581
0
    ssfe->ssfe_info.snd_context = chk->rec.data.context;
3582
0
    ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3583
0
    ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3584
0
  } 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
0
  if (chk->data != NULL) {
3605
    /* Trim off the sctp chunk header (it should be there) */
3606
0
    if (chk->send_size == chkhdr_len + payload_len + padding_len) {
3607
0
      m_adj(chk->data, chkhdr_len);
3608
0
      m_adj(chk->data, -padding_len);
3609
0
      sctp_mbuf_crush(chk->data);
3610
0
      chk->send_size -= (chkhdr_len + padding_len);
3611
0
    }
3612
0
  }
3613
0
  SCTP_BUF_NEXT(m_notify) = chk->data;
3614
  /* Steal off the mbuf */
3615
0
  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
0
  if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3622
0
    sctp_m_freem(m_notify);
3623
0
    return;
3624
0
  }
3625
  /* append to socket */
3626
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3627
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3628
0
                                   m_notify);
3629
0
  if (control == NULL) {
3630
    /* no memory */
3631
0
    sctp_m_freem(m_notify);
3632
0
    return;
3633
0
  }
3634
0
  control->length = SCTP_BUF_LEN(m_notify);
3635
0
  control->spec_flags = M_NOTIFICATION;
3636
  /* not that we need this */
3637
0
  control->tail_mbuf = m_notify;
3638
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
3639
0
                    &stcb->sctp_socket->so_rcv, 1,
3640
0
                    SCTP_READ_LOCK_HELD, so_locked);
3641
0
}
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
0
{
3647
0
  struct mbuf *m_notify;
3648
0
  struct sctp_send_failed *ssf;
3649
0
  struct sctp_send_failed_event *ssfe;
3650
0
  struct sctp_queued_to_read *control;
3651
0
  int notifhdr_len;
3652
3653
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3654
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3655
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3656
3657
0
  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
0
  if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3664
0
    notifhdr_len = sizeof(struct sctp_send_failed_event);
3665
0
  } else {
3666
0
    notifhdr_len = sizeof(struct sctp_send_failed);
3667
0
  }
3668
0
  m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA);
3669
0
  if (m_notify == NULL) {
3670
    /* no space left */
3671
0
    return;
3672
0
  }
3673
0
  SCTP_BUF_LEN(m_notify) = notifhdr_len;
3674
0
  if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
3675
0
    ssfe = mtod(m_notify, struct sctp_send_failed_event *);
3676
0
    memset(ssfe, 0, notifhdr_len);
3677
0
    ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
3678
0
    ssfe->ssfe_flags = SCTP_DATA_UNSENT;
3679
0
    ssfe->ssfe_length = (uint32_t)(notifhdr_len + sp->length);
3680
0
    ssfe->ssfe_error = error;
3681
    /* not exactly what the user sent in, but should be close :) */
3682
0
    ssfe->ssfe_info.snd_sid = sp->sid;
3683
0
    if (sp->some_taken) {
3684
0
      ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
3685
0
    } else {
3686
0
      ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG;
3687
0
    }
3688
0
    ssfe->ssfe_info.snd_ppid = sp->ppid;
3689
0
    ssfe->ssfe_info.snd_context = sp->context;
3690
0
    ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
3691
0
    ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
3692
0
  } 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
0
  SCTP_BUF_NEXT(m_notify) = sp->data;
3713
3714
  /* Steal off the mbuf */
3715
0
  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
0
  if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
3722
0
    sctp_m_freem(m_notify);
3723
0
    return;
3724
0
  }
3725
  /* append to socket */
3726
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3727
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3728
0
                                   m_notify);
3729
0
  if (control == NULL) {
3730
    /* no memory */
3731
0
    sctp_m_freem(m_notify);
3732
0
    return;
3733
0
  }
3734
0
  control->length = SCTP_BUF_LEN(m_notify);
3735
0
  control->spec_flags = M_NOTIFICATION;
3736
  /* not that we need this */
3737
0
  control->tail_mbuf = m_notify;
3738
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
3739
0
                    &stcb->sctp_socket->so_rcv, 1,
3740
0
                    SCTP_READ_LOCK_HELD, so_locked);
3741
0
}
3742
3743
static void
3744
sctp_notify_adaptation_layer(struct sctp_tcb *stcb, int so_locked)
3745
1.74k
{
3746
1.74k
  struct mbuf *m_notify;
3747
1.74k
  struct sctp_adaptation_event *sai;
3748
1.74k
  struct sctp_queued_to_read *control;
3749
3750
1.74k
  KASSERT(stcb != NULL, ("stcb == NULL"));
3751
1.74k
  SCTP_TCB_LOCK_ASSERT(stcb);
3752
1.74k
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3753
3754
1.74k
  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
1.74k
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_NOWAIT, 1, MT_DATA);
3760
1.74k
  if (m_notify == NULL)
3761
    /* no space left */
3762
0
    return;
3763
1.74k
  SCTP_BUF_LEN(m_notify) = 0;
3764
1.74k
  sai = mtod(m_notify, struct sctp_adaptation_event *);
3765
1.74k
  memset(sai, 0, sizeof(struct sctp_adaptation_event));
3766
1.74k
  sai->sai_type = SCTP_ADAPTATION_INDICATION;
3767
1.74k
  sai->sai_flags = 0;
3768
1.74k
  sai->sai_length = sizeof(struct sctp_adaptation_event);
3769
1.74k
  sai->sai_adaptation_ind = stcb->asoc.peers_adaptation;
3770
1.74k
  sai->sai_assoc_id = sctp_get_associd(stcb);
3771
3772
1.74k
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event);
3773
1.74k
  SCTP_BUF_NEXT(m_notify) = NULL;
3774
3775
  /* append to socket */
3776
1.74k
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3777
1.74k
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3778
1.74k
                                   m_notify);
3779
1.74k
  if (control == NULL) {
3780
    /* no memory */
3781
0
    sctp_m_freem(m_notify);
3782
0
    return;
3783
0
  }
3784
1.74k
  control->length = SCTP_BUF_LEN(m_notify);
3785
1.74k
  control->spec_flags = M_NOTIFICATION;
3786
  /* not that we need this */
3787
1.74k
  control->tail_mbuf = m_notify;
3788
1.74k
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
3789
1.74k
                    &stcb->sctp_socket->so_rcv, 1,
3790
1.74k
                    SCTP_READ_LOCK_HELD, so_locked);
3791
1.74k
}
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
0
{
3798
0
  struct mbuf *m_notify;
3799
0
  struct sctp_pdapi_event *pdapi;
3800
0
  struct sctp_queued_to_read *control;
3801
0
  struct sockbuf *sb;
3802
3803
0
  KASSERT(aborted_control != NULL, ("aborted_control is NULL"));
3804
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3805
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3806
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3807
3808
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA);
3814
0
  if (m_notify == NULL)
3815
    /* no space left */
3816
0
    return;
3817
0
  SCTP_BUF_LEN(m_notify) = 0;
3818
0
  pdapi = mtod(m_notify, struct sctp_pdapi_event *);
3819
0
  memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
3820
0
  pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
3821
0
  pdapi->pdapi_flags = 0;
3822
0
  pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
3823
0
  pdapi->pdapi_indication = error;
3824
0
  pdapi->pdapi_stream = aborted_control->sinfo_stream;
3825
0
  pdapi->pdapi_seq = (uint16_t)aborted_control->mid;
3826
0
  pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
3827
3828
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
3829
0
  SCTP_BUF_NEXT(m_notify) = NULL;
3830
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3831
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3832
0
                                   m_notify);
3833
0
  if (control == NULL) {
3834
    /* no memory */
3835
0
    sctp_m_freem(m_notify);
3836
0
    return;
3837
0
  }
3838
0
  control->length = SCTP_BUF_LEN(m_notify);
3839
0
  control->spec_flags = M_NOTIFICATION;
3840
  /* not that we need this */
3841
0
  control->tail_mbuf = m_notify;
3842
0
  sb = &stcb->sctp_socket->so_rcv;
3843
0
  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
0
  sctp_sballoc(stcb, sb, m_notify);
3847
0
  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
0
  control->end_added = 1;
3851
0
  TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, aborted_control, control, next);
3852
0
  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
0
    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
0
  }
3877
0
}
3878
3879
static void
3880
sctp_notify_shutdown_event(struct sctp_tcb *stcb, int so_locked)
3881
0
{
3882
0
  struct mbuf *m_notify;
3883
0
  struct sctp_shutdown_event *sse;
3884
0
  struct sctp_queued_to_read *control;
3885
3886
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3887
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3888
0
  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
0
  if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3895
0
      (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
0
    socantsendmore(stcb->sctp_socket);
3912
#if defined(__APPLE__) && !defined(__Userspace__)
3913
    SCTP_SOCKET_UNLOCK(so, 1);
3914
#endif
3915
0
  }
3916
3917
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_NOWAIT, 1, MT_DATA);
3923
0
  if (m_notify == NULL)
3924
    /* no space left */
3925
0
    return;
3926
0
  sse = mtod(m_notify, struct sctp_shutdown_event *);
3927
0
  memset(sse, 0, sizeof(struct sctp_shutdown_event));
3928
0
  sse->sse_type = SCTP_SHUTDOWN_EVENT;
3929
0
  sse->sse_flags = 0;
3930
0
  sse->sse_length = sizeof(struct sctp_shutdown_event);
3931
0
  sse->sse_assoc_id = sctp_get_associd(stcb);
3932
3933
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event);
3934
0
  SCTP_BUF_NEXT(m_notify) = NULL;
3935
3936
  /* append to socket */
3937
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3938
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3939
0
                                   m_notify);
3940
0
  if (control == NULL) {
3941
    /* no memory */
3942
0
    sctp_m_freem(m_notify);
3943
0
    return;
3944
0
  }
3945
0
  control->length = SCTP_BUF_LEN(m_notify);
3946
0
  control->spec_flags = M_NOTIFICATION;
3947
  /* not that we need this */
3948
0
  control->tail_mbuf = m_notify;
3949
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
3950
0
                    &stcb->sctp_socket->so_rcv, 1,
3951
0
                    SCTP_READ_LOCK_HELD, so_locked);
3952
0
}
3953
3954
static void
3955
sctp_notify_sender_dry_event(struct sctp_tcb *stcb, int so_locked)
3956
0
{
3957
0
  struct mbuf *m_notify;
3958
0
  struct sctp_sender_dry_event *event;
3959
0
  struct sctp_queued_to_read *control;
3960
3961
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
3962
0
  SCTP_TCB_LOCK_ASSERT(stcb);
3963
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
3964
3965
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_sender_dry_event), 0, M_NOWAIT, 1, MT_DATA);
3971
0
  if (m_notify == NULL) {
3972
    /* no space left */
3973
0
    return;
3974
0
  }
3975
0
  SCTP_BUF_LEN(m_notify) = 0;
3976
0
  event = mtod(m_notify, struct sctp_sender_dry_event *);
3977
0
  memset(event, 0, sizeof(struct sctp_sender_dry_event));
3978
0
  event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
3979
0
  event->sender_dry_flags = 0;
3980
0
  event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
3981
0
  event->sender_dry_assoc_id = sctp_get_associd(stcb);
3982
3983
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_sender_dry_event);
3984
0
  SCTP_BUF_NEXT(m_notify) = NULL;
3985
3986
  /* append to socket */
3987
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
3988
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
3989
0
                                   m_notify);
3990
0
  if (control == NULL) {
3991
    /* no memory */
3992
0
    sctp_m_freem(m_notify);
3993
0
    return;
3994
0
  }
3995
0
  control->length = SCTP_BUF_LEN(m_notify);
3996
0
  control->spec_flags = M_NOTIFICATION;
3997
  /* not that we need this */
3998
0
  control->tail_mbuf = m_notify;
3999
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4000
0
                    &stcb->sctp_socket->so_rcv, 1,
4001
0
                    SCTP_READ_LOCK_HELD, so_locked);
4002
0
}
4003
4004
static void
4005
sctp_notify_stream_reset_add(struct sctp_tcb *stcb, int flag, int so_locked)
4006
0
{
4007
0
  struct mbuf *m_notify;
4008
0
  struct sctp_queued_to_read *control;
4009
0
  struct sctp_stream_change_event *stradd;
4010
4011
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
4012
0
  SCTP_TCB_LOCK_ASSERT(stcb);
4013
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
4014
4015
0
  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
0
  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
0
  stcb->asoc.peer_req_out = 0;
4026
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
4027
0
  if (m_notify == NULL)
4028
    /* no space left */
4029
0
    return;
4030
0
  SCTP_BUF_LEN(m_notify) = 0;
4031
0
  stradd = mtod(m_notify, struct sctp_stream_change_event *);
4032
0
  memset(stradd, 0, sizeof(struct sctp_stream_change_event));
4033
0
  stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
4034
0
  stradd->strchange_flags = flag;
4035
0
  stradd->strchange_length = sizeof(struct sctp_stream_change_event);
4036
0
  stradd->strchange_assoc_id = sctp_get_associd(stcb);
4037
0
  stradd->strchange_instrms = stcb->asoc.streamincnt;
4038
0
  stradd->strchange_outstrms = stcb->asoc.streamoutcnt;
4039
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
4040
0
  SCTP_BUF_NEXT(m_notify) = NULL;
4041
0
  if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4042
    /* no space */
4043
0
    sctp_m_freem(m_notify);
4044
0
    return;
4045
0
  }
4046
  /* append to socket */
4047
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4048
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
4049
0
                                   m_notify);
4050
0
  if (control == NULL) {
4051
    /* no memory */
4052
0
    sctp_m_freem(m_notify);
4053
0
    return;
4054
0
  }
4055
0
  control->length = SCTP_BUF_LEN(m_notify);
4056
0
  control->spec_flags = M_NOTIFICATION;
4057
  /* not that we need this */
4058
0
  control->tail_mbuf = m_notify;
4059
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4060
0
                    &stcb->sctp_socket->so_rcv, 1,
4061
0
                    SCTP_READ_LOCK_HELD, so_locked);
4062
0
}
4063
4064
static void
4065
sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, int flag, int so_locked)
4066
0
{
4067
0
  struct mbuf *m_notify;
4068
0
  struct sctp_queued_to_read *control;
4069
0
  struct sctp_assoc_reset_event *strasoc;
4070
4071
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
4072
0
  SCTP_TCB_LOCK_ASSERT(stcb);
4073
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
4074
4075
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
4081
0
  if (m_notify == NULL)
4082
    /* no space left */
4083
0
    return;
4084
0
  SCTP_BUF_LEN(m_notify) = 0;
4085
0
  strasoc = mtod(m_notify, struct sctp_assoc_reset_event  *);
4086
0
  memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
4087
0
  strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
4088
0
  strasoc->assocreset_flags = flag;
4089
0
  strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
4090
0
  strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
4091
0
  strasoc->assocreset_local_tsn = stcb->asoc.sending_seq;
4092
0
  strasoc->assocreset_remote_tsn = stcb->asoc.mapping_array_base_tsn + 1;
4093
0
  SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
4094
0
  SCTP_BUF_NEXT(m_notify) = NULL;
4095
0
  if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4096
    /* no space */
4097
0
    sctp_m_freem(m_notify);
4098
0
    return;
4099
0
  }
4100
  /* append to socket */
4101
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4102
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
4103
0
                                   m_notify);
4104
0
  if (control == NULL) {
4105
    /* no memory */
4106
0
    sctp_m_freem(m_notify);
4107
0
    return;
4108
0
  }
4109
0
  control->length = SCTP_BUF_LEN(m_notify);
4110
0
  control->spec_flags = M_NOTIFICATION;
4111
  /* not that we need this */
4112
0
  control->tail_mbuf = m_notify;
4113
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4114
0
                    &stcb->sctp_socket->so_rcv, 1,
4115
0
                    SCTP_READ_LOCK_HELD, so_locked);
4116
0
}
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
0
{
4122
0
  struct mbuf *m_notify;
4123
0
  struct sctp_queued_to_read *control;
4124
0
  struct sctp_stream_reset_event *strreset;
4125
0
  int len;
4126
4127
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
4128
0
  SCTP_TCB_LOCK_ASSERT(stcb);
4129
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
4130
4131
0
  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
0
  m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
4137
0
  if (m_notify == NULL)
4138
    /* no space left */
4139
0
    return;
4140
0
  SCTP_BUF_LEN(m_notify) = 0;
4141
0
  len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
4142
0
  if (len > M_TRAILINGSPACE(m_notify)) {
4143
    /* never enough room */
4144
0
    sctp_m_freem(m_notify);
4145
0
    return;
4146
0
  }
4147
0
  strreset = mtod(m_notify, struct sctp_stream_reset_event *);
4148
0
  memset(strreset, 0, len);
4149
0
  strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
4150
0
  strreset->strreset_flags = flag;
4151
0
  strreset->strreset_length = len;
4152
0
  strreset->strreset_assoc_id = sctp_get_associd(stcb);
4153
0
  if (number_entries) {
4154
0
    int i;
4155
4156
0
    for (i = 0; i < number_entries; i++) {
4157
0
      strreset->strreset_stream_list[i] = ntohs(list[i]);
4158
0
    }
4159
0
  }
4160
0
  SCTP_BUF_LEN(m_notify) = len;
4161
0
  SCTP_BUF_NEXT(m_notify) = NULL;
4162
0
  if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
4163
    /* no space */
4164
0
    sctp_m_freem(m_notify);
4165
0
    return;
4166
0
  }
4167
  /* append to socket */
4168
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4169
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
4170
0
                                   m_notify);
4171
0
  if (control == NULL) {
4172
    /* no memory */
4173
0
    sctp_m_freem(m_notify);
4174
0
    return;
4175
0
  }
4176
0
  control->length = SCTP_BUF_LEN(m_notify);
4177
0
  control->spec_flags = M_NOTIFICATION;
4178
  /* not that we need this */
4179
0
  control->tail_mbuf = m_notify;
4180
0
  sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4181
0
                    &stcb->sctp_socket->so_rcv, 1,
4182
0
                    SCTP_READ_LOCK_HELD, so_locked);
4183
0
}
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
0
{
4189
0
  struct mbuf *m_notify;
4190
0
  struct sctp_remote_error *sre;
4191
0
  struct sctp_queued_to_read *control;
4192
0
  unsigned int notif_len;
4193
0
  uint16_t chunk_len;
4194
4195
0
  KASSERT(stcb != NULL, ("stcb == NULL"));
4196
0
  SCTP_TCB_LOCK_ASSERT(stcb);
4197
0
  SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep);
4198
4199
0
  if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) {
4200
0
    return;
4201
0
  }
4202
4203
0
  if (chunk != NULL) {
4204
0
    chunk_len = ntohs(chunk->ch.chunk_length);
4205
    /*
4206
     * Only SCTP_CHUNK_BUFFER_SIZE are guaranteed to be
4207
     * contiguous.
4208
     */
4209
0
    if (chunk_len > SCTP_CHUNK_BUFFER_SIZE) {
4210
0
      chunk_len = SCTP_CHUNK_BUFFER_SIZE;
4211
0
    }
4212
0
  } else {
4213
0
    chunk_len = 0;
4214
0
  }
4215
0
  notif_len = (unsigned int)(sizeof(struct sctp_remote_error) + chunk_len);
4216
0
  m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA);
4217
0
  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
0
  SCTP_BUF_NEXT(m_notify) = NULL;
4226
0
  sre = mtod(m_notify, struct sctp_remote_error *);
4227
0
  memset(sre, 0, notif_len);
4228
0
  sre->sre_type = SCTP_REMOTE_ERROR;
4229
0
  sre->sre_flags = 0;
4230
0
  sre->sre_length = sizeof(struct sctp_remote_error);
4231
0
  sre->sre_error = error;
4232
0
  sre->sre_assoc_id = sctp_get_associd(stcb);
4233
0
  if (notif_len > sizeof(struct sctp_remote_error)) {
4234
0
    memcpy(sre->sre_data, chunk, chunk_len);
4235
0
    sre->sre_length += chunk_len;
4236
0
  }
4237
0
  SCTP_BUF_LEN(m_notify) = sre->sre_length;
4238
0
  control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
4239
0
                                   0, 0, stcb->asoc.context, 0, 0, 0,
4240
0
                                   m_notify);
4241
0
  if (control != NULL) {
4242
0
    control->length = SCTP_BUF_LEN(m_notify);
4243
0
    control->spec_flags = M_NOTIFICATION;
4244
    /* not that we need this */
4245
0
    control->tail_mbuf = m_notify;
4246
0
    sctp_add_to_readq(stcb->sctp_ep, stcb, control,
4247
0
                      &stcb->sctp_socket->so_rcv, 1,
4248
0
                      SCTP_READ_LOCK_HELD, so_locked);
4249
0
  } else {
4250
0
    sctp_m_freem(m_notify);
4251
0
  }
4252
0
}
4253
4254
void
4255
sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
4256
                uint32_t error, void *data, int so_locked)
4257
1.74k
{
4258
1.74k
  struct sctp_inpcb *inp;
4259
1.74k
  struct sctp_nets *net;
4260
4261
1.74k
  KASSERT(stcb != NULL, ("stcb == NULL"));
4262
1.74k
  SCTP_TCB_LOCK_ASSERT(stcb);
4263
4264
1.74k
  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
1.74k
  if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
4273
0
    return;
4274
0
  }
4275
1.74k
  if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4276
1.74k
      (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4277
0
    if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
4278
0
        (notification == SCTP_NOTIFY_INTERFACE_UP) ||
4279
0
        (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
4280
      /* Don't report these in front states */
4281
0
      return;
4282
0
    }
4283
0
  }
4284
1.74k
  if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) {
4285
1.74k
    SCTP_INP_READ_LOCK(inp);
4286
1.74k
  }
4287
1.74k
  SCTP_INP_READ_LOCK_ASSERT(inp);
4288
4289
1.74k
  if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4290
1.74k
      (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4291
1.74k
      (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) {
4292
0
    SCTP_INP_READ_UNLOCK(inp);
4293
0
    return;
4294
0
  }
4295
4296
1.74k
  switch (notification) {
4297
1.74k
  case SCTP_NOTIFY_ASSOC_UP:
4298
1.74k
    if (stcb->asoc.assoc_up_sent == 0) {
4299
1.74k
      sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, false, false, so_locked);
4300
1.74k
      stcb->asoc.assoc_up_sent = 1;
4301
1.74k
    }
4302
1.74k
    if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
4303
1.74k
      sctp_notify_adaptation_layer(stcb, so_locked);
4304
1.74k
    }
4305
1.74k
    if (stcb->asoc.auth_supported == 0) {
4306
0
      sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, 0, so_locked);
4307
0
    }
4308
1.74k
    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
0
  case SCTP_NOTIFY_INTERFACE_CONFIRMED:
4339
0
    net = (struct sctp_nets *)data;
4340
0
    sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
4341
0
                                 &net->ro._l_addr.sa, error, so_locked);
4342
0
    break;
4343
0
  case SCTP_NOTIFY_SPECIAL_SP_FAIL:
4344
0
    sctp_notify_send_failed2(stcb, error,
4345
0
                             (struct sctp_stream_queue_pending *)data, so_locked);
4346
0
    break;
4347
0
  case SCTP_NOTIFY_SENT_DG_FAIL:
4348
0
    sctp_notify_send_failed(stcb, 1, error,
4349
0
        (struct sctp_tmit_chunk *)data, so_locked);
4350
0
    break;
4351
0
  case SCTP_NOTIFY_UNSENT_DG_FAIL:
4352
0
    sctp_notify_send_failed(stcb, 0, error,
4353
0
                            (struct sctp_tmit_chunk *)data, so_locked);
4354
0
    break;
4355
0
  case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
4356
0
    sctp_notify_partial_delivery_indication(stcb, error,
4357
0
                                            (struct sctp_queued_to_read *)data,
4358
0
                                            so_locked);
4359
0
    break;
4360
0
  case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
4361
0
    if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4362
0
        (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4363
0
      sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, false, false, so_locked);
4364
0
    } else {
4365
0
      sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, false, false, so_locked);
4366
0
    }
4367
0
    break;
4368
0
  case SCTP_NOTIFY_ASSOC_REM_ABORTED:
4369
0
    if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) ||
4370
0
        (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) {
4371
0
      sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, true, false, so_locked);
4372
0
    } else {
4373
0
      sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, true, false, so_locked);
4374
0
    }
4375
0
    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
0
  case SCTP_NOTIFY_STR_RESET_SEND:
4391
0
    sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN, so_locked);
4392
0
    break;
4393
0
  case SCTP_NOTIFY_STR_RESET_RECV:
4394
0
    sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING, so_locked);
4395
0
    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
0
  case SCTP_NOTIFY_STR_RESET_ADD:
4413
0
    sctp_notify_stream_reset_add(stcb, error, so_locked);
4414
0
    break;
4415
0
  case SCTP_NOTIFY_STR_RESET_TSN:
4416
0
    sctp_notify_stream_reset_tsn(stcb, error, so_locked);
4417
0
    break;
4418
0
  case SCTP_NOTIFY_ASCONF_ADD_IP:
4419
0
    sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
4420
0
                                 error, so_locked);
4421
0
    break;
4422
0
  case SCTP_NOTIFY_ASCONF_DELETE_IP:
4423
0
    sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
4424
0
                                 error, so_locked);
4425
0
    break;
4426
0
  case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
4427
0
    sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
4428
0
                                 error, so_locked);
4429
0
    break;
4430
0
  case SCTP_NOTIFY_PEER_SHUTDOWN:
4431
0
    sctp_notify_shutdown_event(stcb, so_locked);
4432
0
    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
0
  case SCTP_NOTIFY_SENDER_DRY:
4446
0
    sctp_notify_sender_dry_event(stcb, so_locked);
4447
0
    break;
4448
0
  case SCTP_NOTIFY_REMOTE_ERROR:
4449
0
    sctp_notify_remote_error(stcb, error, data, so_locked);
4450
0
    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
1.74k
  }
4456
1.74k
  if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) {
4457
1.74k
    SCTP_INP_READ_UNLOCK(inp);
4458
1.74k
  }
4459
1.74k
}
4460
4461
void
4462
sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int so_locked)
4463
0
{
4464
0
  struct sctp_association *asoc;
4465
0
  struct sctp_stream_out *outs;
4466
0
  struct sctp_tmit_chunk *chk, *nchk;
4467
0
  struct sctp_stream_queue_pending *sp, *nsp;
4468
0
  int i;
4469
4470
0
  if (stcb == NULL) {
4471
0
    return;
4472
0
  }
4473
0
  asoc = &stcb->asoc;
4474
0
  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
0
  if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4486
0
      (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4487
0
      (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
0
  TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) {
4493
0
    TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
4494
0
    asoc->sent_queue_cnt--;
4495
0
    if (chk->sent != SCTP_DATAGRAM_NR_ACKED) {
4496
0
      if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4497
0
        asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4498
0
#ifdef INVARIANTS
4499
0
      } else {
4500
0
        panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4501
0
#endif
4502
0
      }
4503
0
    }
4504
0
    if (chk->data != NULL) {
4505
0
      sctp_free_bufspace(stcb, asoc, chk, 1);
4506
0
      sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
4507
0
                      error, chk, so_locked);
4508
0
      if (chk->data) {
4509
0
        sctp_m_freem(chk->data);
4510
0
        chk->data = NULL;
4511
0
      }
4512
0
    }
4513
0
    sctp_free_a_chunk(stcb, chk, so_locked);
4514
    /*sa_ignore FREED_MEMORY*/
4515
0
  }
4516
  /* pending send queue SHOULD be empty */
4517
0
  TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
4518
0
    TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
4519
0
    asoc->send_queue_cnt--;
4520
0
    if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) {
4521
0
      asoc->strmout[chk->rec.data.sid].chunks_on_queues--;
4522
0
#ifdef INVARIANTS
4523
0
    } else {
4524
0
      panic("No chunks on the queues for sid %u.", chk->rec.data.sid);
4525
0
#endif
4526
0
    }
4527
0
    if (chk->data != NULL) {
4528
0
      sctp_free_bufspace(stcb, asoc, chk, 1);
4529
0
      sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
4530
0
                      error, chk, so_locked);
4531
0
      if (chk->data) {
4532
0
        sctp_m_freem(chk->data);
4533
0
        chk->data = NULL;
4534
0
      }
4535
0
    }
4536
0
    sctp_free_a_chunk(stcb, chk, so_locked);
4537
    /*sa_ignore FREED_MEMORY*/
4538
0
  }
4539
0
  for (i = 0; i < asoc->streamoutcnt; i++) {
4540
    /* For each stream */
4541
0
    outs = &asoc->strmout[i];
4542
    /* clean up any sends there */
4543
0
    TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
4544
0
      atomic_subtract_int(&asoc->stream_queue_cnt, 1);
4545
0
      TAILQ_REMOVE(&outs->outqueue, sp, next);
4546
0
      stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp);
4547
0
      sctp_free_spbufspace(stcb, asoc, sp);
4548
0
      if (sp->data) {
4549
0
        sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
4550
0
            error, (void *)sp, so_locked);
4551
0
        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
0
      }
4558
0
      if (sp->net) {
4559
0
        sctp_free_remote_addr(sp->net);
4560
0
        sp->net = NULL;
4561
0
      }
4562
      /* Free the chunk */
4563
0
      sctp_free_a_strmoq(stcb, sp, so_locked);
4564
      /*sa_ignore FREED_MEMORY*/
4565
0
    }
4566
0
  }
4567
0
}
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
0
{
4574
0
  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
0
  SCTP_TCB_LOCK_ASSERT(stcb);
4585
4586
0
  if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
4587
0
      ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
4588
0
       (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
4589
0
    sctp_pcb_add_flags(stcb->sctp_ep, SCTP_PCB_FLAGS_WAS_ABORTED);
4590
0
  }
4591
0
  if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
4592
0
      (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
4593
0
      (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
4594
0
    return;
4595
0
  }
4596
0
  SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
4597
  /* Tell them we lost the asoc */
4598
0
  sctp_report_all_outbound(stcb, error, so_locked);
4599
0
  if (from_peer) {
4600
0
    sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
4601
0
  } else {
4602
0
    if (timeout) {
4603
0
      sctp_ulp_notify(SCTP_NOTIFY_ASSOC_TIMEDOUT, stcb, error, abort, so_locked);
4604
0
    } else {
4605
0
      sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked);
4606
0
    }
4607
0
  }
4608
0
}
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
0
{
4620
#if defined(__APPLE__) && !defined(__Userspace__)
4621
  struct socket *so;
4622
#endif
4623
0
  struct sctp_gen_error_cause* cause;
4624
0
  uint32_t vtag;
4625
0
  uint16_t cause_code;
4626
4627
0
  if (stcb != NULL) {
4628
0
    vtag = stcb->asoc.peer_vtag;
4629
0
    vrf_id = stcb->asoc.vrf_id;
4630
0
    if (op_err != NULL) {
4631
      /* Read the cause code from the error cause. */
4632
0
      cause = mtod(op_err, struct sctp_gen_error_cause *);
4633
0
      cause_code = ntohs(cause->code);
4634
0
    } else {
4635
0
      cause_code = 0;
4636
0
    }
4637
0
  } else {
4638
0
    vtag = 0;
4639
0
  }
4640
0
  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
0
                  vrf_id, port);
4645
0
  if (stcb != NULL) {
4646
    /* We have a TCB to abort, send notification too */
4647
0
    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
0
    SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4658
0
    if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4659
0
        (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4660
0
      SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4661
0
    }
4662
0
    (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4663
0
                          SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
4664
#if defined(__APPLE__) && !defined(__Userspace__)
4665
    SCTP_SOCKET_UNLOCK(so, 1);
4666
#endif
4667
0
  }
4668
0
}
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
0
{
4735
#if defined(__APPLE__) && !defined(__Userspace__)
4736
  struct socket *so;
4737
#endif
4738
0
  struct sctp_gen_error_cause* cause;
4739
0
  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
0
  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
0
  if (op_err != NULL) {
4772
    /* Read the cause code from the error cause. */
4773
0
    cause = mtod(op_err, struct sctp_gen_error_cause *);
4774
0
    cause_code = ntohs(cause->code);
4775
0
  } else {
4776
0
    cause_code = 0;
4777
0
  }
4778
  /* notify the peer */
4779
0
  sctp_send_abort_tcb(stcb, op_err, so_locked);
4780
0
  SCTP_STAT_INCR_COUNTER32(sctps_aborted);
4781
0
  if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
4782
0
      (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
4783
0
    SCTP_STAT_DECR_GAUGE32(sctps_currestab);
4784
0
  }
4785
  /* notify the ulp */
4786
0
  if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
4787
0
    sctp_abort_notification(stcb, false, timedout, cause_code, NULL, so_locked);
4788
0
  }
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
0
  (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
4803
0
                        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
0
}
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
0
{
4821
0
  struct sctp_chunkhdr *ch, chunk_buf;
4822
0
  unsigned int chk_length;
4823
0
  int contains_init_chunk;
4824
4825
0
  SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
4826
  /* Generate a TO address for future reference */
4827
0
  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
0
  contains_init_chunk = 0;
4840
0
  ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4841
0
      sizeof(*ch), (uint8_t *) & chunk_buf);
4842
0
  while (ch != NULL) {
4843
0
    chk_length = ntohs(ch->chunk_length);
4844
0
    if (chk_length < sizeof(*ch)) {
4845
      /* break to abort land */
4846
0
      break;
4847
0
    }
4848
0
    switch (ch->chunk_type) {
4849
0
    case SCTP_INIT:
4850
0
      contains_init_chunk = 1;
4851
0
      break;
4852
0
    case SCTP_PACKET_DROPPED:
4853
      /* we don't respond to pkt-dropped */
4854
0
      return;
4855
0
    case SCTP_ABORT_ASSOCIATION:
4856
      /* we don't respond with an ABORT to an ABORT */
4857
0
      return;
4858
0
    case SCTP_SHUTDOWN_COMPLETE:
4859
      /*
4860
       * we ignore it since we are not waiting for it and
4861
       * peer is gone
4862
       */
4863
0
      return;
4864
0
    case SCTP_SHUTDOWN_ACK:
4865
0
      sctp_send_shutdown_complete2(src, dst, sh,
4866
#if defined(__FreeBSD__) && !defined(__Userspace__)
4867
                                   mflowtype, mflowid, fibnum,
4868
#endif
4869
0
                                   vrf_id, port);
4870
0
      return;
4871
0
    default:
4872
0
      break;
4873
0
    }
4874
0
    offset += SCTP_SIZE32(chk_length);
4875
0
    ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4876
0
        sizeof(*ch), (uint8_t *) & chunk_buf);
4877
0
  }
4878
0
  if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
4879
0
      ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
4880
0
       (contains_init_chunk == 0))) {
4881
0
    sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
4882
#if defined(__FreeBSD__) && !defined(__Userspace__)
4883
                    mflowtype, mflowid, fibnum,
4884
#endif
4885
0
                    vrf_id, port);
4886
0
  }
4887
0
}
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
0
{
4896
0
  struct sctp_chunkhdr *ch;
4897
0
  struct sctp_init_chunk *init_chk, chunk_buf;
4898
0
  int offset;
4899
0
  unsigned int chk_length;
4900
4901
0
  offset = iphlen + sizeof(struct sctphdr);
4902
0
  ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
4903
0
      (uint8_t *) & chunk_buf);
4904
0
  while (ch != NULL) {
4905
0
    chk_length = ntohs(ch->chunk_length);
4906
0
    if (chk_length < sizeof(*ch)) {
4907
      /* packet is probably corrupt */
4908
0
      break;
4909
0
    }
4910
    /* we seem to be ok, is it an abort? */
4911
0
    if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
4912
      /* yep, tell them */
4913
0
      return (1);
4914
0
    }
4915
0
    if ((ch->chunk_type == SCTP_INITIATION) ||
4916
0
        (ch->chunk_type == SCTP_INITIATION_ACK)) {
4917
      /* need to update the Vtag */
4918
0
      init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
4919
0
          offset, sizeof(struct sctp_init_chunk), (uint8_t *) & chunk_buf);
4920
0
      if (init_chk != NULL) {
4921
0
        *vtag = ntohl(init_chk->init.initiate_tag);
4922
0
      }
4923
0
    }
4924
    /* Nope, move to the next chunk */
4925
0
    offset += SCTP_SIZE32(chk_length);
4926
0
    ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
4927
0
        sizeof(*ch), (uint8_t *) & chunk_buf);
4928
0
  }
4929
0
  return (0);
4930
0
}
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
3.49k
{
5017
5018
  /* must be valid */
5019
3.49k
  if (sa1 == NULL || sa2 == NULL)
5020
0
    return (0);
5021
5022
  /* must be the same family */
5023
3.49k
  if (sa1->sa_family != sa2->sa_family)
5024
0
    return (0);
5025
5026
3.49k
  switch (sa1->sa_family) {
5027
0
#ifdef INET6
5028
0
  case AF_INET6:
5029
0
  {
5030
    /* IPv6 addresses */
5031
0
    struct sockaddr_in6 *sin6_1, *sin6_2;
5032
5033
0
    sin6_1 = (struct sockaddr_in6 *)sa1;
5034
0
    sin6_2 = (struct sockaddr_in6 *)sa2;
5035
0
    return (SCTP6_ARE_ADDR_EQUAL(sin6_1,
5036
0
        sin6_2));
5037
0
  }
5038
0
#endif
5039
0
#ifdef INET
5040
0
  case AF_INET:
5041
0
  {
5042
    /* IPv4 addresses */
5043
0
    struct sockaddr_in *sin_1, *sin_2;
5044
5045
0
    sin_1 = (struct sockaddr_in *)sa1;
5046
0
    sin_2 = (struct sockaddr_in *)sa2;
5047
0
    return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
5048
0
  }
5049
0
#endif
5050
0
#if defined(__Userspace__)
5051
3.49k
  case AF_CONN:
5052
3.49k
  {
5053
3.49k
    struct sockaddr_conn *sconn_1, *sconn_2;
5054
5055
3.49k
    sconn_1 = (struct sockaddr_conn *)sa1;
5056
3.49k
    sconn_2 = (struct sockaddr_conn *)sa2;
5057
3.49k
    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
3.49k
  }
5064
3.49k
}
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
3.49k
{
5237
3.49k
  if ((inp != NULL) &&
5238
3.49k
      (inp->sctp_socket != NULL) &&
5239
3.49k
      (((inp->sctp_flags & (SCTP_PCB_FLAGS_TCPTYPE | SCTP_PCB_FLAGS_IN_TCPPOOL)) == 0) ||
5240
3.49k
       !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
3.49k
    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
3.49k
  }
5268
3.49k
}
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
3.49k
{
5277
3.49k
  uint32_t pd_point, length;
5278
5279
3.49k
  if ((inp->recv_callback == NULL) ||
5280
0
      (stcb == NULL) ||
5281
3.49k
      (stcb->sctp_socket == NULL)) {
5282
3.49k
    return;
5283
3.49k
  }
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
3.49k
{
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
3.49k
  struct mbuf *m, *prev = NULL;
5384
5385
3.49k
  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
3.49k
  if (inp_read_lock_held == SCTP_READ_LOCK_NOT_HELD) {
5400
0
    SCTP_INP_READ_LOCK(inp);
5401
0
  }
5402
3.49k
  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
3.49k
  if ((control->spec_flags & M_NOTIFICATION) == 0) {
5417
0
    atomic_add_int(&inp->total_recvs, 1);
5418
0
    if (!control->do_not_ref_stcb) {
5419
0
      atomic_add_int(&stcb->total_recvs, 1);
5420
0
    }
5421
0
  }
5422
3.49k
  m = control->data;
5423
3.49k
  control->held_length = 0;
5424
3.49k
  control->length = 0;
5425
6.99k
  while (m != NULL) {
5426
3.49k
    if (SCTP_BUF_LEN(m) == 0) {
5427
      /* Skip mbufs with NO length */
5428
0
      if (prev == NULL) {
5429
        /* First one */
5430
0
        control->data = sctp_m_free(m);
5431
0
        m = control->data;
5432
0
      } else {
5433
0
        SCTP_BUF_NEXT(prev) = sctp_m_free(m);
5434
0
        m = SCTP_BUF_NEXT(prev);
5435
0
      }
5436
0
      if (m == NULL) {
5437
0
        control->tail_mbuf = prev;
5438
0
      }
5439
0
      continue;
5440
0
    }
5441
3.49k
    prev = m;
5442
3.49k
    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
3.49k
    sctp_sballoc(stcb, sb, m);
5446
3.49k
    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
3.49k
    atomic_add_int(&control->length, SCTP_BUF_LEN(m));
5450
3.49k
    m = SCTP_BUF_NEXT(m);
5451
3.49k
  }
5452
3.49k
  if (prev != NULL) {
5453
3.49k
    control->tail_mbuf = prev;
5454
3.49k
  } 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
3.49k
  if (end) {
5465
3.49k
    control->end_added = 1;
5466
3.49k
  }
5467
3.49k
  TAILQ_INSERT_TAIL(&inp->read_queue, control, next);
5468
3.49k
  control->on_read_q = 1;
5469
3.49k
#if defined(__Userspace__)
5470
3.49k
  sctp_invoke_recv_callback(inp, stcb, control, SCTP_READ_LOCK_HELD);
5471
3.49k
#endif
5472
3.49k
  if ((inp != NULL) && (inp->sctp_socket != NULL)) {
5473
3.49k
    sctp_wakeup_the_read_socket(inp, stcb, so_locked);
5474
3.49k
  }
5475
3.49k
  if (inp_read_lock_held == SCTP_READ_LOCK_NOT_HELD) {
5476
0
    SCTP_INP_READ_UNLOCK(inp);
5477
0
  }
5478
3.49k
}
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
1.74k
{
5491
1.74k
  struct mbuf *m;
5492
1.74k
  struct sctp_gen_error_cause *cause;
5493
1.74k
  size_t info_len;
5494
1.74k
  uint16_t len;
5495
5496
1.74k
  if ((code == 0) || (info == NULL)) {
5497
0
    return (NULL);
5498
0
  }
5499
1.74k
  info_len = strlen(info);
5500
1.74k
  if (info_len > (SCTP_MAX_CAUSE_LENGTH - sizeof(struct sctp_paramhdr))) {
5501
0
    return (NULL);
5502
0
  }
5503
1.74k
  len = (uint16_t)(sizeof(struct sctp_paramhdr) + info_len);
5504
1.74k
  m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5505
1.74k
  if (m != NULL) {
5506
1.74k
    SCTP_BUF_LEN(m) = len;
5507
1.74k
    cause = mtod(m, struct sctp_gen_error_cause *);
5508
1.74k
    cause->code = htons(code);
5509
1.74k
    cause->length = htons(len);
5510
1.74k
    memcpy(cause->info, info, info_len);
5511
1.74k
  }
5512
1.74k
  return (m);
5513
1.74k
}
5514
5515
struct mbuf *
5516
sctp_generate_no_user_data_cause(uint32_t tsn)
5517
0
{
5518
0
  struct mbuf *m;
5519
0
  struct sctp_error_no_user_data *no_user_data_cause;
5520
0
  uint16_t len;
5521
5522
0
  len = (uint16_t)sizeof(struct sctp_error_no_user_data);
5523
0
  m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
5524
0
  if (m != NULL) {
5525
0
    SCTP_BUF_LEN(m) = len;
5526
0
    no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
5527
0
    no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
5528
0
    no_user_data_cause->cause.length = htons(len);
5529
0
    no_user_data_cause->tsn = htonl(tsn);
5530
0
  }
5531
0
  return (m);
5532
0
}
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
0
{
5538
0
  if (tp1->data == NULL) {
5539
0
    return;
5540
0
  }
5541
0
  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
0
  if (asoc->total_output_queue_size >= tp1->book_size) {
5552
0
    atomic_subtract_int(&asoc->total_output_queue_size, tp1->book_size);
5553
0
  } else {
5554
0
    asoc->total_output_queue_size = 0;
5555
0
  }
5556
0
  if ((stcb->sctp_socket != NULL) &&
5557
0
      (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) ||
5558
0
       ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) {
5559
0
    SCTP_SB_DECR(&stcb->sctp_socket->so_snd, tp1->book_size);
5560
0
  }
5561
0
}
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
3.50k
{
5866
3.50k
  switch (addr->sa_family) {
5867
0
#ifdef INET
5868
4
  case AF_INET:
5869
4
  {
5870
4
    struct sockaddr_in *sin;
5871
5872
4
    sin = (struct sockaddr_in *)addr;
5873
4
    return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16));
5874
0
  }
5875
0
#endif
5876
0
#ifdef INET6
5877
0
  case AF_INET6:
5878
0
  {
5879
0
    struct sockaddr_in6 *sin6;
5880
0
    uint32_t hash_of_addr;
5881
5882
0
    sin6 = (struct sockaddr_in6 *)addr;
5883
0
#if !defined(_WIN32) && !(defined(__FreeBSD__) && defined(__Userspace__)) && !defined(__APPLE__)
5884
0
    hash_of_addr = (sin6->sin6_addr.s6_addr32[0] +
5885
0
        sin6->sin6_addr.s6_addr32[1] +
5886
0
        sin6->sin6_addr.s6_addr32[2] +
5887
0
        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
0
    hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16));
5895
0
    return (hash_of_addr);
5896
0
  }
5897
0
#endif
5898
0
#if defined(__Userspace__)
5899
3.50k
  case AF_CONN:
5900
3.50k
  {
5901
3.50k
    struct sockaddr_conn *sconn;
5902
3.50k
    uintptr_t temp;
5903
5904
3.50k
    sconn = (struct sockaddr_conn *)addr;
5905
3.50k
    temp = (uintptr_t)sconn->sconn_addr;
5906
3.50k
    return ((uint32_t)(temp ^ (temp >> 16)));
5907
0
  }
5908
0
#endif
5909
0
  default:
5910
0
    break;
5911
3.50k
  }
5912
0
  return (0);
5913
3.50k
}
5914
5915
struct sctp_ifa *
5916
sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
5917
3.50k
{
5918
3.50k
  struct sctp_ifa *sctp_ifap;
5919
3.50k
  struct sctp_vrf *vrf;
5920
3.50k
  struct sctp_ifalist *hash_head;
5921
3.50k
  uint32_t hash_of_addr;
5922
5923
3.50k
  if (holds_lock == 0) {
5924
3.49k
    SCTP_IPI_ADDR_RLOCK();
5925
3.49k
  } else {
5926
3
    SCTP_IPI_ADDR_LOCK_ASSERT();
5927
3
  }
5928
5929
3.50k
  vrf = sctp_find_vrf(vrf_id);
5930
3.50k
  if (vrf == NULL) {
5931
0
    if (holds_lock == 0)
5932
0
      SCTP_IPI_ADDR_RUNLOCK();
5933
0
    return (NULL);
5934
0
  }
5935
5936
3.50k
  hash_of_addr = sctp_get_ifa_hash_val(addr);
5937
5938
3.50k
  hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)];
5939
3.50k
  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
3.50k
  LIST_FOREACH(sctp_ifap, hash_head, next_bucket) {
5951
3.49k
    if (addr->sa_family != sctp_ifap->address.sa.sa_family)
5952
0
      continue;
5953
3.49k
#ifdef INET
5954
3.49k
    if (addr->sa_family == AF_INET) {
5955
0
      if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
5956
0
          sctp_ifap->address.sin.sin_addr.s_addr) {
5957
        /* found him. */
5958
0
        break;
5959
0
      }
5960
0
    }
5961
3.49k
#endif
5962
3.49k
#ifdef INET6
5963
3.49k
    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
3.49k
#endif
5971
3.49k
#if defined(__Userspace__)
5972
3.49k
    if (addr->sa_family == AF_CONN) {
5973
3.49k
      if (((struct sockaddr_conn *)addr)->sconn_addr == sctp_ifap->address.sconn.sconn_addr) {
5974
        /* found him. */
5975
3.49k
        break;
5976
3.49k
      }
5977
3.49k
    }
5978
3.49k
#endif
5979
3.49k
  }
5980
3.50k
  if (holds_lock == 0)
5981
3.50k
    SCTP_IPI_ADDR_RUNLOCK();
5982
3.50k
  return (sctp_ifap);
5983
3.50k
}
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
0
{
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
0
  int r_unlocked = 0;
5994
0
  uint32_t dif, rwnd;
5995
0
  struct socket *so = NULL;
5996
5997
0
  if (stcb == NULL)
5998
0
    return;
5999
6000
0
  atomic_add_int(&stcb->asoc.refcnt, 1);
6001
6002
0
  if ((SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
6003
0
      (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED | SCTP_STATE_SHUTDOWN_RECEIVED))) {
6004
    /* Pre-check If we are freeing no update */
6005
0
    goto no_lock;
6006
0
  }
6007
0
  SCTP_INP_INCR_REF(stcb->sctp_ep);
6008
0
  if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6009
0
      (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
6010
0
    goto out;
6011
0
  }
6012
0
  so = stcb->sctp_socket;
6013
0
  if (so == NULL) {
6014
0
    goto out;
6015
0
  }
6016
0
  atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far);
6017
  /* Have you have freed enough to look */
6018
0
  *freed_so_far = 0;
6019
  /* Yep, its worth a look and the lock overhead */
6020
6021
  /* Figure out what the rwnd would be */
6022
0
  rwnd = sctp_calc_rwnd(stcb, &stcb->asoc);
6023
0
  if (rwnd >= stcb->asoc.my_last_reported_rwnd) {
6024
0
    dif = rwnd - stcb->asoc.my_last_reported_rwnd;
6025
0
  } else {
6026
0
    dif = 0;
6027
0
  }
6028
0
  if (dif >= rwnd_req) {
6029
0
    if (hold_rlock) {
6030
0
      SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
6031
0
      r_unlocked = 1;
6032
0
    }
6033
0
    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
0
    SCTP_TCB_LOCK(stcb);
6042
0
    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
0
    SCTP_STAT_INCR(sctps_wu_sacks_sent);
6048
#if defined(__FreeBSD__) && !defined(__Userspace__)
6049
    NET_EPOCH_ENTER(et);
6050
#endif
6051
0
    sctp_send_sack(stcb, SCTP_SO_LOCKED);
6052
6053
0
    sctp_chunk_output(stcb->sctp_ep, stcb,
6054
0
          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
0
    sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
6060
0
                    SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
6061
0
    SCTP_TCB_UNLOCK(stcb);
6062
0
  } else {
6063
    /* Update how much we have pending */
6064
0
    stcb->freed_by_sorcv_sincelast = dif;
6065
0
  }
6066
0
 out:
6067
0
  if (so && r_unlocked && hold_rlock) {
6068
0
    SCTP_INP_READ_LOCK(stcb->sctp_ep);
6069
0
  }
6070
6071
0
  SCTP_INP_DECR_REF(stcb->sctp_ep);
6072
0
 no_lock:
6073
0
  atomic_subtract_int(&stcb->asoc.refcnt, 1);
6074
0
  return;
6075
0
}
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
3.49k
{
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
3.49k
  struct sctp_inpcb *inp = NULL;
6096
3.49k
  ssize_t my_len = 0;
6097
3.49k
  ssize_t cp_len = 0;
6098
3.49k
  int error = 0;
6099
3.49k
  struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL;
6100
3.49k
  struct mbuf *m = NULL;
6101
3.49k
  struct sctp_tcb *stcb = NULL;
6102
3.49k
  int wakeup_read_socket = 0;
6103
3.49k
  int freecnt_applied = 0;
6104
3.49k
  int out_flags = 0, in_flags = 0;
6105
3.49k
  int block_allowed = 1;
6106
3.49k
  uint32_t freed_so_far = 0;
6107
3.49k
  ssize_t copied_so_far = 0;
6108
3.49k
  int in_eeor_mode = 0;
6109
3.49k
  int no_rcv_needed = 0;
6110
3.49k
  uint32_t rwnd_req = 0;
6111
3.49k
  int hold_sblock = 0;
6112
3.49k
  int hold_rlock = 0;
6113
3.49k
  ssize_t slen = 0;
6114
3.49k
  uint32_t held_length = 0;
6115
#if defined(__FreeBSD__) && !defined(__Userspace__)
6116
  int sockbuf_lock = 0;
6117
#endif
6118
6119
3.49k
  if (uio == NULL) {
6120
0
    SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
6121
0
    return (EINVAL);
6122
0
  }
6123
6124
3.49k
  if (msg_flags) {
6125
3.49k
    in_flags = *msg_flags;
6126
3.49k
    if (in_flags & MSG_PEEK)
6127
3.49k
      SCTP_STAT_INCR(sctps_read_peeks);
6128
3.49k
  } 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
3.49k
  slen = uio->uio_resid;
6139
3.49k
#endif
6140
6141
  /* Pull in and set up our int flags */
6142
3.49k
  if (in_flags & MSG_OOB) {
6143
    /* Out of band's NOT supported */
6144
0
    return (EOPNOTSUPP);
6145
0
  }
6146
3.49k
  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
3.49k
  if ((in_flags & (MSG_DONTWAIT
6151
#if defined(__FreeBSD__) && !defined(__Userspace__)
6152
       | MSG_NBIO
6153
#endif
6154
3.49k
         )) ||
6155
3.49k
      SCTP_SO_IS_NBIO(so)) {
6156
3.49k
    block_allowed = 0;
6157
3.49k
  }
6158
  /* setup the endpoint */
6159
3.49k
  inp = (struct sctp_inpcb *)so->so_pcb;
6160
3.49k
  if (inp == NULL) {
6161
0
    SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
6162
0
    return (EFAULT);
6163
0
  }
6164
3.49k
  rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
6165
  /* Must be at least a MTU's worth */
6166
3.49k
  if (rwnd_req < SCTP_MIN_RWND)
6167
0
    rwnd_req = SCTP_MIN_RWND;
6168
3.49k
  in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
6169
3.49k
  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
3.49k
#if defined(__Userspace__)
6184
3.49k
  SOCKBUF_LOCK(&so->so_rcv);
6185
3.49k
  hold_sblock = 1;
6186
3.49k
#endif
6187
3.49k
  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
3.49k
  if (error) {
6209
0
    goto release_unlocked;
6210
0
  }
6211
#if defined(__FreeBSD__) && !defined(__Userspace__)
6212
  sockbuf_lock = 1;
6213
#endif
6214
3.49k
 restart:
6215
3.49k
#if defined(__Userspace__)
6216
3.49k
  if (hold_sblock == 0) {
6217
0
    SOCKBUF_LOCK(&so->so_rcv);
6218
0
    hold_sblock = 1;
6219
0
  }
6220
3.49k
#endif
6221
#if defined(__APPLE__) && !defined(__Userspace__)
6222
  sbunlock(&so->so_rcv, 1);
6223
#endif
6224
6225
3.49k
 restart_nosblocks:
6226
3.49k
  if (hold_sblock == 0) {
6227
0
    SOCKBUF_LOCK(&so->so_rcv);
6228
0
    hold_sblock = 1;
6229
0
  }
6230
3.49k
  if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
6231
3.49k
      (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
3.49k
  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
3.49k
  if (SCTP_SBAVAIL(&so->so_rcv) <= held_length) {
6253
0
    if (so->so_error) {
6254
0
      error = so->so_error;
6255
0
      if ((in_flags & MSG_PEEK) == 0) {
6256
0
        so->so_error = 0;
6257
0
      }
6258
0
      goto out;
6259
0
    }
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
3.49k
  if (hold_sblock == 1) {
6305
3.49k
    SOCKBUF_UNLOCK(&so->so_rcv);
6306
3.49k
    hold_sblock = 0;
6307
3.49k
  }
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
3.49k
  control = TAILQ_FIRST(&inp->read_queue);
6314
3.49k
  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
3.49k
  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
3.49k
  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
3.49k
  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
3.49k
  control->held_length = 0;
6459
3.49k
 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
3.49k
  if (hold_rlock == 0) {
6465
3.49k
    hold_rlock = 1;
6466
3.49k
    SCTP_INP_READ_LOCK(inp);
6467
3.49k
  }
6468
3.49k
  control->some_taken++;
6469
3.49k
  stcb = control->stcb;
6470
3.49k
  if (stcb) {
6471
3.49k
    if ((control->do_not_ref_stcb == 0) &&
6472
3.49k
        (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) {
6473
0
      if (freecnt_applied == 0)
6474
0
        stcb = NULL;
6475
3.49k
    } 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
3.49k
      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
3.49k
      } else {
6490
3.49k
        atomic_add_int(&stcb->asoc.refcnt, 1);
6491
3.49k
        freecnt_applied = 1;
6492
3.49k
      }
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
3.49k
      freed_so_far = (uint32_t)stcb->freed_by_sorcv_sincelast;
6503
3.49k
      stcb->freed_by_sorcv_sincelast = 0;
6504
3.49k
    }
6505
3.49k
  }
6506
3.49k
  if (stcb &&
6507
3.49k
      ((control->spec_flags & M_NOTIFICATION) == 0) &&
6508
0
      control->do_not_ref_stcb == 0) {
6509
0
    stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
6510
0
  }
6511
6512
  /* First lets get off the sinfo and sockaddr info */
6513
3.49k
  if ((sinfo != NULL) && (filling_sinfo != 0)) {
6514
3.49k
    sinfo->sinfo_stream = control->sinfo_stream;
6515
3.49k
    sinfo->sinfo_ssn = (uint16_t)control->mid;
6516
3.49k
    sinfo->sinfo_flags = control->sinfo_flags;
6517
3.49k
    sinfo->sinfo_ppid = control->sinfo_ppid;
6518
3.49k
    sinfo->sinfo_context =control->sinfo_context;
6519
3.49k
    sinfo->sinfo_timetolive = control->sinfo_timetolive;
6520
3.49k
    sinfo->sinfo_tsn = control->sinfo_tsn;
6521
3.49k
    sinfo->sinfo_cumtsn = control->sinfo_cumtsn;
6522
3.49k
    sinfo->sinfo_assoc_id = control->sinfo_assoc_id;
6523
3.49k
    nxt = TAILQ_NEXT(control, next);
6524
3.49k
    if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
6525
3.49k
        sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) {
6526
3.49k
      struct sctp_extrcvinfo *s_extra;
6527
3.49k
      s_extra = (struct sctp_extrcvinfo *)sinfo;
6528
3.49k
      if ((nxt) &&
6529
1.74k
          (nxt->length)) {
6530
1.74k
        s_extra->serinfo_next_flags = SCTP_NEXT_MSG_AVAIL;
6531
1.74k
        if (nxt->sinfo_flags & SCTP_UNORDERED) {
6532
0
          s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED;
6533
0
        }
6534
1.74k
        if (nxt->spec_flags & M_NOTIFICATION) {
6535
1.74k
          s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION;
6536
1.74k
        }
6537
1.74k
        s_extra->serinfo_next_aid = nxt->sinfo_assoc_id;
6538
1.74k
        s_extra->serinfo_next_length = nxt->length;
6539
1.74k
        s_extra->serinfo_next_ppid = nxt->sinfo_ppid;
6540
1.74k
        s_extra->serinfo_next_stream = nxt->sinfo_stream;
6541
1.74k
        if (nxt->tail_mbuf != NULL) {
6542
1.74k
          if (nxt->end_added) {
6543
1.74k
            s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE;
6544
1.74k
          }
6545
1.74k
        }
6546
1.74k
      } 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
1.74k
        nxt = NULL;
6552
1.74k
        s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
6553
1.74k
        s_extra->serinfo_next_aid = 0;
6554
1.74k
        s_extra->serinfo_next_length = 0;
6555
1.74k
        s_extra->serinfo_next_ppid = 0;
6556
1.74k
        s_extra->serinfo_next_stream = 0;
6557
1.74k
      }
6558
3.49k
    }
6559
    /*
6560
     * update off the real current cum-ack, if we have an stcb.
6561
     */
6562
3.49k
    if ((control->do_not_ref_stcb == 0) && stcb)
6563
3.49k
      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
3.49k
    sinfo->sinfo_flags &= 0x00ff;
6569
3.49k
    if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) {
6570
0
      sinfo->sinfo_flags |= SCTP_UNORDERED;
6571
0
    }
6572
3.49k
  }
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
3.49k
  if ((fromlen > 0) && (from != NULL)) {
6593
3.49k
    union sctp_sockstore store;
6594
3.49k
    size_t len;
6595
6596
3.49k
    switch (control->whoFrom->ro._l_addr.sa.sa_family) {
6597
0
#ifdef INET6
6598
0
      case AF_INET6:
6599
0
        len = sizeof(struct sockaddr_in6);
6600
0
        store.sin6 = control->whoFrom->ro._l_addr.sin6;
6601
0
        store.sin6.sin6_port = control->port_from;
6602
0
        break;
6603
0
#endif
6604
0
#ifdef INET
6605
0
      case AF_INET:
6606
0
#ifdef INET6
6607
0
        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
0
        } else {
6613
0
          len = sizeof(struct sockaddr_in);
6614
0
          store.sin = control->whoFrom->ro._l_addr.sin;
6615
0
          store.sin.sin_port = control->port_from;
6616
0
        }
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
0
        break;
6623
0
#endif
6624
0
#if defined(__Userspace__)
6625
3.49k
      case AF_CONN:
6626
3.49k
        len = sizeof(struct sockaddr_conn);
6627
3.49k
        store.sconn = control->whoFrom->ro._l_addr.sconn;
6628
3.49k
        store.sconn.sconn_port = control->port_from;
6629
3.49k
        break;
6630
0
#endif
6631
0
      default:
6632
0
        len = 0;
6633
0
        break;
6634
3.49k
    }
6635
3.49k
    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
3.49k
  }
6647
3.49k
  if (hold_rlock) {
6648
3.49k
    SCTP_INP_READ_UNLOCK(inp);
6649
3.49k
    hold_rlock = 0;
6650
3.49k
  }
6651
3.49k
  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
3.49k
  if (mp == NULL) {
6657
    /* copy out each mbuf in the chain up to length */
6658
3.49k
  get_more_data:
6659
3.49k
    m = control->data;
6660
3.49k
    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
3.49k
      cp_len = uio->uio_resid;
6670
3.49k
#endif
6671
3.49k
      my_len = SCTP_BUF_LEN(m);
6672
3.49k
      if (cp_len > my_len) {
6673
        /* not enough in this buf */
6674
3.49k
        cp_len = my_len;
6675
3.49k
      }
6676
3.49k
      if (hold_rlock) {
6677
0
        SCTP_INP_READ_UNLOCK(inp);
6678
0
        hold_rlock = 0;
6679
0
      }
6680
#if defined(__APPLE__) && !defined(__Userspace__)
6681
      SCTP_SOCKET_UNLOCK(so, 0);
6682
#endif
6683
3.49k
      if (cp_len > 0)
6684
3.49k
        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
3.49k
      if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
6690
0
        goto release;
6691
0
      }
6692
6693
3.49k
      if ((control->do_not_ref_stcb == 0) && stcb &&
6694
3.49k
          stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
6695
0
        no_rcv_needed = 1;
6696
0
      }
6697
3.49k
      if (error) {
6698
        /* error we are out of here */
6699
0
        goto release;
6700
0
      }
6701
3.49k
      SCTP_INP_READ_LOCK(inp);
6702
3.49k
      hold_rlock = 1;
6703
3.49k
      if (cp_len == SCTP_BUF_LEN(m)) {
6704
3.49k
        if ((SCTP_BUF_NEXT(m)== NULL) &&
6705
3.49k
            (control->end_added)) {
6706
3.49k
          out_flags |= MSG_EOR;
6707
3.49k
          if ((control->do_not_ref_stcb == 0) &&
6708
3.49k
              (control->stcb != NULL) &&
6709
3.49k
              ((control->spec_flags & M_NOTIFICATION) == 0))
6710
0
            control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0;
6711
3.49k
        }
6712
3.49k
        if (control->spec_flags & M_NOTIFICATION) {
6713
3.49k
          out_flags |= MSG_NOTIFICATION;
6714
3.49k
        }
6715
        /* we ate up the mbuf */
6716
3.49k
        if (in_flags & MSG_PEEK) {
6717
          /* just looking */
6718
0
          m = SCTP_BUF_NEXT(m);
6719
0
          copied_so_far += cp_len;
6720
3.49k
        } else {
6721
          /* dispose of the mbuf */
6722
3.49k
          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
6.99k
          sctp_sbfree(control, stcb, &so->so_rcv, m);
6727
3.49k
          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
3.49k
          copied_so_far += cp_len;
6732
3.49k
          freed_so_far += (uint32_t)cp_len;
6733
3.49k
          freed_so_far += MSIZE;
6734
3.49k
          atomic_subtract_int(&control->length, (int)cp_len);
6735
3.49k
          control->data = sctp_m_free(m);
6736
3.49k
          m = control->data;
6737
          /* been through it all, must hold sb lock ok to null tail */
6738
3.49k
          if (control->data == NULL) {
6739
3.49k
#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
3.49k
#endif
6752
3.49k
            control->tail_mbuf = NULL;
6753
3.49k
#ifdef INVARIANTS
6754
3.49k
            if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) {
6755
0
              panic("end_added, nothing left and no MSG_EOR");
6756
0
            }
6757
3.49k
#endif
6758
3.49k
          }
6759
3.49k
        }
6760
3.49k
      } else {
6761
        /* Do we need to trim the mbuf? */
6762
0
        if (control->spec_flags & M_NOTIFICATION) {
6763
0
          out_flags |= MSG_NOTIFICATION;
6764
0
        }
6765
0
        if ((in_flags & MSG_PEEK) == 0) {
6766
0
          SCTP_BUF_RESV_UF(m, cp_len);
6767
0
          SCTP_BUF_LEN(m) -= (int)cp_len;
6768
0
          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
0
          SCTP_SB_DECR(&so->so_rcv, cp_len);
6772
0
          if ((control->do_not_ref_stcb == 0) &&
6773
0
              stcb) {
6774
0
            atomic_subtract_int(&stcb->asoc.sb_cc, (int)cp_len);
6775
0
          }
6776
0
          copied_so_far += cp_len;
6777
0
          freed_so_far += (uint32_t)cp_len;
6778
0
          freed_so_far += MSIZE;
6779
0
          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
0
          atomic_subtract_int(&control->length, (int)cp_len);
6784
0
        } else {
6785
0
          copied_so_far += cp_len;
6786
0
        }
6787
0
      }
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
3.49k
      if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) {
6796
3.49k
#endif
6797
3.49k
        break;
6798
3.49k
      }
6799
0
      if (((stcb) && (in_flags & MSG_PEEK) == 0) &&
6800
0
          (control->do_not_ref_stcb == 0) &&
6801
0
          (freed_so_far >= rwnd_req)) {
6802
0
        sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6803
0
      }
6804
0
    } /* 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
3.49k
    if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) {
6811
      /* we are done with this control */
6812
3.49k
      if (control->length == 0) {
6813
3.49k
        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
3.49k
      done_with_control:
6823
3.49k
        if (hold_rlock == 0) {
6824
0
          SCTP_INP_READ_LOCK(inp);
6825
0
          hold_rlock = 1;
6826
0
        }
6827
3.49k
        TAILQ_REMOVE(&inp->read_queue, control, next);
6828
        /* Add back any hidden data */
6829
3.49k
        if (control->held_length) {
6830
0
          held_length = 0;
6831
0
          control->held_length = 0;
6832
0
          wakeup_read_socket = 1;
6833
0
        }
6834
3.49k
        if (control->aux_data) {
6835
0
          sctp_m_free (control->aux_data);
6836
0
          control->aux_data = NULL;
6837
0
        }
6838
3.49k
        no_rcv_needed = control->do_not_ref_stcb;
6839
3.49k
        sctp_free_remote_addr(control->whoFrom);
6840
3.49k
        control->data = NULL;
6841
3.49k
#ifdef INVARIANTS
6842
3.49k
        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
3.49k
#endif
6847
6.99k
        sctp_free_a_readq(stcb, control);
6848
6.99k
        control = NULL;
6849
6.99k
        if ((freed_so_far >= rwnd_req) &&
6850
0
            (no_rcv_needed == 0))
6851
0
          sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
6852
6853
6.99k
      } 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
3.49k
    }
6871
3.49k
    if (out_flags & MSG_EOR) {
6872
3.49k
      goto release;
6873
3.49k
    }
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
0
    if ((uio->uio_resid == 0) ||
6882
0
#endif
6883
0
        ((in_eeor_mode) &&
6884
0
         (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))) {
6885
0
      goto release;
6886
0
    }
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
3.49k
 release:
7061
3.49k
  if (hold_rlock == 1) {
7062
3.49k
    SCTP_INP_READ_UNLOCK(inp);
7063
3.49k
    hold_rlock = 0;
7064
3.49k
  }
7065
3.49k
#if defined(__Userspace__)
7066
3.49k
  if (hold_sblock == 0) {
7067
3.49k
    SOCKBUF_LOCK(&so->so_rcv);
7068
3.49k
    hold_sblock = 1;
7069
3.49k
  }
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
3.49k
 release_unlocked:
7086
3.49k
  if (hold_sblock) {
7087
3.49k
    SOCKBUF_UNLOCK(&so->so_rcv);
7088
3.49k
    hold_sblock = 0;
7089
3.49k
  }
7090
3.49k
  if ((stcb) && (in_flags & MSG_PEEK) == 0) {
7091
3.49k
    if ((freed_so_far >= rwnd_req) &&
7092
0
        (control && (control->do_not_ref_stcb == 0)) &&
7093
0
        (no_rcv_needed == 0))
7094
0
      sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
7095
3.49k
  }
7096
3.49k
 out:
7097
3.49k
  if (msg_flags) {
7098
3.49k
    *msg_flags = out_flags;
7099
3.49k
  }
7100
3.49k
  if (((out_flags & MSG_EOR) == 0) &&
7101
0
      ((in_flags & MSG_PEEK) == 0) &&
7102
0
      (sinfo) &&
7103
0
      (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) ||
7104
0
       sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO))) {
7105
0
    struct sctp_extrcvinfo *s_extra;
7106
0
    s_extra = (struct sctp_extrcvinfo *)sinfo;
7107
0
    s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG;
7108
0
  }
7109
3.49k
  if (hold_rlock == 1) {
7110
0
    SCTP_INP_READ_UNLOCK(inp);
7111
0
  }
7112
3.49k
  if (hold_sblock) {
7113
0
    SOCKBUF_UNLOCK(&so->so_rcv);
7114
0
  }
7115
#if defined(__FreeBSD__) && !defined(__Userspace__)
7116
  if (sockbuf_lock) {
7117
    SOCK_IO_RECV_UNLOCK(so);
7118
  }
7119
#endif
7120
7121
3.49k
  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
3.49k
    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
3.49k
    stcb->freed_by_sorcv_sincelast = freed_so_far;
7138
3.49k
    atomic_subtract_int(&stcb->asoc.refcnt, 1);
7139
3.49k
  }
7140
3.49k
  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
3.49k
 stage_left:
7172
3.49k
  if (wakeup_read_socket) {
7173
0
    sctp_sorwakeup(inp, so);
7174
0
  }
7175
3.49k
  return (error);
7176
3.49k
}
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
3.50k
{
7392
3.50k
  long hashsize;
7393
3.50k
  LIST_HEAD(generic, generic) *hashtbl;
7394
3.50k
  int i;
7395
7396
3.50k
  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
29.7k
  for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
7405
26.2k
    continue;
7406
3.50k
  hashsize >>= 1;
7407
  /*cannot use MALLOC here because it has to be declared or defined
7408
    using MALLOC_DECLARE or MALLOC_DEFINE first. */
7409
3.50k
  if (flags & HASH_WAITOK)
7410
0
    hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
7411
3.50k
  else if (flags & HASH_NOWAIT)
7412
3.50k
    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
3.50k
  if (hashtbl == NULL)
7422
0
    return (NULL);
7423
7424
525k
  for (i = 0; i < hashsize; i++)
7425
522k
    LIST_INIT(&hashtbl[i]);
7426
3.50k
  *hashmask = hashsize - 1;
7427
3.50k
  return (hashtbl);
7428
3.50k
}
7429
7430
void
7431
sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
7432
3.49k
{
7433
3.49k
  LIST_HEAD(generic, generic) *hashtbl, *hp;
7434
7435
3.49k
  hashtbl = vhashtbl;
7436
507k
  for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
7437
503k
    if (!LIST_EMPTY(hp)) {
7438
0
      SCTP_PRINTF("hashdestroy: hash not empty.\n");
7439
0
      return;
7440
0
    }
7441
3.49k
  FREE(hashtbl, type);
7442
3.49k
}
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
6.99k
{
8686
#if defined(KDTRACE_HOOKS)
8687
  int old_state = stcb->asoc.state;
8688
#endif
8689
8690
6.99k
  KASSERT((new_state & ~SCTP_STATE_MASK) == 0,
8691
6.99k
          ("sctp_set_state: Can't set substate (new_state = %x)",
8692
6.99k
          new_state));
8693
6.99k
  stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state;
8694
6.99k
  if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) ||
8695
6.99k
      (new_state == SCTP_STATE_SHUTDOWN_SENT) ||
8696
6.99k
      (new_state == SCTP_STATE_SHUTDOWN_ACK_SENT)) {
8697
0
    SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
8698
0
  }
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
6.99k
}
8707
8708
void
8709
sctp_add_substate(struct sctp_tcb *stcb, int substate)
8710
3.49k
{
8711
#if defined(KDTRACE_HOOKS)
8712
  int old_state = stcb->asoc.state;
8713
#endif
8714
8715
3.49k
  KASSERT((substate & SCTP_STATE_MASK) == 0,
8716
3.49k
          ("sctp_add_substate: Can't set state (substate = %x)",
8717
3.49k
          substate));
8718
3.49k
  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
3.49k
}
8728