Coverage Report

Created: 2022-08-24 06:02

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