sctputil.c revision 1.1 1 1.1 rjs /* $KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $ */
2 1.1 rjs /* $NetBSD: sctputil.c,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
3 1.1 rjs
4 1.1 rjs /*
5 1.1 rjs * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
6 1.1 rjs * All rights reserved.
7 1.1 rjs *
8 1.1 rjs * Redistribution and use in source and binary forms, with or without
9 1.1 rjs * modification, are permitted provided that the following conditions
10 1.1 rjs * are met:
11 1.1 rjs * 1. Redistributions of source code must retain the above copyright
12 1.1 rjs * notice, this list of conditions and the following disclaimer.
13 1.1 rjs * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 rjs * notice, this list of conditions and the following disclaimer in the
15 1.1 rjs * documentation and/or other materials provided with the distribution.
16 1.1 rjs * 3. All advertising materials mentioning features or use of this software
17 1.1 rjs * must display the following acknowledgement:
18 1.1 rjs * This product includes software developed by Cisco Systems, Inc.
19 1.1 rjs * 4. Neither the name of the project nor the names of its contributors
20 1.1 rjs * may be used to endorse or promote products derived from this software
21 1.1 rjs * without specific prior written permission.
22 1.1 rjs *
23 1.1 rjs * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 rjs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 rjs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 rjs * ARE DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
27 1.1 rjs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 rjs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 rjs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 rjs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 rjs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 rjs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 rjs * SUCH DAMAGE.
34 1.1 rjs */
35 1.1 rjs
36 1.1 rjs #include <sys/cdefs.h>
37 1.1 rjs __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.1 2015/10/13 21:28:35 rjs Exp $");
38 1.1 rjs
39 1.1 rjs #ifdef _KERNEL_OPT
40 1.1 rjs #include "opt_inet.h"
41 1.1 rjs #include "opt_ipsec.h"
42 1.1 rjs #include "opt_sctp.h"
43 1.1 rjs #endif /* _KERNEL_OPT */
44 1.1 rjs
45 1.1 rjs #include <sys/param.h>
46 1.1 rjs #include <sys/systm.h>
47 1.1 rjs #include <sys/malloc.h>
48 1.1 rjs #include <sys/mbuf.h>
49 1.1 rjs #include <sys/domain.h>
50 1.1 rjs #include <sys/protosw.h>
51 1.1 rjs #include <sys/socket.h>
52 1.1 rjs #include <sys/socketvar.h>
53 1.1 rjs #include <sys/mutex.h>
54 1.1 rjs #include <sys/proc.h>
55 1.1 rjs #include <sys/kernel.h>
56 1.1 rjs #include <sys/sysctl.h>
57 1.1 rjs
58 1.1 rjs #include <sys/callout.h>
59 1.1 rjs
60 1.1 rjs #include <net/radix.h>
61 1.1 rjs #include <net/route.h>
62 1.1 rjs
63 1.1 rjs #ifdef INET6
64 1.1 rjs #include <sys/domain.h>
65 1.1 rjs #endif
66 1.1 rjs
67 1.1 rjs #include <machine/limits.h>
68 1.1 rjs
69 1.1 rjs #include <net/if.h>
70 1.1 rjs #include <net/if_types.h>
71 1.1 rjs #include <net/route.h>
72 1.1 rjs
73 1.1 rjs #include <netinet/in.h>
74 1.1 rjs #include <netinet/in_systm.h>
75 1.1 rjs #include <netinet/ip.h>
76 1.1 rjs #include <netinet/in_pcb.h>
77 1.1 rjs #include <netinet/in_var.h>
78 1.1 rjs #include <netinet/ip_var.h>
79 1.1 rjs
80 1.1 rjs #ifdef INET6
81 1.1 rjs #include <netinet/ip6.h>
82 1.1 rjs #include <netinet6/ip6_var.h>
83 1.1 rjs #include <netinet6/scope6_var.h>
84 1.1 rjs #include <netinet6/in6_pcb.h>
85 1.1 rjs
86 1.1 rjs #endif /* INET6 */
87 1.1 rjs
88 1.1 rjs #include <netinet/sctp_pcb.h>
89 1.1 rjs
90 1.1 rjs #ifdef IPSEC
91 1.1 rjs #include <netinet6/ipsec.h>
92 1.1 rjs #include <netkey/key.h>
93 1.1 rjs #endif /* IPSEC */
94 1.1 rjs
95 1.1 rjs #include <netinet/sctputil.h>
96 1.1 rjs #include <netinet/sctp_var.h>
97 1.1 rjs #ifdef INET6
98 1.1 rjs #include <netinet6/sctp6_var.h>
99 1.1 rjs #endif
100 1.1 rjs #include <netinet/sctp_header.h>
101 1.1 rjs #include <netinet/sctp_output.h>
102 1.1 rjs #include <netinet/sctp_hashdriver.h>
103 1.1 rjs #include <netinet/sctp_uio.h>
104 1.1 rjs #include <netinet/sctp_timer.h>
105 1.1 rjs #include <netinet/sctp_crc32.h>
106 1.1 rjs #include <netinet/sctp_indata.h> /* for sctp_deliver_data() */
107 1.1 rjs #define NUMBER_OF_MTU_SIZES 18
108 1.1 rjs
109 1.1 rjs #ifdef SCTP_DEBUG
110 1.1 rjs extern u_int32_t sctp_debug_on;
111 1.1 rjs #endif
112 1.1 rjs
113 1.1 rjs #ifdef SCTP_STAT_LOGGING
114 1.1 rjs int sctp_cwnd_log_at=0;
115 1.1 rjs int sctp_cwnd_log_rolled=0;
116 1.1 rjs struct sctp_cwnd_log sctp_clog[SCTP_STAT_LOG_SIZE];
117 1.1 rjs
118 1.1 rjs void sctp_clr_stat_log(void)
119 1.1 rjs {
120 1.1 rjs sctp_cwnd_log_at=0;
121 1.1 rjs sctp_cwnd_log_rolled=0;
122 1.1 rjs }
123 1.1 rjs
124 1.1 rjs void
125 1.1 rjs sctp_log_strm_del_alt(u_int32_t tsn, u_int16_t sseq, int from)
126 1.1 rjs {
127 1.1 rjs
128 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
129 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
130 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = tsn;
131 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = sseq;
132 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
133 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
134 1.1 rjs sctp_cwnd_log_at++;
135 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
136 1.1 rjs sctp_cwnd_log_at = 0;
137 1.1 rjs sctp_cwnd_log_rolled = 1;
138 1.1 rjs }
139 1.1 rjs
140 1.1 rjs }
141 1.1 rjs
142 1.1 rjs void
143 1.1 rjs sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
144 1.1 rjs {
145 1.1 rjs
146 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
147 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAP;
148 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.base = map;
149 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.cum = cum;
150 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.high = high;
151 1.1 rjs sctp_cwnd_log_at++;
152 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
153 1.1 rjs sctp_cwnd_log_at = 0;
154 1.1 rjs sctp_cwnd_log_rolled = 1;
155 1.1 rjs }
156 1.1 rjs }
157 1.1 rjs
158 1.1 rjs void
159 1.1 rjs sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
160 1.1 rjs int from)
161 1.1 rjs {
162 1.1 rjs
163 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
164 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_FR;
165 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_tsn = biggest_tsn;
166 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_new_tsn = biggest_new_tsn;
167 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.tsn = tsn;
168 1.1 rjs sctp_cwnd_log_at++;
169 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
170 1.1 rjs sctp_cwnd_log_at = 0;
171 1.1 rjs sctp_cwnd_log_rolled = 1;
172 1.1 rjs }
173 1.1 rjs }
174 1.1 rjs
175 1.1 rjs void
176 1.1 rjs sctp_log_strm_del(struct sctp_tmit_chunk *chk, struct sctp_tmit_chunk *poschk,
177 1.1 rjs int from)
178 1.1 rjs {
179 1.1 rjs
180 1.1 rjs if (chk == NULL) {
181 1.1 rjs printf("Gak log of NULL?\n");
182 1.1 rjs return;
183 1.1 rjs }
184 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
185 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
186 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = chk->rec.data.TSN_seq;
187 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = chk->rec.data.stream_seq;
188 1.1 rjs if (poschk != NULL) {
189 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn =
190 1.1 rjs poschk->rec.data.TSN_seq;
191 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq =
192 1.1 rjs poschk->rec.data.stream_seq;
193 1.1 rjs } else {
194 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
195 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
196 1.1 rjs }
197 1.1 rjs sctp_cwnd_log_at++;
198 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
199 1.1 rjs sctp_cwnd_log_at = 0;
200 1.1 rjs sctp_cwnd_log_rolled = 1;
201 1.1 rjs }
202 1.1 rjs }
203 1.1 rjs
204 1.1 rjs void
205 1.1 rjs sctp_log_cwnd(struct sctp_nets *net, int augment, uint8_t from)
206 1.1 rjs {
207 1.1 rjs
208 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
209 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_CWND;
210 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
211 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = net->cwnd;
212 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
213 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = augment;
214 1.1 rjs sctp_cwnd_log_at++;
215 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
216 1.1 rjs sctp_cwnd_log_at = 0;
217 1.1 rjs sctp_cwnd_log_rolled = 1;
218 1.1 rjs }
219 1.1 rjs }
220 1.1 rjs
221 1.1 rjs void
222 1.1 rjs sctp_log_maxburst(struct sctp_nets *net, int error, int burst, uint8_t from)
223 1.1 rjs {
224 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
225 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAXBURST;
226 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
227 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = error;
228 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
229 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = burst;
230 1.1 rjs sctp_cwnd_log_at++;
231 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
232 1.1 rjs sctp_cwnd_log_at = 0;
233 1.1 rjs sctp_cwnd_log_rolled = 1;
234 1.1 rjs }
235 1.1 rjs }
236 1.1 rjs
237 1.1 rjs void
238 1.1 rjs sctp_log_rwnd(uint8_t from, u_int32_t peers_rwnd , u_int32_t snd_size, u_int32_t overhead)
239 1.1 rjs {
240 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
241 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
242 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
243 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = snd_size;
244 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
245 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = 0;
246 1.1 rjs sctp_cwnd_log_at++;
247 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
248 1.1 rjs sctp_cwnd_log_at = 0;
249 1.1 rjs sctp_cwnd_log_rolled = 1;
250 1.1 rjs }
251 1.1 rjs }
252 1.1 rjs
253 1.1 rjs void
254 1.1 rjs sctp_log_rwnd_set(uint8_t from, u_int32_t peers_rwnd , u_int32_t flight_size, u_int32_t overhead, u_int32_t a_rwndval)
255 1.1 rjs {
256 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
257 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
258 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
259 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = flight_size;
260 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
261 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = a_rwndval;
262 1.1 rjs sctp_cwnd_log_at++;
263 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
264 1.1 rjs sctp_cwnd_log_at = 0;
265 1.1 rjs sctp_cwnd_log_rolled = 1;
266 1.1 rjs }
267 1.1 rjs }
268 1.1 rjs
269 1.1 rjs void
270 1.1 rjs sctp_log_mbcnt(uint8_t from, u_int32_t total_oq , u_int32_t book, u_int32_t total_mbcnt_q, u_int32_t mbcnt)
271 1.1 rjs {
272 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
273 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MBCNT;
274 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_size = total_oq;
275 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.size_change = book;
276 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_mb_size = total_mbcnt_q;
277 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.mbcnt_change = mbcnt;
278 1.1 rjs sctp_cwnd_log_at++;
279 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
280 1.1 rjs sctp_cwnd_log_at = 0;
281 1.1 rjs sctp_cwnd_log_rolled = 1;
282 1.1 rjs }
283 1.1 rjs }
284 1.1 rjs
285 1.1 rjs void
286 1.1 rjs sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc)
287 1.1 rjs {
288 1.1 rjs
289 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
290 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_BLOCK;
291 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxmb = (u_int16_t)(so->so_snd.sb_mbmax/1024);
292 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onmb = asoc->total_output_mbuf_queue_size;
293 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxsb = (u_int16_t)(so->so_snd.sb_hiwat/1024);
294 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onsb = asoc->total_output_queue_size;
295 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.send_sent_qcnt = (u_int16_t)(asoc->send_queue_cnt + asoc->sent_queue_cnt);
296 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.stream_qcnt = (u_int16_t)asoc->stream_queue_cnt;
297 1.1 rjs sctp_cwnd_log_at++;
298 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
299 1.1 rjs sctp_cwnd_log_at = 0;
300 1.1 rjs sctp_cwnd_log_rolled = 1;
301 1.1 rjs }
302 1.1 rjs }
303 1.1 rjs
304 1.1 rjs int
305 1.1 rjs sctp_fill_stat_log(struct mbuf *m)
306 1.1 rjs {
307 1.1 rjs struct sctp_cwnd_log_req *req;
308 1.1 rjs int size_limit, num, i, at, cnt_out=0;
309 1.1 rjs
310 1.1 rjs if (m == NULL)
311 1.1 rjs return (EINVAL);
312 1.1 rjs
313 1.1 rjs size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req));
314 1.1 rjs if (size_limit < sizeof(struct sctp_cwnd_log)) {
315 1.1 rjs return (EINVAL);
316 1.1 rjs }
317 1.1 rjs req = mtod(m, struct sctp_cwnd_log_req *);
318 1.1 rjs num = size_limit/sizeof(struct sctp_cwnd_log);
319 1.1 rjs if (sctp_cwnd_log_rolled) {
320 1.1 rjs req->num_in_log = SCTP_STAT_LOG_SIZE;
321 1.1 rjs } else {
322 1.1 rjs req->num_in_log = sctp_cwnd_log_at;
323 1.1 rjs /* if the log has not rolled, we don't
324 1.1 rjs * let you have old data.
325 1.1 rjs */
326 1.1 rjs if (req->end_at > sctp_cwnd_log_at) {
327 1.1 rjs req->end_at = sctp_cwnd_log_at;
328 1.1 rjs }
329 1.1 rjs }
330 1.1 rjs if ((num < SCTP_STAT_LOG_SIZE) &&
331 1.1 rjs ((sctp_cwnd_log_rolled) || (sctp_cwnd_log_at > num))) {
332 1.1 rjs /* we can't return all of it */
333 1.1 rjs if (((req->start_at == 0) && (req->end_at == 0)) ||
334 1.1 rjs (req->start_at >= SCTP_STAT_LOG_SIZE) ||
335 1.1 rjs (req->end_at >= SCTP_STAT_LOG_SIZE)) {
336 1.1 rjs /* No user request or user is wacked. */
337 1.1 rjs req->num_ret = num;
338 1.1 rjs req->end_at = sctp_cwnd_log_at - 1;
339 1.1 rjs if ((sctp_cwnd_log_at - num) < 0) {
340 1.1 rjs int cc;
341 1.1 rjs cc = num - sctp_cwnd_log_at;
342 1.1 rjs req->start_at = SCTP_STAT_LOG_SIZE - cc;
343 1.1 rjs } else {
344 1.1 rjs req->start_at = sctp_cwnd_log_at - num;
345 1.1 rjs }
346 1.1 rjs } else {
347 1.1 rjs /* a user request */
348 1.1 rjs int cc;
349 1.1 rjs if (req->start_at > req->end_at) {
350 1.1 rjs cc = (SCTP_STAT_LOG_SIZE - req->start_at) +
351 1.1 rjs (req->end_at + 1);
352 1.1 rjs } else {
353 1.1 rjs
354 1.1 rjs cc = req->end_at - req->start_at;
355 1.1 rjs }
356 1.1 rjs if (cc < num) {
357 1.1 rjs num = cc;
358 1.1 rjs }
359 1.1 rjs req->num_ret = num;
360 1.1 rjs }
361 1.1 rjs } else {
362 1.1 rjs /* We can return all of it */
363 1.1 rjs req->start_at = 0;
364 1.1 rjs req->end_at = sctp_cwnd_log_at - 1;
365 1.1 rjs req->num_ret = sctp_cwnd_log_at;
366 1.1 rjs }
367 1.1 rjs for (i = 0, at = req->start_at; i < req->num_ret; i++) {
368 1.1 rjs req->log[i] = sctp_clog[at];
369 1.1 rjs cnt_out++;
370 1.1 rjs at++;
371 1.1 rjs if (at >= SCTP_STAT_LOG_SIZE)
372 1.1 rjs at = 0;
373 1.1 rjs }
374 1.1 rjs m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log_req)) + sizeof(struct sctp_cwnd_log_req);
375 1.1 rjs return (0);
376 1.1 rjs }
377 1.1 rjs
378 1.1 rjs #endif
379 1.1 rjs
380 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
381 1.1 rjs u_int8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
382 1.1 rjs static int sctp_audit_indx = 0;
383 1.1 rjs
384 1.1 rjs static
385 1.1 rjs void sctp_print_audit_report(void)
386 1.1 rjs {
387 1.1 rjs int i;
388 1.1 rjs int cnt;
389 1.1 rjs cnt = 0;
390 1.1 rjs for (i=sctp_audit_indx;i<SCTP_AUDIT_SIZE;i++) {
391 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) &&
392 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
393 1.1 rjs cnt = 0;
394 1.1 rjs printf("\n");
395 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) {
396 1.1 rjs cnt = 0;
397 1.1 rjs printf("\n");
398 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) &&
399 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
400 1.1 rjs printf("\n");
401 1.1 rjs cnt = 0;
402 1.1 rjs }
403 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
404 1.1 rjs (uint32_t)sctp_audit_data[i][1]);
405 1.1 rjs cnt++;
406 1.1 rjs if ((cnt % 14) == 0)
407 1.1 rjs printf("\n");
408 1.1 rjs }
409 1.1 rjs for (i=0;i<sctp_audit_indx;i++) {
410 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) &&
411 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
412 1.1 rjs cnt = 0;
413 1.1 rjs printf("\n");
414 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) {
415 1.1 rjs cnt = 0;
416 1.1 rjs printf("\n");
417 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) &&
418 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
419 1.1 rjs printf("\n");
420 1.1 rjs cnt = 0;
421 1.1 rjs }
422 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
423 1.1 rjs (uint32_t)sctp_audit_data[i][1]);
424 1.1 rjs cnt++;
425 1.1 rjs if ((cnt % 14) == 0)
426 1.1 rjs printf("\n");
427 1.1 rjs }
428 1.1 rjs printf("\n");
429 1.1 rjs }
430 1.1 rjs
431 1.1 rjs void sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
432 1.1 rjs struct sctp_nets *net)
433 1.1 rjs {
434 1.1 rjs int resend_cnt, tot_out, rep, tot_book_cnt;
435 1.1 rjs struct sctp_nets *lnet;
436 1.1 rjs struct sctp_tmit_chunk *chk;
437 1.1 rjs
438 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAA;
439 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
440 1.1 rjs sctp_audit_indx++;
441 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
442 1.1 rjs sctp_audit_indx = 0;
443 1.1 rjs }
444 1.1 rjs if (inp == NULL) {
445 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
446 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x01;
447 1.1 rjs sctp_audit_indx++;
448 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
449 1.1 rjs sctp_audit_indx = 0;
450 1.1 rjs }
451 1.1 rjs return;
452 1.1 rjs }
453 1.1 rjs if (stcb == NULL) {
454 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
455 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x02;
456 1.1 rjs sctp_audit_indx++;
457 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
458 1.1 rjs sctp_audit_indx = 0;
459 1.1 rjs }
460 1.1 rjs return;
461 1.1 rjs }
462 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA1;
463 1.1 rjs sctp_audit_data[sctp_audit_indx][1] =
464 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
465 1.1 rjs sctp_audit_indx++;
466 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
467 1.1 rjs sctp_audit_indx = 0;
468 1.1 rjs }
469 1.1 rjs rep = 0;
470 1.1 rjs tot_book_cnt = 0;
471 1.1 rjs resend_cnt = tot_out = 0;
472 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
473 1.1 rjs if (chk->sent == SCTP_DATAGRAM_RESEND) {
474 1.1 rjs resend_cnt++;
475 1.1 rjs } else if (chk->sent < SCTP_DATAGRAM_RESEND) {
476 1.1 rjs tot_out += chk->book_size;
477 1.1 rjs tot_book_cnt++;
478 1.1 rjs }
479 1.1 rjs }
480 1.1 rjs if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
481 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
482 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA1;
483 1.1 rjs sctp_audit_indx++;
484 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
485 1.1 rjs sctp_audit_indx = 0;
486 1.1 rjs }
487 1.1 rjs printf("resend_cnt:%d asoc-tot:%d\n",
488 1.1 rjs resend_cnt, stcb->asoc.sent_queue_retran_cnt);
489 1.1 rjs rep = 1;
490 1.1 rjs stcb->asoc.sent_queue_retran_cnt = resend_cnt;
491 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA2;
492 1.1 rjs sctp_audit_data[sctp_audit_indx][1] =
493 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
494 1.1 rjs sctp_audit_indx++;
495 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
496 1.1 rjs sctp_audit_indx = 0;
497 1.1 rjs }
498 1.1 rjs }
499 1.1 rjs if (tot_out != stcb->asoc.total_flight) {
500 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
501 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA2;
502 1.1 rjs sctp_audit_indx++;
503 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
504 1.1 rjs sctp_audit_indx = 0;
505 1.1 rjs }
506 1.1 rjs rep = 1;
507 1.1 rjs printf("tot_flt:%d asoc_tot:%d\n", tot_out,
508 1.1 rjs (int)stcb->asoc.total_flight);
509 1.1 rjs stcb->asoc.total_flight = tot_out;
510 1.1 rjs }
511 1.1 rjs if (tot_book_cnt != stcb->asoc.total_flight_count) {
512 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
513 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA5;
514 1.1 rjs sctp_audit_indx++;
515 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
516 1.1 rjs sctp_audit_indx = 0;
517 1.1 rjs }
518 1.1 rjs rep = 1;
519 1.1 rjs printf("tot_flt_book:%d\n", tot_book);
520 1.1 rjs
521 1.1 rjs stcb->asoc.total_flight_count = tot_book_cnt;
522 1.1 rjs }
523 1.1 rjs tot_out = 0;
524 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
525 1.1 rjs tot_out += lnet->flight_size;
526 1.1 rjs }
527 1.1 rjs if (tot_out != stcb->asoc.total_flight) {
528 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
529 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA3;
530 1.1 rjs sctp_audit_indx++;
531 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
532 1.1 rjs sctp_audit_indx = 0;
533 1.1 rjs }
534 1.1 rjs rep = 1;
535 1.1 rjs printf("real flight:%d net total was %d\n",
536 1.1 rjs stcb->asoc.total_flight, tot_out);
537 1.1 rjs /* now corrective action */
538 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
539 1.1 rjs tot_out = 0;
540 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
541 1.1 rjs if ((chk->whoTo == lnet) &&
542 1.1 rjs (chk->sent < SCTP_DATAGRAM_RESEND)) {
543 1.1 rjs tot_out += chk->book_size;
544 1.1 rjs }
545 1.1 rjs }
546 1.1 rjs if (lnet->flight_size != tot_out) {
547 1.1 rjs printf("net:%x flight was %d corrected to %d\n",
548 1.1 rjs (uint32_t)lnet, lnet->flight_size, tot_out);
549 1.1 rjs lnet->flight_size = tot_out;
550 1.1 rjs }
551 1.1 rjs
552 1.1 rjs }
553 1.1 rjs }
554 1.1 rjs
555 1.1 rjs if (rep) {
556 1.1 rjs sctp_print_audit_report();
557 1.1 rjs }
558 1.1 rjs }
559 1.1 rjs
560 1.1 rjs void
561 1.1 rjs sctp_audit_log(u_int8_t ev, u_int8_t fd)
562 1.1 rjs {
563 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = ev;
564 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = fd;
565 1.1 rjs sctp_audit_indx++;
566 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
567 1.1 rjs sctp_audit_indx = 0;
568 1.1 rjs }
569 1.1 rjs }
570 1.1 rjs
571 1.1 rjs #endif
572 1.1 rjs
573 1.1 rjs /*
574 1.1 rjs * a list of sizes based on typical mtu's, used only if next hop
575 1.1 rjs * size not returned.
576 1.1 rjs */
577 1.1 rjs static int sctp_mtu_sizes[] = {
578 1.1 rjs 68,
579 1.1 rjs 296,
580 1.1 rjs 508,
581 1.1 rjs 512,
582 1.1 rjs 544,
583 1.1 rjs 576,
584 1.1 rjs 1006,
585 1.1 rjs 1492,
586 1.1 rjs 1500,
587 1.1 rjs 1536,
588 1.1 rjs 2002,
589 1.1 rjs 2048,
590 1.1 rjs 4352,
591 1.1 rjs 4464,
592 1.1 rjs 8166,
593 1.1 rjs 17914,
594 1.1 rjs 32000,
595 1.1 rjs 65535
596 1.1 rjs };
597 1.1 rjs
598 1.1 rjs int
599 1.1 rjs find_next_best_mtu(int totsz)
600 1.1 rjs {
601 1.1 rjs int i, perfer;
602 1.1 rjs /*
603 1.1 rjs * if we are in here we must find the next best fit based on the
604 1.1 rjs * size of the dg that failed to be sent.
605 1.1 rjs */
606 1.1 rjs perfer = 0;
607 1.1 rjs for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) {
608 1.1 rjs if (totsz < sctp_mtu_sizes[i]) {
609 1.1 rjs perfer = i - 1;
610 1.1 rjs if (perfer < 0)
611 1.1 rjs perfer = 0;
612 1.1 rjs break;
613 1.1 rjs }
614 1.1 rjs }
615 1.1 rjs return (sctp_mtu_sizes[perfer]);
616 1.1 rjs }
617 1.1 rjs
618 1.1 rjs void
619 1.1 rjs sctp_fill_random_store(struct sctp_pcb *m)
620 1.1 rjs {
621 1.1 rjs /*
622 1.1 rjs * Here we use the MD5/SHA-1 to hash with our good randomNumbers
623 1.1 rjs * and our counter. The result becomes our good random numbers and
624 1.1 rjs * we then setup to give these out. Note that we do no lockig
625 1.1 rjs * to protect this. This is ok, since if competing folks call
626 1.1 rjs * this we will get more gobbled gook in the random store whic
627 1.1 rjs * is what we want. There is a danger that two guys will use
628 1.1 rjs * the same random numbers, but thats ok too since that
629 1.1 rjs * is random as well :->
630 1.1 rjs */
631 1.1 rjs m->store_at = 0;
632 1.1 rjs sctp_hash_digest((char *)m->random_numbers, sizeof(m->random_numbers),
633 1.1 rjs (char *)&m->random_counter, sizeof(m->random_counter),
634 1.1 rjs (char *)m->random_store);
635 1.1 rjs m->random_counter++;
636 1.1 rjs }
637 1.1 rjs
638 1.1 rjs uint32_t
639 1.1 rjs sctp_select_initial_TSN(struct sctp_pcb *m)
640 1.1 rjs {
641 1.1 rjs /*
642 1.1 rjs * A true implementation should use random selection process to
643 1.1 rjs * get the initial stream sequence number, using RFC1750 as a
644 1.1 rjs * good guideline
645 1.1 rjs */
646 1.1 rjs u_long x, *xp;
647 1.1 rjs uint8_t *p;
648 1.1 rjs
649 1.1 rjs if (m->initial_sequence_debug != 0) {
650 1.1 rjs u_int32_t ret;
651 1.1 rjs ret = m->initial_sequence_debug;
652 1.1 rjs m->initial_sequence_debug++;
653 1.1 rjs return (ret);
654 1.1 rjs }
655 1.1 rjs if ((m->store_at+sizeof(u_long)) > SCTP_SIGNATURE_SIZE) {
656 1.1 rjs /* Refill the random store */
657 1.1 rjs sctp_fill_random_store(m);
658 1.1 rjs }
659 1.1 rjs p = &m->random_store[(int)m->store_at];
660 1.1 rjs xp = (u_long *)p;
661 1.1 rjs x = *xp;
662 1.1 rjs m->store_at += sizeof(u_long);
663 1.1 rjs return (x);
664 1.1 rjs }
665 1.1 rjs
666 1.1 rjs u_int32_t sctp_select_a_tag(struct sctp_inpcb *m)
667 1.1 rjs {
668 1.1 rjs u_long x, not_done;
669 1.1 rjs struct timeval now;
670 1.1 rjs
671 1.1 rjs SCTP_GETTIME_TIMEVAL(&now);
672 1.1 rjs not_done = 1;
673 1.1 rjs while (not_done) {
674 1.1 rjs x = sctp_select_initial_TSN(&m->sctp_ep);
675 1.1 rjs if (x == 0) {
676 1.1 rjs /* we never use 0 */
677 1.1 rjs continue;
678 1.1 rjs }
679 1.1 rjs if (sctp_is_vtag_good(m, x, &now)) {
680 1.1 rjs not_done = 0;
681 1.1 rjs }
682 1.1 rjs }
683 1.1 rjs return (x);
684 1.1 rjs }
685 1.1 rjs
686 1.1 rjs
687 1.1 rjs int
688 1.1 rjs sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
689 1.1 rjs int for_a_init, uint32_t override_tag )
690 1.1 rjs {
691 1.1 rjs /*
692 1.1 rjs * Anything set to zero is taken care of by the allocation
693 1.1 rjs * routine's bzero
694 1.1 rjs */
695 1.1 rjs
696 1.1 rjs /*
697 1.1 rjs * Up front select what scoping to apply on addresses I tell my peer
698 1.1 rjs * Not sure what to do with these right now, we will need to come up
699 1.1 rjs * with a way to set them. We may need to pass them through from the
700 1.1 rjs * caller in the sctp_aloc_assoc() function.
701 1.1 rjs */
702 1.1 rjs int i;
703 1.1 rjs /* init all variables to a known value.*/
704 1.1 rjs asoc->state = SCTP_STATE_INUSE;
705 1.1 rjs asoc->max_burst = m->sctp_ep.max_burst;
706 1.1 rjs asoc->heart_beat_delay = m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
707 1.1 rjs asoc->cookie_life = m->sctp_ep.def_cookie_life;
708 1.1 rjs
709 1.1 rjs if (override_tag) {
710 1.1 rjs asoc->my_vtag = override_tag;
711 1.1 rjs } else {
712 1.1 rjs asoc->my_vtag = sctp_select_a_tag(m);
713 1.1 rjs }
714 1.1 rjs asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
715 1.1 rjs sctp_select_initial_TSN(&m->sctp_ep);
716 1.1 rjs asoc->t3timeout_highest_marked = asoc->asconf_seq_out;
717 1.1 rjs /* we are opptimisitic here */
718 1.1 rjs asoc->peer_supports_asconf = 1;
719 1.1 rjs asoc->peer_supports_asconf_setprim = 1;
720 1.1 rjs asoc->peer_supports_pktdrop = 1;
721 1.1 rjs
722 1.1 rjs asoc->sent_queue_retran_cnt = 0;
723 1.1 rjs /* This will need to be adjusted */
724 1.1 rjs asoc->last_cwr_tsn = asoc->init_seq_number - 1;
725 1.1 rjs asoc->last_acked_seq = asoc->init_seq_number - 1;
726 1.1 rjs asoc->advanced_peer_ack_point = asoc->last_acked_seq;
727 1.1 rjs asoc->asconf_seq_in = asoc->last_acked_seq;
728 1.1 rjs
729 1.1 rjs /* here we are different, we hold the next one we expect */
730 1.1 rjs asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
731 1.1 rjs
732 1.1 rjs asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
733 1.1 rjs asoc->initial_rto = m->sctp_ep.initial_rto;
734 1.1 rjs
735 1.1 rjs asoc->max_init_times = m->sctp_ep.max_init_times;
736 1.1 rjs asoc->max_send_times = m->sctp_ep.max_send_times;
737 1.1 rjs asoc->def_net_failure = m->sctp_ep.def_net_failure;
738 1.1 rjs
739 1.1 rjs /* ECN Nonce initialization */
740 1.1 rjs asoc->ecn_nonce_allowed = 0;
741 1.1 rjs asoc->receiver_nonce_sum = 1;
742 1.1 rjs asoc->nonce_sum_expect_base = 1;
743 1.1 rjs asoc->nonce_sum_check = 1;
744 1.1 rjs asoc->nonce_resync_tsn = 0;
745 1.1 rjs asoc->nonce_wait_for_ecne = 0;
746 1.1 rjs asoc->nonce_wait_tsn = 0;
747 1.1 rjs
748 1.1 rjs if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
749 1.1 rjs struct in6pcb *inp6;
750 1.1 rjs
751 1.1 rjs
752 1.1 rjs /* Its a V6 socket */
753 1.1 rjs inp6 = (struct in6pcb *)m;
754 1.1 rjs asoc->ipv6_addr_legal = 1;
755 1.1 rjs /* Now look at the binding flag to see if V4 will be legal */
756 1.1 rjs if (
757 1.1 rjs #if defined(__OpenBSD__)
758 1.1 rjs (0) /* we always do dual bind */
759 1.1 rjs #elif defined (__NetBSD__)
760 1.1 rjs (inp6->in6p_flags & IN6P_IPV6_V6ONLY)
761 1.1 rjs #else
762 1.1 rjs (inp6->inp_flags & IN6P_IPV6_V6ONLY)
763 1.1 rjs #endif
764 1.1 rjs == 0) {
765 1.1 rjs asoc->ipv4_addr_legal = 1;
766 1.1 rjs } else {
767 1.1 rjs /* V4 addresses are NOT legal on the association */
768 1.1 rjs asoc->ipv4_addr_legal = 0;
769 1.1 rjs }
770 1.1 rjs } else {
771 1.1 rjs /* Its a V4 socket, no - V6 */
772 1.1 rjs asoc->ipv4_addr_legal = 1;
773 1.1 rjs asoc->ipv6_addr_legal = 0;
774 1.1 rjs }
775 1.1 rjs
776 1.1 rjs
777 1.1 rjs asoc->my_rwnd = max(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND);
778 1.1 rjs asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat;
779 1.1 rjs
780 1.1 rjs asoc->smallest_mtu = m->sctp_frag_point;
781 1.1 rjs asoc->minrto = m->sctp_ep.sctp_minrto;
782 1.1 rjs asoc->maxrto = m->sctp_ep.sctp_maxrto;
783 1.1 rjs
784 1.1 rjs LIST_INIT(&asoc->sctp_local_addr_list);
785 1.1 rjs TAILQ_INIT(&asoc->nets);
786 1.1 rjs TAILQ_INIT(&asoc->pending_reply_queue);
787 1.1 rjs asoc->last_asconf_ack_sent = NULL;
788 1.1 rjs /* Setup to fill the hb random cache at first HB */
789 1.1 rjs asoc->hb_random_idx = 4;
790 1.1 rjs
791 1.1 rjs asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
792 1.1 rjs
793 1.1 rjs /*
794 1.1 rjs * Now the stream parameters, here we allocate space for all
795 1.1 rjs * streams that we request by default.
796 1.1 rjs */
797 1.1 rjs asoc->streamoutcnt = asoc->pre_open_streams =
798 1.1 rjs m->sctp_ep.pre_open_stream_count;
799 1.1 rjs asoc->strmout = malloc(asoc->streamoutcnt *
800 1.1 rjs sizeof(struct sctp_stream_out), M_PCB, M_NOWAIT);
801 1.1 rjs if (asoc->strmout == NULL) {
802 1.1 rjs /* big trouble no memory */
803 1.1 rjs return (ENOMEM);
804 1.1 rjs }
805 1.1 rjs for (i = 0; i < asoc->streamoutcnt; i++) {
806 1.1 rjs /*
807 1.1 rjs * inbound side must be set to 0xffff,
808 1.1 rjs * also NOTE when we get the INIT-ACK back (for INIT sender)
809 1.1 rjs * we MUST reduce the count (streamoutcnt) but first check
810 1.1 rjs * if we sent to any of the upper streams that were dropped
811 1.1 rjs * (if some were). Those that were dropped must be notified
812 1.1 rjs * to the upper layer as failed to send.
813 1.1 rjs */
814 1.1 rjs asoc->strmout[i].next_sequence_sent = 0x0;
815 1.1 rjs TAILQ_INIT(&asoc->strmout[i].outqueue);
816 1.1 rjs asoc->strmout[i].stream_no = i;
817 1.1 rjs asoc->strmout[i].next_spoke.tqe_next = 0;
818 1.1 rjs asoc->strmout[i].next_spoke.tqe_prev = 0;
819 1.1 rjs }
820 1.1 rjs /* Now the mapping array */
821 1.1 rjs asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
822 1.1 rjs asoc->mapping_array = malloc(asoc->mapping_array_size,
823 1.1 rjs M_PCB, M_NOWAIT);
824 1.1 rjs if (asoc->mapping_array == NULL) {
825 1.1 rjs free(asoc->strmout, M_PCB);
826 1.1 rjs return (ENOMEM);
827 1.1 rjs }
828 1.1 rjs memset(asoc->mapping_array, 0, asoc->mapping_array_size);
829 1.1 rjs /* Now the init of the other outqueues */
830 1.1 rjs TAILQ_INIT(&asoc->out_wheel);
831 1.1 rjs TAILQ_INIT(&asoc->control_send_queue);
832 1.1 rjs TAILQ_INIT(&asoc->send_queue);
833 1.1 rjs TAILQ_INIT(&asoc->sent_queue);
834 1.1 rjs TAILQ_INIT(&asoc->reasmqueue);
835 1.1 rjs TAILQ_INIT(&asoc->delivery_queue);
836 1.1 rjs asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
837 1.1 rjs
838 1.1 rjs TAILQ_INIT(&asoc->asconf_queue);
839 1.1 rjs return (0);
840 1.1 rjs }
841 1.1 rjs
842 1.1 rjs int
843 1.1 rjs sctp_expand_mapping_array(struct sctp_association *asoc)
844 1.1 rjs {
845 1.1 rjs /* mapping array needs to grow */
846 1.1 rjs u_int8_t *new_array;
847 1.1 rjs uint16_t new_size;
848 1.1 rjs
849 1.1 rjs new_size = asoc->mapping_array_size + SCTP_MAPPING_ARRAY_INCR;
850 1.1 rjs new_array = malloc(new_size, M_PCB, M_NOWAIT);
851 1.1 rjs if (new_array == NULL) {
852 1.1 rjs /* can't get more, forget it */
853 1.1 rjs printf("No memory for expansion of SCTP mapping array %d\n",
854 1.1 rjs new_size);
855 1.1 rjs return (-1);
856 1.1 rjs }
857 1.1 rjs memset(new_array, 0, new_size);
858 1.1 rjs memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
859 1.1 rjs free(asoc->mapping_array, M_PCB);
860 1.1 rjs asoc->mapping_array = new_array;
861 1.1 rjs asoc->mapping_array_size = new_size;
862 1.1 rjs return (0);
863 1.1 rjs }
864 1.1 rjs
865 1.1 rjs static void
866 1.1 rjs sctp_timeout_handler(void *t)
867 1.1 rjs {
868 1.1 rjs struct sctp_inpcb *inp;
869 1.1 rjs struct sctp_tcb *stcb;
870 1.1 rjs struct sctp_nets *net;
871 1.1 rjs struct sctp_timer *tmr;
872 1.1 rjs int did_output;
873 1.1 rjs
874 1.1 rjs mutex_enter(softnet_lock);
875 1.1 rjs tmr = (struct sctp_timer *)t;
876 1.1 rjs inp = (struct sctp_inpcb *)tmr->ep;
877 1.1 rjs stcb = (struct sctp_tcb *)tmr->tcb;
878 1.1 rjs net = (struct sctp_nets *)tmr->net;
879 1.1 rjs did_output = 1;
880 1.1 rjs
881 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
882 1.1 rjs sctp_audit_log(0xF0, (u_int8_t)tmr->type);
883 1.1 rjs sctp_auditing(3, inp, stcb, net);
884 1.1 rjs #endif
885 1.1 rjs sctp_pegs[SCTP_TIMERS_EXP]++;
886 1.1 rjs
887 1.1 rjs if (inp == NULL) {
888 1.1 rjs return;
889 1.1 rjs }
890 1.1 rjs
891 1.1 rjs SCTP_INP_WLOCK(inp);
892 1.1 rjs if (inp->sctp_socket == 0) {
893 1.1 rjs mutex_exit(softnet_lock);
894 1.1 rjs SCTP_INP_WUNLOCK(inp);
895 1.1 rjs return;
896 1.1 rjs }
897 1.1 rjs if (stcb) {
898 1.1 rjs if (stcb->asoc.state == 0) {
899 1.1 rjs mutex_exit(softnet_lock);
900 1.1 rjs SCTP_INP_WUNLOCK(inp);
901 1.1 rjs return;
902 1.1 rjs }
903 1.1 rjs }
904 1.1 rjs #ifdef SCTP_DEBUG
905 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
906 1.1 rjs printf("Timer type %d goes off\n", tmr->type);
907 1.1 rjs }
908 1.1 rjs #endif /* SCTP_DEBUG */
909 1.1 rjs #ifndef __NetBSD__
910 1.1 rjs if (!callout_active(&tmr->timer)) {
911 1.1 rjs SCTP_INP_WUNLOCK(inp);
912 1.1 rjs return;
913 1.1 rjs }
914 1.1 rjs #endif
915 1.1 rjs if (stcb) {
916 1.1 rjs SCTP_TCB_LOCK(stcb);
917 1.1 rjs }
918 1.1 rjs SCTP_INP_INCR_REF(inp);
919 1.1 rjs SCTP_INP_WUNLOCK(inp);
920 1.1 rjs
921 1.1 rjs switch (tmr->type) {
922 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR:
923 1.1 rjs {
924 1.1 rjs struct sctp_iterator *it;
925 1.1 rjs it = (struct sctp_iterator *)inp;
926 1.1 rjs sctp_iterator_timer(it);
927 1.1 rjs }
928 1.1 rjs break;
929 1.1 rjs /* call the handler for the appropriate timer type */
930 1.1 rjs case SCTP_TIMER_TYPE_SEND:
931 1.1 rjs sctp_pegs[SCTP_TMIT_TIMER]++;
932 1.1 rjs stcb->asoc.num_send_timers_up--;
933 1.1 rjs if (stcb->asoc.num_send_timers_up < 0) {
934 1.1 rjs stcb->asoc.num_send_timers_up = 0;
935 1.1 rjs }
936 1.1 rjs if (sctp_t3rxt_timer(inp, stcb, net)) {
937 1.1 rjs /* no need to unlock on tcb its gone */
938 1.1 rjs
939 1.1 rjs goto out_decr;
940 1.1 rjs }
941 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
942 1.1 rjs sctp_auditing(4, inp, stcb, net);
943 1.1 rjs #endif
944 1.1 rjs sctp_chunk_output(inp, stcb, 1);
945 1.1 rjs if ((stcb->asoc.num_send_timers_up == 0) &&
946 1.1 rjs (stcb->asoc.sent_queue_cnt > 0)
947 1.1 rjs ) {
948 1.1 rjs struct sctp_tmit_chunk *chk;
949 1.1 rjs /*
950 1.1 rjs * safeguard. If there on some on the sent queue
951 1.1 rjs * somewhere but no timers running something is
952 1.1 rjs * wrong... so we start a timer on the first chunk
953 1.1 rjs * on the send queue on whatever net it is sent to.
954 1.1 rjs */
955 1.1 rjs sctp_pegs[SCTP_T3_SAFEGRD]++;
956 1.1 rjs chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
957 1.1 rjs sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb,
958 1.1 rjs chk->whoTo);
959 1.1 rjs }
960 1.1 rjs break;
961 1.1 rjs case SCTP_TIMER_TYPE_INIT:
962 1.1 rjs if (sctp_t1init_timer(inp, stcb, net)) {
963 1.1 rjs /* no need to unlock on tcb its gone */
964 1.1 rjs goto out_decr;
965 1.1 rjs }
966 1.1 rjs /* We do output but not here */
967 1.1 rjs did_output = 0;
968 1.1 rjs break;
969 1.1 rjs case SCTP_TIMER_TYPE_RECV:
970 1.1 rjs sctp_pegs[SCTP_RECV_TIMER]++;
971 1.1 rjs sctp_send_sack(stcb);
972 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
973 1.1 rjs sctp_auditing(4, inp, stcb, net);
974 1.1 rjs #endif
975 1.1 rjs sctp_chunk_output(inp, stcb, 4);
976 1.1 rjs break;
977 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN:
978 1.1 rjs if (sctp_shutdown_timer(inp, stcb, net) ) {
979 1.1 rjs /* no need to unlock on tcb its gone */
980 1.1 rjs goto out_decr;
981 1.1 rjs }
982 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
983 1.1 rjs sctp_auditing(4, inp, stcb, net);
984 1.1 rjs #endif
985 1.1 rjs sctp_chunk_output(inp, stcb, 5);
986 1.1 rjs break;
987 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT:
988 1.1 rjs if (sctp_heartbeat_timer(inp, stcb, net)) {
989 1.1 rjs /* no need to unlock on tcb its gone */
990 1.1 rjs goto out_decr;
991 1.1 rjs }
992 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
993 1.1 rjs sctp_auditing(4, inp, stcb, net);
994 1.1 rjs #endif
995 1.1 rjs sctp_chunk_output(inp, stcb, 6);
996 1.1 rjs break;
997 1.1 rjs case SCTP_TIMER_TYPE_COOKIE:
998 1.1 rjs if (sctp_cookie_timer(inp, stcb, net)) {
999 1.1 rjs /* no need to unlock on tcb its gone */
1000 1.1 rjs goto out_decr;
1001 1.1 rjs }
1002 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
1003 1.1 rjs sctp_auditing(4, inp, stcb, net);
1004 1.1 rjs #endif
1005 1.1 rjs sctp_chunk_output(inp, stcb, 1);
1006 1.1 rjs break;
1007 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE:
1008 1.1 rjs {
1009 1.1 rjs struct timeval tv;
1010 1.1 rjs int i, secret;
1011 1.1 rjs SCTP_GETTIME_TIMEVAL(&tv);
1012 1.1 rjs SCTP_INP_WLOCK(inp);
1013 1.1 rjs inp->sctp_ep.time_of_secret_change = tv.tv_sec;
1014 1.1 rjs inp->sctp_ep.last_secret_number =
1015 1.1 rjs inp->sctp_ep.current_secret_number;
1016 1.1 rjs inp->sctp_ep.current_secret_number++;
1017 1.1 rjs if (inp->sctp_ep.current_secret_number >=
1018 1.1 rjs SCTP_HOW_MANY_SECRETS) {
1019 1.1 rjs inp->sctp_ep.current_secret_number = 0;
1020 1.1 rjs }
1021 1.1 rjs secret = (int)inp->sctp_ep.current_secret_number;
1022 1.1 rjs for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) {
1023 1.1 rjs inp->sctp_ep.secret_key[secret][i] =
1024 1.1 rjs sctp_select_initial_TSN(&inp->sctp_ep);
1025 1.1 rjs }
1026 1.1 rjs SCTP_INP_WUNLOCK(inp);
1027 1.1 rjs sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net);
1028 1.1 rjs }
1029 1.1 rjs did_output = 0;
1030 1.1 rjs break;
1031 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE:
1032 1.1 rjs sctp_pathmtu_timer(inp, stcb, net);
1033 1.1 rjs did_output = 0;
1034 1.1 rjs break;
1035 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK:
1036 1.1 rjs if (sctp_shutdownack_timer(inp, stcb, net)) {
1037 1.1 rjs /* no need to unlock on tcb its gone */
1038 1.1 rjs goto out_decr;
1039 1.1 rjs }
1040 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
1041 1.1 rjs sctp_auditing(4, inp, stcb, net);
1042 1.1 rjs #endif
1043 1.1 rjs sctp_chunk_output(inp, stcb, 7);
1044 1.1 rjs break;
1045 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
1046 1.1 rjs sctp_abort_an_association(inp, stcb,
1047 1.1 rjs SCTP_SHUTDOWN_GUARD_EXPIRES, NULL);
1048 1.1 rjs /* no need to unlock on tcb its gone */
1049 1.1 rjs goto out_decr;
1050 1.1 rjs break;
1051 1.1 rjs
1052 1.1 rjs case SCTP_TIMER_TYPE_STRRESET:
1053 1.1 rjs if (sctp_strreset_timer(inp, stcb, net)) {
1054 1.1 rjs /* no need to unlock on tcb its gone */
1055 1.1 rjs goto out_decr;
1056 1.1 rjs }
1057 1.1 rjs sctp_chunk_output(inp, stcb, 9);
1058 1.1 rjs break;
1059 1.1 rjs
1060 1.1 rjs case SCTP_TIMER_TYPE_ASCONF:
1061 1.1 rjs if (sctp_asconf_timer(inp, stcb, net)) {
1062 1.1 rjs /* no need to unlock on tcb its gone */
1063 1.1 rjs goto out_decr;
1064 1.1 rjs }
1065 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
1066 1.1 rjs sctp_auditing(4, inp, stcb, net);
1067 1.1 rjs #endif
1068 1.1 rjs sctp_chunk_output(inp, stcb, 8);
1069 1.1 rjs break;
1070 1.1 rjs
1071 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE:
1072 1.1 rjs sctp_autoclose_timer(inp, stcb, net);
1073 1.1 rjs sctp_chunk_output(inp, stcb, 10);
1074 1.1 rjs did_output = 0;
1075 1.1 rjs break;
1076 1.1 rjs case SCTP_TIMER_TYPE_INPKILL:
1077 1.1 rjs /* special case, take away our
1078 1.1 rjs * increment since WE are the killer
1079 1.1 rjs */
1080 1.1 rjs SCTP_INP_WLOCK(inp);
1081 1.1 rjs SCTP_INP_DECR_REF(inp);
1082 1.1 rjs SCTP_INP_WUNLOCK(inp);
1083 1.1 rjs sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
1084 1.1 rjs sctp_inpcb_free(inp, 1);
1085 1.1 rjs goto out_no_decr;
1086 1.1 rjs break;
1087 1.1 rjs default:
1088 1.1 rjs #ifdef SCTP_DEBUG
1089 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1090 1.1 rjs printf("sctp_timeout_handler:unknown timer %d\n",
1091 1.1 rjs tmr->type);
1092 1.1 rjs }
1093 1.1 rjs #endif /* SCTP_DEBUG */
1094 1.1 rjs break;
1095 1.1 rjs };
1096 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
1097 1.1 rjs sctp_audit_log(0xF1, (u_int8_t)tmr->type);
1098 1.1 rjs sctp_auditing(5, inp, stcb, net);
1099 1.1 rjs #endif
1100 1.1 rjs if (did_output) {
1101 1.1 rjs /*
1102 1.1 rjs * Now we need to clean up the control chunk chain if an
1103 1.1 rjs * ECNE is on it. It must be marked as UNSENT again so next
1104 1.1 rjs * call will continue to send it until such time that we get
1105 1.1 rjs * a CWR, to remove it. It is, however, less likely that we
1106 1.1 rjs * will find a ecn echo on the chain though.
1107 1.1 rjs */
1108 1.1 rjs sctp_fix_ecn_echo(&stcb->asoc);
1109 1.1 rjs }
1110 1.1 rjs if (stcb) {
1111 1.1 rjs SCTP_TCB_UNLOCK(stcb);
1112 1.1 rjs }
1113 1.1 rjs out_decr:
1114 1.1 rjs SCTP_INP_WLOCK(inp);
1115 1.1 rjs SCTP_INP_DECR_REF(inp);
1116 1.1 rjs SCTP_INP_WUNLOCK(inp);
1117 1.1 rjs
1118 1.1 rjs out_no_decr:
1119 1.1 rjs
1120 1.1 rjs mutex_exit(softnet_lock);
1121 1.1 rjs }
1122 1.1 rjs
1123 1.1 rjs int
1124 1.1 rjs sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1125 1.1 rjs struct sctp_nets *net)
1126 1.1 rjs {
1127 1.1 rjs int to_ticks;
1128 1.1 rjs struct sctp_timer *tmr;
1129 1.1 rjs
1130 1.1 rjs if (inp == NULL)
1131 1.1 rjs return (EFAULT);
1132 1.1 rjs
1133 1.1 rjs to_ticks = 0;
1134 1.1 rjs
1135 1.1 rjs tmr = NULL;
1136 1.1 rjs switch (t_type) {
1137 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR:
1138 1.1 rjs {
1139 1.1 rjs struct sctp_iterator *it;
1140 1.1 rjs it = (struct sctp_iterator *)inp;
1141 1.1 rjs tmr = &it->tmr;
1142 1.1 rjs to_ticks = SCTP_ITERATOR_TICKS;
1143 1.1 rjs }
1144 1.1 rjs break;
1145 1.1 rjs case SCTP_TIMER_TYPE_SEND:
1146 1.1 rjs /* Here we use the RTO timer */
1147 1.1 rjs {
1148 1.1 rjs int rto_val;
1149 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1150 1.1 rjs return (EFAULT);
1151 1.1 rjs }
1152 1.1 rjs tmr = &net->rxt_timer;
1153 1.1 rjs if (net->RTO == 0) {
1154 1.1 rjs rto_val = stcb->asoc.initial_rto;
1155 1.1 rjs } else {
1156 1.1 rjs rto_val = net->RTO;
1157 1.1 rjs }
1158 1.1 rjs to_ticks = MSEC_TO_TICKS(rto_val);
1159 1.1 rjs }
1160 1.1 rjs break;
1161 1.1 rjs case SCTP_TIMER_TYPE_INIT:
1162 1.1 rjs /*
1163 1.1 rjs * Here we use the INIT timer default
1164 1.1 rjs * usually about 1 minute.
1165 1.1 rjs */
1166 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1167 1.1 rjs return (EFAULT);
1168 1.1 rjs }
1169 1.1 rjs tmr = &net->rxt_timer;
1170 1.1 rjs if (net->RTO == 0) {
1171 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1172 1.1 rjs } else {
1173 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1174 1.1 rjs }
1175 1.1 rjs break;
1176 1.1 rjs case SCTP_TIMER_TYPE_RECV:
1177 1.1 rjs /*
1178 1.1 rjs * Here we use the Delayed-Ack timer value from the inp
1179 1.1 rjs * ususually about 200ms.
1180 1.1 rjs */
1181 1.1 rjs if (stcb == NULL) {
1182 1.1 rjs return (EFAULT);
1183 1.1 rjs }
1184 1.1 rjs tmr = &stcb->asoc.dack_timer;
1185 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV];
1186 1.1 rjs break;
1187 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN:
1188 1.1 rjs /* Here we use the RTO of the destination. */
1189 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1190 1.1 rjs return (EFAULT);
1191 1.1 rjs }
1192 1.1 rjs
1193 1.1 rjs if (net->RTO == 0) {
1194 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1195 1.1 rjs } else {
1196 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1197 1.1 rjs }
1198 1.1 rjs tmr = &net->rxt_timer;
1199 1.1 rjs break;
1200 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT:
1201 1.1 rjs /*
1202 1.1 rjs * the net is used here so that we can add in the RTO.
1203 1.1 rjs * Even though we use a different timer. We also add the
1204 1.1 rjs * HB timer PLUS a random jitter.
1205 1.1 rjs */
1206 1.1 rjs if (stcb == NULL) {
1207 1.1 rjs return (EFAULT);
1208 1.1 rjs }
1209 1.1 rjs {
1210 1.1 rjs uint32_t rndval;
1211 1.1 rjs uint8_t this_random;
1212 1.1 rjs int cnt_of_unconf=0;
1213 1.1 rjs struct sctp_nets *lnet;
1214 1.1 rjs
1215 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
1216 1.1 rjs if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
1217 1.1 rjs cnt_of_unconf++;
1218 1.1 rjs }
1219 1.1 rjs }
1220 1.1 rjs #ifdef SCTP_DEBUG
1221 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1222 1.1 rjs printf("HB timer to start unconfirmed:%d hb_delay:%d\n",
1223 1.1 rjs cnt_of_unconf, stcb->asoc.heart_beat_delay);
1224 1.1 rjs }
1225 1.1 rjs #endif
1226 1.1 rjs if (stcb->asoc.hb_random_idx > 3) {
1227 1.1 rjs rndval = sctp_select_initial_TSN(&inp->sctp_ep);
1228 1.1 rjs memcpy(stcb->asoc.hb_random_values, &rndval,
1229 1.1 rjs sizeof(stcb->asoc.hb_random_values));
1230 1.1 rjs this_random = stcb->asoc.hb_random_values[0];
1231 1.1 rjs stcb->asoc.hb_random_idx = 0;
1232 1.1 rjs stcb->asoc.hb_ect_randombit = 0;
1233 1.1 rjs } else {
1234 1.1 rjs this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx];
1235 1.1 rjs stcb->asoc.hb_random_idx++;
1236 1.1 rjs stcb->asoc.hb_ect_randombit = 0;
1237 1.1 rjs }
1238 1.1 rjs /*
1239 1.1 rjs * this_random will be 0 - 256 ms
1240 1.1 rjs * RTO is in ms.
1241 1.1 rjs */
1242 1.1 rjs if ((stcb->asoc.heart_beat_delay == 0) &&
1243 1.1 rjs (cnt_of_unconf == 0)) {
1244 1.1 rjs /* no HB on this inp after confirmations */
1245 1.1 rjs return (0);
1246 1.1 rjs }
1247 1.1 rjs if (net) {
1248 1.1 rjs int delay;
1249 1.1 rjs delay = stcb->asoc.heart_beat_delay;
1250 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
1251 1.1 rjs if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) &&
1252 1.1 rjs ((lnet->dest_state & SCTP_ADDR_OUT_OF_SCOPE) == 0) &&
1253 1.1 rjs (lnet->dest_state & SCTP_ADDR_REACHABLE)) {
1254 1.1 rjs delay = 0;
1255 1.1 rjs }
1256 1.1 rjs }
1257 1.1 rjs if (net->RTO == 0) {
1258 1.1 rjs /* Never been checked */
1259 1.1 rjs to_ticks = this_random + stcb->asoc.initial_rto + delay;
1260 1.1 rjs } else {
1261 1.1 rjs /* set rto_val to the ms */
1262 1.1 rjs to_ticks = delay + net->RTO + this_random;
1263 1.1 rjs }
1264 1.1 rjs } else {
1265 1.1 rjs if (cnt_of_unconf) {
1266 1.1 rjs to_ticks = this_random + stcb->asoc.initial_rto;
1267 1.1 rjs } else {
1268 1.1 rjs to_ticks = stcb->asoc.heart_beat_delay + this_random + stcb->asoc.initial_rto;
1269 1.1 rjs }
1270 1.1 rjs }
1271 1.1 rjs /*
1272 1.1 rjs * Now we must convert the to_ticks that are now in
1273 1.1 rjs * ms to ticks.
1274 1.1 rjs */
1275 1.1 rjs to_ticks *= hz;
1276 1.1 rjs to_ticks /= 1000;
1277 1.1 rjs #ifdef SCTP_DEBUG
1278 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1279 1.1 rjs printf("Timer to expire in %d ticks\n", to_ticks);
1280 1.1 rjs }
1281 1.1 rjs #endif
1282 1.1 rjs tmr = &stcb->asoc.hb_timer;
1283 1.1 rjs }
1284 1.1 rjs break;
1285 1.1 rjs case SCTP_TIMER_TYPE_COOKIE:
1286 1.1 rjs /*
1287 1.1 rjs * Here we can use the RTO timer from the network since
1288 1.1 rjs * one RTT was compelete. If a retran happened then we will
1289 1.1 rjs * be using the RTO initial value.
1290 1.1 rjs */
1291 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1292 1.1 rjs return (EFAULT);
1293 1.1 rjs }
1294 1.1 rjs if (net->RTO == 0) {
1295 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1296 1.1 rjs } else {
1297 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1298 1.1 rjs }
1299 1.1 rjs tmr = &net->rxt_timer;
1300 1.1 rjs break;
1301 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE:
1302 1.1 rjs /*
1303 1.1 rjs * nothing needed but the endpoint here
1304 1.1 rjs * ususually about 60 minutes.
1305 1.1 rjs */
1306 1.1 rjs tmr = &inp->sctp_ep.signature_change;
1307 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
1308 1.1 rjs break;
1309 1.1 rjs case SCTP_TIMER_TYPE_INPKILL:
1310 1.1 rjs /*
1311 1.1 rjs * The inp is setup to die. We re-use the
1312 1.1 rjs * signature_chage timer since that has
1313 1.1 rjs * stopped and we are in the GONE state.
1314 1.1 rjs */
1315 1.1 rjs tmr = &inp->sctp_ep.signature_change;
1316 1.1 rjs to_ticks = (SCTP_INP_KILL_TIMEOUT * hz) / 1000;
1317 1.1 rjs break;
1318 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE:
1319 1.1 rjs /*
1320 1.1 rjs * Here we use the value found in the EP for PMTU
1321 1.1 rjs * ususually about 10 minutes.
1322 1.1 rjs */
1323 1.1 rjs if (stcb == NULL) {
1324 1.1 rjs return (EFAULT);
1325 1.1 rjs }
1326 1.1 rjs if (net == NULL) {
1327 1.1 rjs return (EFAULT);
1328 1.1 rjs }
1329 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
1330 1.1 rjs tmr = &net->pmtu_timer;
1331 1.1 rjs break;
1332 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK:
1333 1.1 rjs /* Here we use the RTO of the destination */
1334 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1335 1.1 rjs return (EFAULT);
1336 1.1 rjs }
1337 1.1 rjs if (net->RTO == 0) {
1338 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1339 1.1 rjs } else {
1340 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1341 1.1 rjs }
1342 1.1 rjs tmr = &net->rxt_timer;
1343 1.1 rjs break;
1344 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
1345 1.1 rjs /*
1346 1.1 rjs * Here we use the endpoints shutdown guard timer
1347 1.1 rjs * usually about 3 minutes.
1348 1.1 rjs */
1349 1.1 rjs if (stcb == NULL) {
1350 1.1 rjs return (EFAULT);
1351 1.1 rjs }
1352 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
1353 1.1 rjs tmr = &stcb->asoc.shut_guard_timer;
1354 1.1 rjs break;
1355 1.1 rjs case SCTP_TIMER_TYPE_STRRESET:
1356 1.1 rjs /*
1357 1.1 rjs * Here the timer comes from the inp
1358 1.1 rjs * but its value is from the RTO.
1359 1.1 rjs */
1360 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1361 1.1 rjs return (EFAULT);
1362 1.1 rjs }
1363 1.1 rjs if (net->RTO == 0) {
1364 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1365 1.1 rjs } else {
1366 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1367 1.1 rjs }
1368 1.1 rjs tmr = &stcb->asoc.strreset_timer;
1369 1.1 rjs break;
1370 1.1 rjs
1371 1.1 rjs case SCTP_TIMER_TYPE_ASCONF:
1372 1.1 rjs /*
1373 1.1 rjs * Here the timer comes from the inp
1374 1.1 rjs * but its value is from the RTO.
1375 1.1 rjs */
1376 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1377 1.1 rjs return (EFAULT);
1378 1.1 rjs }
1379 1.1 rjs if (net->RTO == 0) {
1380 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
1381 1.1 rjs } else {
1382 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO);
1383 1.1 rjs }
1384 1.1 rjs tmr = &stcb->asoc.asconf_timer;
1385 1.1 rjs break;
1386 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE:
1387 1.1 rjs if (stcb == NULL) {
1388 1.1 rjs return (EFAULT);
1389 1.1 rjs }
1390 1.1 rjs if (stcb->asoc.sctp_autoclose_ticks == 0) {
1391 1.1 rjs /* Really an error since stcb is NOT set to autoclose */
1392 1.1 rjs return (0);
1393 1.1 rjs }
1394 1.1 rjs to_ticks = stcb->asoc.sctp_autoclose_ticks;
1395 1.1 rjs tmr = &stcb->asoc.autoclose_timer;
1396 1.1 rjs break;
1397 1.1 rjs default:
1398 1.1 rjs #ifdef SCTP_DEBUG
1399 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1400 1.1 rjs printf("sctp_timer_start:Unknown timer type %d\n",
1401 1.1 rjs t_type);
1402 1.1 rjs }
1403 1.1 rjs #endif /* SCTP_DEBUG */
1404 1.1 rjs return (EFAULT);
1405 1.1 rjs break;
1406 1.1 rjs };
1407 1.1 rjs if ((to_ticks <= 0) || (tmr == NULL)) {
1408 1.1 rjs #ifdef SCTP_DEBUG
1409 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1410 1.1 rjs printf("sctp_timer_start:%d:software error to_ticks:%d tmr:%p not set ??\n",
1411 1.1 rjs t_type, to_ticks, tmr);
1412 1.1 rjs }
1413 1.1 rjs #endif /* SCTP_DEBUG */
1414 1.1 rjs return (EFAULT);
1415 1.1 rjs }
1416 1.1 rjs if (callout_pending(&tmr->timer)) {
1417 1.1 rjs /*
1418 1.1 rjs * we do NOT allow you to have it already running.
1419 1.1 rjs * if it is we leave the current one up unchanged
1420 1.1 rjs */
1421 1.1 rjs return (EALREADY);
1422 1.1 rjs }
1423 1.1 rjs /* At this point we can proceed */
1424 1.1 rjs if (t_type == SCTP_TIMER_TYPE_SEND) {
1425 1.1 rjs stcb->asoc.num_send_timers_up++;
1426 1.1 rjs }
1427 1.1 rjs tmr->type = t_type;
1428 1.1 rjs tmr->ep = (void *)inp;
1429 1.1 rjs tmr->tcb = (void *)stcb;
1430 1.1 rjs tmr->net = (void *)net;
1431 1.1 rjs callout_reset(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
1432 1.1 rjs return (0);
1433 1.1 rjs }
1434 1.1 rjs
1435 1.1 rjs int
1436 1.1 rjs sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1437 1.1 rjs struct sctp_nets *net)
1438 1.1 rjs {
1439 1.1 rjs struct sctp_timer *tmr;
1440 1.1 rjs
1441 1.1 rjs if (inp == NULL)
1442 1.1 rjs return (EFAULT);
1443 1.1 rjs
1444 1.1 rjs tmr = NULL;
1445 1.1 rjs switch (t_type) {
1446 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR:
1447 1.1 rjs {
1448 1.1 rjs struct sctp_iterator *it;
1449 1.1 rjs it = (struct sctp_iterator *)inp;
1450 1.1 rjs tmr = &it->tmr;
1451 1.1 rjs }
1452 1.1 rjs break;
1453 1.1 rjs case SCTP_TIMER_TYPE_SEND:
1454 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1455 1.1 rjs return (EFAULT);
1456 1.1 rjs }
1457 1.1 rjs tmr = &net->rxt_timer;
1458 1.1 rjs break;
1459 1.1 rjs case SCTP_TIMER_TYPE_INIT:
1460 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1461 1.1 rjs return (EFAULT);
1462 1.1 rjs }
1463 1.1 rjs tmr = &net->rxt_timer;
1464 1.1 rjs break;
1465 1.1 rjs case SCTP_TIMER_TYPE_RECV:
1466 1.1 rjs if (stcb == NULL) {
1467 1.1 rjs return (EFAULT);
1468 1.1 rjs }
1469 1.1 rjs tmr = &stcb->asoc.dack_timer;
1470 1.1 rjs break;
1471 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN:
1472 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1473 1.1 rjs return (EFAULT);
1474 1.1 rjs }
1475 1.1 rjs tmr = &net->rxt_timer;
1476 1.1 rjs break;
1477 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT:
1478 1.1 rjs if (stcb == NULL) {
1479 1.1 rjs return (EFAULT);
1480 1.1 rjs }
1481 1.1 rjs tmr = &stcb->asoc.hb_timer;
1482 1.1 rjs break;
1483 1.1 rjs case SCTP_TIMER_TYPE_COOKIE:
1484 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1485 1.1 rjs return (EFAULT);
1486 1.1 rjs }
1487 1.1 rjs tmr = &net->rxt_timer;
1488 1.1 rjs break;
1489 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE:
1490 1.1 rjs /* nothing needed but the endpoint here */
1491 1.1 rjs tmr = &inp->sctp_ep.signature_change;
1492 1.1 rjs /* We re-use the newcookie timer for
1493 1.1 rjs * the INP kill timer. We must assure
1494 1.1 rjs * that we do not kill it by accident.
1495 1.1 rjs */
1496 1.1 rjs break;
1497 1.1 rjs case SCTP_TIMER_TYPE_INPKILL:
1498 1.1 rjs /*
1499 1.1 rjs * The inp is setup to die. We re-use the
1500 1.1 rjs * signature_chage timer since that has
1501 1.1 rjs * stopped and we are in the GONE state.
1502 1.1 rjs */
1503 1.1 rjs tmr = &inp->sctp_ep.signature_change;
1504 1.1 rjs break;
1505 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE:
1506 1.1 rjs if (stcb == NULL) {
1507 1.1 rjs return (EFAULT);
1508 1.1 rjs }
1509 1.1 rjs if (net == NULL) {
1510 1.1 rjs return (EFAULT);
1511 1.1 rjs }
1512 1.1 rjs tmr = &net->pmtu_timer;
1513 1.1 rjs break;
1514 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK:
1515 1.1 rjs if ((stcb == NULL) || (net == NULL)) {
1516 1.1 rjs return (EFAULT);
1517 1.1 rjs }
1518 1.1 rjs tmr = &net->rxt_timer;
1519 1.1 rjs break;
1520 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
1521 1.1 rjs if (stcb == NULL) {
1522 1.1 rjs return (EFAULT);
1523 1.1 rjs }
1524 1.1 rjs tmr = &stcb->asoc.shut_guard_timer;
1525 1.1 rjs break;
1526 1.1 rjs case SCTP_TIMER_TYPE_STRRESET:
1527 1.1 rjs if (stcb == NULL) {
1528 1.1 rjs return (EFAULT);
1529 1.1 rjs }
1530 1.1 rjs tmr = &stcb->asoc.strreset_timer;
1531 1.1 rjs break;
1532 1.1 rjs case SCTP_TIMER_TYPE_ASCONF:
1533 1.1 rjs if (stcb == NULL) {
1534 1.1 rjs return (EFAULT);
1535 1.1 rjs }
1536 1.1 rjs tmr = &stcb->asoc.asconf_timer;
1537 1.1 rjs break;
1538 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE:
1539 1.1 rjs if (stcb == NULL) {
1540 1.1 rjs return (EFAULT);
1541 1.1 rjs }
1542 1.1 rjs tmr = &stcb->asoc.autoclose_timer;
1543 1.1 rjs break;
1544 1.1 rjs default:
1545 1.1 rjs #ifdef SCTP_DEBUG
1546 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) {
1547 1.1 rjs printf("sctp_timer_stop:Unknown timer type %d\n",
1548 1.1 rjs t_type);
1549 1.1 rjs }
1550 1.1 rjs #endif /* SCTP_DEBUG */
1551 1.1 rjs break;
1552 1.1 rjs };
1553 1.1 rjs if (tmr == NULL)
1554 1.1 rjs return (EFAULT);
1555 1.1 rjs
1556 1.1 rjs if ((tmr->type != t_type) && tmr->type) {
1557 1.1 rjs /*
1558 1.1 rjs * Ok we have a timer that is under joint use. Cookie timer
1559 1.1 rjs * per chance with the SEND timer. We therefore are NOT
1560 1.1 rjs * running the timer that the caller wants stopped. So just
1561 1.1 rjs * return.
1562 1.1 rjs */
1563 1.1 rjs return (0);
1564 1.1 rjs }
1565 1.1 rjs if (t_type == SCTP_TIMER_TYPE_SEND) {
1566 1.1 rjs stcb->asoc.num_send_timers_up--;
1567 1.1 rjs if (stcb->asoc.num_send_timers_up < 0) {
1568 1.1 rjs stcb->asoc.num_send_timers_up = 0;
1569 1.1 rjs }
1570 1.1 rjs }
1571 1.1 rjs callout_stop(&tmr->timer);
1572 1.1 rjs return (0);
1573 1.1 rjs }
1574 1.1 rjs
1575 1.1 rjs #ifdef SCTP_USE_ADLER32
1576 1.1 rjs static uint32_t
1577 1.1 rjs update_adler32(uint32_t adler, uint8_t *buf, int32_t len)
1578 1.1 rjs {
1579 1.1 rjs u_int32_t s1 = adler & 0xffff;
1580 1.1 rjs u_int32_t s2 = (adler >> 16) & 0xffff;
1581 1.1 rjs int n;
1582 1.1 rjs
1583 1.1 rjs for (n = 0; n < len; n++, buf++) {
1584 1.1 rjs /* s1 = (s1 + buf[n]) % BASE */
1585 1.1 rjs /* first we add */
1586 1.1 rjs s1 = (s1 + *buf);
1587 1.1 rjs /*
1588 1.1 rjs * now if we need to, we do a mod by subtracting. It seems
1589 1.1 rjs * a bit faster since I really will only ever do one subtract
1590 1.1 rjs * at the MOST, since buf[n] is a max of 255.
1591 1.1 rjs */
1592 1.1 rjs if (s1 >= SCTP_ADLER32_BASE) {
1593 1.1 rjs s1 -= SCTP_ADLER32_BASE;
1594 1.1 rjs }
1595 1.1 rjs /* s2 = (s2 + s1) % BASE */
1596 1.1 rjs /* first we add */
1597 1.1 rjs s2 = (s2 + s1);
1598 1.1 rjs /*
1599 1.1 rjs * again, it is more efficent (it seems) to subtract since
1600 1.1 rjs * the most s2 will ever be is (BASE-1 + BASE-1) in the worse
1601 1.1 rjs * case. This would then be (2 * BASE) - 2, which will still
1602 1.1 rjs * only do one subtract. On Intel this is much better to do
1603 1.1 rjs * this way and avoid the divide. Have not -pg'd on sparc.
1604 1.1 rjs */
1605 1.1 rjs if (s2 >= SCTP_ADLER32_BASE) {
1606 1.1 rjs s2 -= SCTP_ADLER32_BASE;
1607 1.1 rjs }
1608 1.1 rjs }
1609 1.1 rjs /* Return the adler32 of the bytes buf[0..len-1] */
1610 1.1 rjs return ((s2 << 16) + s1);
1611 1.1 rjs }
1612 1.1 rjs
1613 1.1 rjs #endif
1614 1.1 rjs
1615 1.1 rjs
1616 1.1 rjs u_int32_t
1617 1.1 rjs sctp_calculate_len(struct mbuf *m)
1618 1.1 rjs {
1619 1.1 rjs u_int32_t tlen=0;
1620 1.1 rjs struct mbuf *at;
1621 1.1 rjs at = m;
1622 1.1 rjs while (at) {
1623 1.1 rjs tlen += at->m_len;
1624 1.1 rjs at = at->m_next;
1625 1.1 rjs }
1626 1.1 rjs return (tlen);
1627 1.1 rjs }
1628 1.1 rjs
1629 1.1 rjs #if defined(SCTP_WITH_NO_CSUM)
1630 1.1 rjs
1631 1.1 rjs uint32_t
1632 1.1 rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
1633 1.1 rjs {
1634 1.1 rjs /*
1635 1.1 rjs * given a mbuf chain with a packetheader offset by 'offset'
1636 1.1 rjs * pointing at a sctphdr (with csum set to 0) go through
1637 1.1 rjs * the chain of m_next's and calculate the SCTP checksum.
1638 1.1 rjs * This is currently Adler32 but will change to CRC32x
1639 1.1 rjs * soon. Also has a side bonus calculate the total length
1640 1.1 rjs * of the mbuf chain.
1641 1.1 rjs * Note: if offset is greater than the total mbuf length,
1642 1.1 rjs * checksum=1, pktlen=0 is returned (ie. no real error code)
1643 1.1 rjs */
1644 1.1 rjs if (pktlen == NULL)
1645 1.1 rjs return (0);
1646 1.1 rjs *pktlen = sctp_calculate_len(m);
1647 1.1 rjs return (0);
1648 1.1 rjs }
1649 1.1 rjs
1650 1.1 rjs #elif defined(SCTP_USE_INCHKSUM)
1651 1.1 rjs
1652 1.1 rjs #include <machine/in_cksum.h>
1653 1.1 rjs
1654 1.1 rjs uint32_t
1655 1.1 rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
1656 1.1 rjs {
1657 1.1 rjs /*
1658 1.1 rjs * given a mbuf chain with a packetheader offset by 'offset'
1659 1.1 rjs * pointing at a sctphdr (with csum set to 0) go through
1660 1.1 rjs * the chain of m_next's and calculate the SCTP checksum.
1661 1.1 rjs * This is currently Adler32 but will change to CRC32x
1662 1.1 rjs * soon. Also has a side bonus calculate the total length
1663 1.1 rjs * of the mbuf chain.
1664 1.1 rjs * Note: if offset is greater than the total mbuf length,
1665 1.1 rjs * checksum=1, pktlen=0 is returned (ie. no real error code)
1666 1.1 rjs */
1667 1.1 rjs int32_t tlen=0;
1668 1.1 rjs struct mbuf *at;
1669 1.1 rjs uint32_t the_sum, retsum;
1670 1.1 rjs
1671 1.1 rjs at = m;
1672 1.1 rjs while (at) {
1673 1.1 rjs tlen += at->m_len;
1674 1.1 rjs at = at->m_next;
1675 1.1 rjs }
1676 1.1 rjs the_sum = (uint32_t)(in_cksum_skip(m, tlen, offset));
1677 1.1 rjs if (pktlen != NULL)
1678 1.1 rjs *pktlen = (tlen-offset);
1679 1.1 rjs retsum = htons(the_sum);
1680 1.1 rjs return (the_sum);
1681 1.1 rjs }
1682 1.1 rjs
1683 1.1 rjs #else
1684 1.1 rjs
1685 1.1 rjs uint32_t
1686 1.1 rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset)
1687 1.1 rjs {
1688 1.1 rjs /*
1689 1.1 rjs * given a mbuf chain with a packetheader offset by 'offset'
1690 1.1 rjs * pointing at a sctphdr (with csum set to 0) go through
1691 1.1 rjs * the chain of m_next's and calculate the SCTP checksum.
1692 1.1 rjs * This is currently Adler32 but will change to CRC32x
1693 1.1 rjs * soon. Also has a side bonus calculate the total length
1694 1.1 rjs * of the mbuf chain.
1695 1.1 rjs * Note: if offset is greater than the total mbuf length,
1696 1.1 rjs * checksum=1, pktlen=0 is returned (ie. no real error code)
1697 1.1 rjs */
1698 1.1 rjs int32_t tlen=0;
1699 1.1 rjs #ifdef SCTP_USE_ADLER32
1700 1.1 rjs uint32_t base = 1L;
1701 1.1 rjs #else
1702 1.1 rjs uint32_t base = 0xffffffff;
1703 1.1 rjs #endif /* SCTP_USE_ADLER32 */
1704 1.1 rjs struct mbuf *at;
1705 1.1 rjs at = m;
1706 1.1 rjs /* find the correct mbuf and offset into mbuf */
1707 1.1 rjs while ((at != NULL) && (offset > (uint32_t)at->m_len)) {
1708 1.1 rjs offset -= at->m_len; /* update remaining offset left */
1709 1.1 rjs at = at->m_next;
1710 1.1 rjs }
1711 1.1 rjs
1712 1.1 rjs while (at != NULL) {
1713 1.1 rjs #ifdef SCTP_USE_ADLER32
1714 1.1 rjs base = update_adler32(base, at->m_data + offset,
1715 1.1 rjs at->m_len - offset);
1716 1.1 rjs #else
1717 1.1 rjs base = update_crc32(base, at->m_data + offset,
1718 1.1 rjs at->m_len - offset);
1719 1.1 rjs #endif /* SCTP_USE_ADLER32 */
1720 1.1 rjs tlen += at->m_len - offset;
1721 1.1 rjs /* we only offset once into the first mbuf */
1722 1.1 rjs if (offset) {
1723 1.1 rjs offset = 0;
1724 1.1 rjs }
1725 1.1 rjs at = at->m_next;
1726 1.1 rjs }
1727 1.1 rjs if (pktlen != NULL) {
1728 1.1 rjs *pktlen = tlen;
1729 1.1 rjs }
1730 1.1 rjs #ifdef SCTP_USE_ADLER32
1731 1.1 rjs /* Adler32 */
1732 1.1 rjs base = htonl(base);
1733 1.1 rjs #else
1734 1.1 rjs /* CRC-32c */
1735 1.1 rjs base = sctp_csum_finalize(base);
1736 1.1 rjs #endif
1737 1.1 rjs return (base);
1738 1.1 rjs }
1739 1.1 rjs
1740 1.1 rjs
1741 1.1 rjs #endif
1742 1.1 rjs
1743 1.1 rjs void
1744 1.1 rjs sctp_mtu_size_reset(struct sctp_inpcb *inp,
1745 1.1 rjs struct sctp_association *asoc, u_long mtu)
1746 1.1 rjs {
1747 1.1 rjs /*
1748 1.1 rjs * Reset the P-MTU size on this association, this involves changing
1749 1.1 rjs * the asoc MTU, going through ANY chunk+overhead larger than mtu
1750 1.1 rjs * to allow the DF flag to be cleared.
1751 1.1 rjs */
1752 1.1 rjs struct sctp_tmit_chunk *chk;
1753 1.1 rjs struct sctp_stream_out *strm;
1754 1.1 rjs unsigned int eff_mtu, ovh;
1755 1.1 rjs asoc->smallest_mtu = mtu;
1756 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1757 1.1 rjs ovh = SCTP_MIN_OVERHEAD;
1758 1.1 rjs } else {
1759 1.1 rjs ovh = SCTP_MIN_V4_OVERHEAD;
1760 1.1 rjs }
1761 1.1 rjs eff_mtu = mtu - ovh;
1762 1.1 rjs /* Now mark any chunks that need to let IP fragment */
1763 1.1 rjs TAILQ_FOREACH(strm, &asoc->out_wheel, next_spoke) {
1764 1.1 rjs TAILQ_FOREACH(chk, &strm->outqueue, sctp_next) {
1765 1.1 rjs if (chk->send_size > eff_mtu) {
1766 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT;
1767 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
1768 1.1 rjs }
1769 1.1 rjs }
1770 1.1 rjs }
1771 1.1 rjs TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
1772 1.1 rjs if (chk->send_size > eff_mtu) {
1773 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT;
1774 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
1775 1.1 rjs }
1776 1.1 rjs }
1777 1.1 rjs TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
1778 1.1 rjs if (chk->send_size > eff_mtu) {
1779 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT;
1780 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
1781 1.1 rjs }
1782 1.1 rjs }
1783 1.1 rjs }
1784 1.1 rjs
1785 1.1 rjs
1786 1.1 rjs /*
1787 1.1 rjs * given an association and starting time of the current RTT period
1788 1.1 rjs * return RTO in number of usecs
1789 1.1 rjs * net should point to the current network
1790 1.1 rjs */
1791 1.1 rjs u_int32_t
1792 1.1 rjs sctp_calculate_rto(struct sctp_tcb *stcb,
1793 1.1 rjs struct sctp_association *asoc,
1794 1.1 rjs struct sctp_nets *net,
1795 1.1 rjs struct timeval *old)
1796 1.1 rjs {
1797 1.1 rjs /*
1798 1.1 rjs * given an association and the starting time of the current RTT
1799 1.1 rjs * period (in value1/value2) return RTO in number of usecs.
1800 1.1 rjs */
1801 1.1 rjs int calc_time = 0;
1802 1.1 rjs unsigned int new_rto = 0;
1803 1.1 rjs int first_measure = 0;
1804 1.1 rjs struct timeval now;
1805 1.1 rjs
1806 1.1 rjs /************************/
1807 1.1 rjs /* 1. calculate new RTT */
1808 1.1 rjs /************************/
1809 1.1 rjs /* get the current time */
1810 1.1 rjs SCTP_GETTIME_TIMEVAL(&now);
1811 1.1 rjs /* compute the RTT value */
1812 1.1 rjs if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
1813 1.1 rjs calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;
1814 1.1 rjs if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
1815 1.1 rjs calc_time += (((u_long)now.tv_usec -
1816 1.1 rjs (u_long)old->tv_usec)/1000);
1817 1.1 rjs } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
1818 1.1 rjs /* Borrow 1,000ms from current calculation */
1819 1.1 rjs calc_time -= 1000;
1820 1.1 rjs /* Add in the slop over */
1821 1.1 rjs calc_time += ((int)now.tv_usec/1000);
1822 1.1 rjs /* Add in the pre-second ms's */
1823 1.1 rjs calc_time += (((int)1000000 - (int)old->tv_usec)/1000);
1824 1.1 rjs }
1825 1.1 rjs } else if ((u_long)now.tv_sec == (u_long)old->tv_sec) {
1826 1.1 rjs if ((u_long)now.tv_usec > (u_long)old->tv_usec) {
1827 1.1 rjs calc_time = ((u_long)now.tv_usec -
1828 1.1 rjs (u_long)old->tv_usec)/1000;
1829 1.1 rjs } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) {
1830 1.1 rjs /* impossible .. garbage in nothing out */
1831 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1);
1832 1.1 rjs } else {
1833 1.1 rjs /* impossible .. garbage in nothing out */
1834 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1);
1835 1.1 rjs }
1836 1.1 rjs } else {
1837 1.1 rjs /* Clock wrapped? */
1838 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1);
1839 1.1 rjs }
1840 1.1 rjs /***************************/
1841 1.1 rjs /* 2. update RTTVAR & SRTT */
1842 1.1 rjs /***************************/
1843 1.1 rjs #if 0
1844 1.1 rjs /* if (net->lastsv || net->lastsa) {*/
1845 1.1 rjs /* per Section 5.3.1 C3 in SCTP */
1846 1.1 rjs /* net->lastsv = (int) *//* RTTVAR */
1847 1.1 rjs /* (((double)(1.0 - 0.25) * (double)net->lastsv) +
1848 1.1 rjs (double)(0.25 * (double)abs(net->lastsa - calc_time)));
1849 1.1 rjs net->lastsa = (int) */ /* SRTT */
1850 1.1 rjs /*(((double)(1.0 - 0.125) * (double)net->lastsa) +
1851 1.1 rjs (double)(0.125 * (double)calc_time));
1852 1.1 rjs } else {
1853 1.1 rjs *//* the first RTT calculation, per C2 Section 5.3.1 */
1854 1.1 rjs /* net->lastsa = calc_time; *//* SRTT */
1855 1.1 rjs /* net->lastsv = calc_time / 2; *//* RTTVAR */
1856 1.1 rjs /* }*/
1857 1.1 rjs /* if RTTVAR goes to 0 you set to clock grainularity */
1858 1.1 rjs /* if (net->lastsv == 0) {
1859 1.1 rjs net->lastsv = SCTP_CLOCK_GRANULARITY;
1860 1.1 rjs }
1861 1.1 rjs new_rto = net->lastsa + 4 * net->lastsv;
1862 1.1 rjs */
1863 1.1 rjs #endif
1864 1.1 rjs /* this is Van Jacobson's integer version */
1865 1.1 rjs if (net->RTO) {
1866 1.1 rjs calc_time -= (net->lastsa >> 3);
1867 1.1 rjs net->lastsa += calc_time;
1868 1.1 rjs if (calc_time < 0) {
1869 1.1 rjs calc_time = -calc_time;
1870 1.1 rjs }
1871 1.1 rjs calc_time -= (net->lastsv >> 2);
1872 1.1 rjs net->lastsv += calc_time;
1873 1.1 rjs if (net->lastsv == 0) {
1874 1.1 rjs net->lastsv = SCTP_CLOCK_GRANULARITY;
1875 1.1 rjs }
1876 1.1 rjs } else {
1877 1.1 rjs /* First RTO measurment */
1878 1.1 rjs net->lastsa = calc_time;
1879 1.1 rjs net->lastsv = calc_time >> 1;
1880 1.1 rjs first_measure = 1;
1881 1.1 rjs }
1882 1.1 rjs new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1;
1883 1.1 rjs if ((new_rto > SCTP_SAT_NETWORK_MIN) &&
1884 1.1 rjs (stcb->asoc.sat_network_lockout == 0)) {
1885 1.1 rjs stcb->asoc.sat_network = 1;
1886 1.1 rjs } else if ((!first_measure) && stcb->asoc.sat_network) {
1887 1.1 rjs stcb->asoc.sat_network = 0;
1888 1.1 rjs stcb->asoc.sat_network_lockout = 1;
1889 1.1 rjs }
1890 1.1 rjs /* bound it, per C6/C7 in Section 5.3.1 */
1891 1.1 rjs if (new_rto < stcb->asoc.minrto) {
1892 1.1 rjs new_rto = stcb->asoc.minrto;
1893 1.1 rjs }
1894 1.1 rjs if (new_rto > stcb->asoc.maxrto) {
1895 1.1 rjs new_rto = stcb->asoc.maxrto;
1896 1.1 rjs }
1897 1.1 rjs /* we are now returning the RTT Smoothed */
1898 1.1 rjs return ((u_int32_t)new_rto);
1899 1.1 rjs }
1900 1.1 rjs
1901 1.1 rjs
1902 1.1 rjs /*
1903 1.1 rjs * return a pointer to a contiguous piece of data from the given
1904 1.1 rjs * mbuf chain starting at 'off' for 'len' bytes. If the desired
1905 1.1 rjs * piece spans more than one mbuf, a copy is made at 'ptr'.
1906 1.1 rjs * caller must ensure that the buffer size is >= 'len'
1907 1.1 rjs * returns NULL if there there isn't 'len' bytes in the chain.
1908 1.1 rjs */
1909 1.1 rjs void *
1910 1.1 rjs sctp_m_getptr(struct mbuf *m, int off, int len, u_int8_t *in_ptr)
1911 1.1 rjs {
1912 1.1 rjs uint32_t count;
1913 1.1 rjs uint8_t *ptr;
1914 1.1 rjs ptr = in_ptr;
1915 1.1 rjs if ((off < 0) || (len <= 0))
1916 1.1 rjs return (NULL);
1917 1.1 rjs
1918 1.1 rjs /* find the desired start location */
1919 1.1 rjs while ((m != NULL) && (off > 0)) {
1920 1.1 rjs if (off < m->m_len)
1921 1.1 rjs break;
1922 1.1 rjs off -= m->m_len;
1923 1.1 rjs m = m->m_next;
1924 1.1 rjs }
1925 1.1 rjs if (m == NULL)
1926 1.1 rjs return (NULL);
1927 1.1 rjs
1928 1.1 rjs /* is the current mbuf large enough (eg. contiguous)? */
1929 1.1 rjs if ((m->m_len - off) >= len) {
1930 1.1 rjs return ((void *)(mtod(m, vaddr_t) + off));
1931 1.1 rjs } else {
1932 1.1 rjs /* else, it spans more than one mbuf, so save a temp copy... */
1933 1.1 rjs while ((m != NULL) && (len > 0)) {
1934 1.1 rjs count = min(m->m_len - off, len);
1935 1.1 rjs memcpy(ptr, (void *)(mtod(m, vaddr_t) + off), count);
1936 1.1 rjs len -= count;
1937 1.1 rjs ptr += count;
1938 1.1 rjs off = 0;
1939 1.1 rjs m = m->m_next;
1940 1.1 rjs }
1941 1.1 rjs if ((m == NULL) && (len > 0))
1942 1.1 rjs return (NULL);
1943 1.1 rjs else
1944 1.1 rjs return ((void *)in_ptr);
1945 1.1 rjs }
1946 1.1 rjs }
1947 1.1 rjs
1948 1.1 rjs
1949 1.1 rjs struct sctp_paramhdr *
1950 1.1 rjs sctp_get_next_param(struct mbuf *m,
1951 1.1 rjs int offset,
1952 1.1 rjs struct sctp_paramhdr *pull,
1953 1.1 rjs int pull_limit)
1954 1.1 rjs {
1955 1.1 rjs /* This just provides a typed signature to Peter's Pull routine */
1956 1.1 rjs return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit,
1957 1.1 rjs (u_int8_t *)pull));
1958 1.1 rjs }
1959 1.1 rjs
1960 1.1 rjs
1961 1.1 rjs int
1962 1.1 rjs sctp_add_pad_tombuf(struct mbuf *m, int padlen)
1963 1.1 rjs {
1964 1.1 rjs /*
1965 1.1 rjs * add padlen bytes of 0 filled padding to the end of the mbuf.
1966 1.1 rjs * If padlen is > 3 this routine will fail.
1967 1.1 rjs */
1968 1.1 rjs u_int8_t *dp;
1969 1.1 rjs int i;
1970 1.1 rjs if (padlen > 3) {
1971 1.1 rjs return (ENOBUFS);
1972 1.1 rjs }
1973 1.1 rjs if (M_TRAILINGSPACE(m)) {
1974 1.1 rjs /*
1975 1.1 rjs * The easy way.
1976 1.1 rjs * We hope the majority of the time we hit here :)
1977 1.1 rjs */
1978 1.1 rjs dp = (u_int8_t *)(mtod(m, vaddr_t) + m->m_len);
1979 1.1 rjs m->m_len += padlen;
1980 1.1 rjs } else {
1981 1.1 rjs /* Hard way we must grow the mbuf */
1982 1.1 rjs struct mbuf *tmp;
1983 1.1 rjs MGET(tmp, M_DONTWAIT, MT_DATA);
1984 1.1 rjs if (tmp == NULL) {
1985 1.1 rjs /* Out of space GAK! we are in big trouble. */
1986 1.1 rjs return (ENOSPC);
1987 1.1 rjs }
1988 1.1 rjs /* setup and insert in middle */
1989 1.1 rjs tmp->m_next = m->m_next;
1990 1.1 rjs tmp->m_len = padlen;
1991 1.1 rjs m->m_next = tmp;
1992 1.1 rjs dp = mtod(tmp, u_int8_t *);
1993 1.1 rjs }
1994 1.1 rjs /* zero out the pad */
1995 1.1 rjs for (i= 0; i < padlen; i++) {
1996 1.1 rjs *dp = 0;
1997 1.1 rjs dp++;
1998 1.1 rjs }
1999 1.1 rjs return (0);
2000 1.1 rjs }
2001 1.1 rjs
2002 1.1 rjs int
2003 1.1 rjs sctp_pad_lastmbuf(struct mbuf *m, int padval)
2004 1.1 rjs {
2005 1.1 rjs /* find the last mbuf in chain and pad it */
2006 1.1 rjs struct mbuf *m_at;
2007 1.1 rjs m_at = m;
2008 1.1 rjs while (m_at) {
2009 1.1 rjs if (m_at->m_next == NULL) {
2010 1.1 rjs return (sctp_add_pad_tombuf(m_at, padval));
2011 1.1 rjs }
2012 1.1 rjs m_at = m_at->m_next;
2013 1.1 rjs }
2014 1.1 rjs return (EFAULT);
2015 1.1 rjs }
2016 1.1 rjs
2017 1.1 rjs static void
2018 1.1 rjs sctp_notify_assoc_change(u_int32_t event, struct sctp_tcb *stcb,
2019 1.1 rjs u_int32_t error)
2020 1.1 rjs {
2021 1.1 rjs struct mbuf *m_notify;
2022 1.1 rjs struct sctp_assoc_change *sac;
2023 1.1 rjs const struct sockaddr *to;
2024 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2025 1.1 rjs
2026 1.1 rjs #ifdef SCTP_DEBUG
2027 1.1 rjs printf("notify: %d\n", event);
2028 1.1 rjs #endif
2029 1.1 rjs /*
2030 1.1 rjs * First if we are are going down dump everything we
2031 1.1 rjs * can to the socket rcv queue.
2032 1.1 rjs */
2033 1.1 rjs if ((event == SCTP_SHUTDOWN_COMP) || (event == SCTP_COMM_LOST)) {
2034 1.1 rjs sctp_deliver_data(stcb, &stcb->asoc, NULL, 0);
2035 1.1 rjs }
2036 1.1 rjs
2037 1.1 rjs /*
2038 1.1 rjs * For TCP model AND UDP connected sockets we will send
2039 1.1 rjs * an error up when an ABORT comes in.
2040 1.1 rjs */
2041 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2042 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
2043 1.1 rjs (event == SCTP_COMM_LOST)) {
2044 1.1 rjs stcb->sctp_socket->so_error = ECONNRESET;
2045 1.1 rjs /* Wake ANY sleepers */
2046 1.1 rjs sowwakeup(stcb->sctp_socket);
2047 1.1 rjs sorwakeup(stcb->sctp_socket);
2048 1.1 rjs }
2049 1.1 rjs #if 0
2050 1.1 rjs if ((event == SCTP_COMM_UP) &&
2051 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
2052 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
2053 1.1 rjs soisconnected(stcb->sctp_socket);
2054 1.1 rjs }
2055 1.1 rjs #endif
2056 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
2057 1.1 rjs /* event not enabled */
2058 1.1 rjs return;
2059 1.1 rjs }
2060 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2061 1.1 rjs if (m_notify == NULL)
2062 1.1 rjs /* no space left */
2063 1.1 rjs return;
2064 1.1 rjs m_notify->m_len = 0;
2065 1.1 rjs
2066 1.1 rjs sac = mtod(m_notify, struct sctp_assoc_change *);
2067 1.1 rjs sac->sac_type = SCTP_ASSOC_CHANGE;
2068 1.1 rjs sac->sac_flags = 0;
2069 1.1 rjs sac->sac_length = sizeof(struct sctp_assoc_change);
2070 1.1 rjs sac->sac_state = event;
2071 1.1 rjs sac->sac_error = error;
2072 1.1 rjs /* XXX verify these stream counts */
2073 1.1 rjs sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
2074 1.1 rjs sac->sac_inbound_streams = stcb->asoc.streamincnt;
2075 1.1 rjs sac->sac_assoc_id = sctp_get_associd(stcb);
2076 1.1 rjs
2077 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2078 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change);
2079 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2080 1.1 rjs m_notify->m_len = sizeof(struct sctp_assoc_change);
2081 1.1 rjs m_notify->m_next = NULL;
2082 1.1 rjs
2083 1.1 rjs /* append to socket */
2084 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2085 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2086 1.1 rjs to->sa_family == AF_INET) {
2087 1.1 rjs const struct sockaddr_in *sin;
2088 1.1 rjs
2089 1.1 rjs sin = (const struct sockaddr_in *)to;
2090 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2091 1.1 rjs sin6.sin6_family = AF_INET6;
2092 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2093 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2094 1.1 rjs memcpy(&sin6.sin6_addr.s6_addr16[3], &sin->sin_addr,
2095 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2096 1.1 rjs sin6.sin6_port = sin->sin_port;
2097 1.1 rjs to = (struct sockaddr *)&sin6;
2098 1.1 rjs }
2099 1.1 rjs /* check and strip embedded scope junk */
2100 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2101 1.1 rjs &lsa6);
2102 1.1 rjs /*
2103 1.1 rjs * We need to always notify comm changes.
2104 1.1 rjs * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2105 1.1 rjs * sctp_m_freem(m_notify);
2106 1.1 rjs * return;
2107 1.1 rjs * }
2108 1.1 rjs */
2109 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2110 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2111 1.1 rjs SCTP_TCB_LOCK(stcb);
2112 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv,
2113 1.1 rjs to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2114 1.1 rjs /* not enough room */
2115 1.1 rjs sctp_m_freem(m_notify);
2116 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2117 1.1 rjs return;
2118 1.1 rjs }
2119 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2120 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2121 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2122 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2123 1.1 rjs }
2124 1.1 rjs } else {
2125 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2126 1.1 rjs }
2127 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2128 1.1 rjs /* Wake up any sleeper */
2129 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2130 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
2131 1.1 rjs }
2132 1.1 rjs
2133 1.1 rjs static void
2134 1.1 rjs sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
2135 1.1 rjs const struct sockaddr *sa, uint32_t error)
2136 1.1 rjs {
2137 1.1 rjs struct mbuf *m_notify;
2138 1.1 rjs struct sctp_paddr_change *spc;
2139 1.1 rjs const struct sockaddr *to;
2140 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2141 1.1 rjs
2142 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT))
2143 1.1 rjs /* event not enabled */
2144 1.1 rjs return;
2145 1.1 rjs
2146 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2147 1.1 rjs if (m_notify == NULL)
2148 1.1 rjs return;
2149 1.1 rjs m_notify->m_len = 0;
2150 1.1 rjs
2151 1.1 rjs MCLGET(m_notify, M_DONTWAIT);
2152 1.1 rjs if ((m_notify->m_flags & M_EXT) != M_EXT) {
2153 1.1 rjs sctp_m_freem(m_notify);
2154 1.1 rjs return;
2155 1.1 rjs }
2156 1.1 rjs
2157 1.1 rjs spc = mtod(m_notify, struct sctp_paddr_change *);
2158 1.1 rjs spc->spc_type = SCTP_PEER_ADDR_CHANGE;
2159 1.1 rjs spc->spc_flags = 0;
2160 1.1 rjs spc->spc_length = sizeof(struct sctp_paddr_change);
2161 1.1 rjs if (sa->sa_family == AF_INET) {
2162 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
2163 1.1 rjs } else {
2164 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
2165 1.1 rjs }
2166 1.1 rjs spc->spc_state = state;
2167 1.1 rjs spc->spc_error = error;
2168 1.1 rjs spc->spc_assoc_id = sctp_get_associd(stcb);
2169 1.1 rjs
2170 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2171 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
2172 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2173 1.1 rjs m_notify->m_len = sizeof(struct sctp_paddr_change);
2174 1.1 rjs m_notify->m_next = NULL;
2175 1.1 rjs
2176 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2177 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2178 1.1 rjs to->sa_family == AF_INET) {
2179 1.1 rjs const struct sockaddr_in *sin;
2180 1.1 rjs
2181 1.1 rjs sin = (const struct sockaddr_in *)to;
2182 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2183 1.1 rjs sin6.sin6_family = AF_INET6;
2184 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2185 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2186 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2187 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2188 1.1 rjs sin6.sin6_port = sin->sin_port;
2189 1.1 rjs to = (struct sockaddr *)&sin6;
2190 1.1 rjs }
2191 1.1 rjs /* check and strip embedded scope junk */
2192 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2193 1.1 rjs &lsa6);
2194 1.1 rjs
2195 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2196 1.1 rjs sctp_m_freem(m_notify);
2197 1.1 rjs return;
2198 1.1 rjs }
2199 1.1 rjs /* append to socket */
2200 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2201 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2202 1.1 rjs SCTP_TCB_LOCK(stcb);
2203 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2204 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2205 1.1 rjs /* not enough room */
2206 1.1 rjs sctp_m_freem(m_notify);
2207 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2208 1.1 rjs return;
2209 1.1 rjs }
2210 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2211 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2212 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2213 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2214 1.1 rjs }
2215 1.1 rjs } else {
2216 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2217 1.1 rjs }
2218 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2219 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2220 1.1 rjs }
2221 1.1 rjs
2222 1.1 rjs
2223 1.1 rjs static void
2224 1.1 rjs sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error,
2225 1.1 rjs struct sctp_tmit_chunk *chk)
2226 1.1 rjs {
2227 1.1 rjs struct mbuf *m_notify;
2228 1.1 rjs struct sctp_send_failed *ssf;
2229 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2230 1.1 rjs const struct sockaddr *to;
2231 1.1 rjs int length;
2232 1.1 rjs
2233 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
2234 1.1 rjs /* event not enabled */
2235 1.1 rjs return;
2236 1.1 rjs
2237 1.1 rjs length = sizeof(struct sctp_send_failed) + chk->send_size;
2238 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2239 1.1 rjs if (m_notify == NULL)
2240 1.1 rjs /* no space left */
2241 1.1 rjs return;
2242 1.1 rjs m_notify->m_len = 0;
2243 1.1 rjs ssf = mtod(m_notify, struct sctp_send_failed *);
2244 1.1 rjs ssf->ssf_type = SCTP_SEND_FAILED;
2245 1.1 rjs if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
2246 1.1 rjs ssf->ssf_flags = SCTP_DATA_UNSENT;
2247 1.1 rjs else
2248 1.1 rjs ssf->ssf_flags = SCTP_DATA_SENT;
2249 1.1 rjs ssf->ssf_length = length;
2250 1.1 rjs ssf->ssf_error = error;
2251 1.1 rjs /* not exactly what the user sent in, but should be close :) */
2252 1.1 rjs ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
2253 1.1 rjs ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
2254 1.1 rjs ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
2255 1.1 rjs ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
2256 1.1 rjs ssf->ssf_info.sinfo_context = chk->rec.data.context;
2257 1.1 rjs ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
2258 1.1 rjs ssf->ssf_assoc_id = sctp_get_associd(stcb);
2259 1.1 rjs m_notify->m_next = chk->data;
2260 1.1 rjs if (m_notify->m_next == NULL)
2261 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2262 1.1 rjs else {
2263 1.1 rjs struct mbuf *m;
2264 1.1 rjs m_notify->m_flags |= M_NOTIFICATION;
2265 1.1 rjs m = m_notify;
2266 1.1 rjs while (m->m_next != NULL)
2267 1.1 rjs m = m->m_next;
2268 1.1 rjs m->m_flags |= M_EOR;
2269 1.1 rjs }
2270 1.1 rjs m_notify->m_pkthdr.len = length;
2271 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2272 1.1 rjs m_notify->m_len = sizeof(struct sctp_send_failed);
2273 1.1 rjs
2274 1.1 rjs /* Steal off the mbuf */
2275 1.1 rjs chk->data = NULL;
2276 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2277 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2278 1.1 rjs to->sa_family == AF_INET) {
2279 1.1 rjs const struct sockaddr_in *sin;
2280 1.1 rjs
2281 1.1 rjs sin = satocsin(to);
2282 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2283 1.1 rjs sin6.sin6_family = AF_INET6;
2284 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2285 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2286 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2287 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2288 1.1 rjs sin6.sin6_port = sin->sin_port;
2289 1.1 rjs to = (struct sockaddr *)&sin6;
2290 1.1 rjs }
2291 1.1 rjs /* check and strip embedded scope junk */
2292 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2293 1.1 rjs &lsa6);
2294 1.1 rjs
2295 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2296 1.1 rjs sctp_m_freem(m_notify);
2297 1.1 rjs return;
2298 1.1 rjs }
2299 1.1 rjs
2300 1.1 rjs /* append to socket */
2301 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2302 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2303 1.1 rjs SCTP_TCB_LOCK(stcb);
2304 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2305 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2306 1.1 rjs /* not enough room */
2307 1.1 rjs sctp_m_freem(m_notify);
2308 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2309 1.1 rjs return;
2310 1.1 rjs }
2311 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2312 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2313 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2314 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2315 1.1 rjs }
2316 1.1 rjs } else {
2317 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2318 1.1 rjs }
2319 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2320 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2321 1.1 rjs }
2322 1.1 rjs
2323 1.1 rjs static void
2324 1.1 rjs sctp_notify_adaption_layer(struct sctp_tcb *stcb,
2325 1.1 rjs u_int32_t error)
2326 1.1 rjs {
2327 1.1 rjs struct mbuf *m_notify;
2328 1.1 rjs struct sctp_adaption_event *sai;
2329 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2330 1.1 rjs const struct sockaddr *to;
2331 1.1 rjs
2332 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT))
2333 1.1 rjs /* event not enabled */
2334 1.1 rjs return;
2335 1.1 rjs
2336 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2337 1.1 rjs if (m_notify == NULL)
2338 1.1 rjs /* no space left */
2339 1.1 rjs return;
2340 1.1 rjs m_notify->m_len = 0;
2341 1.1 rjs sai = mtod(m_notify, struct sctp_adaption_event *);
2342 1.1 rjs sai->sai_type = SCTP_ADAPTION_INDICATION;
2343 1.1 rjs sai->sai_flags = 0;
2344 1.1 rjs sai->sai_length = sizeof(struct sctp_adaption_event);
2345 1.1 rjs sai->sai_adaption_ind = error;
2346 1.1 rjs sai->sai_assoc_id = sctp_get_associd(stcb);
2347 1.1 rjs
2348 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2349 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event);
2350 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2351 1.1 rjs m_notify->m_len = sizeof(struct sctp_adaption_event);
2352 1.1 rjs m_notify->m_next = NULL;
2353 1.1 rjs
2354 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2355 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2356 1.1 rjs (to->sa_family == AF_INET)) {
2357 1.1 rjs const struct sockaddr_in *sin;
2358 1.1 rjs
2359 1.1 rjs sin = satocsin(to);
2360 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2361 1.1 rjs sin6.sin6_family = AF_INET6;
2362 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2363 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2364 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2365 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2366 1.1 rjs sin6.sin6_port = sin->sin_port;
2367 1.1 rjs to = (struct sockaddr *)&sin6;
2368 1.1 rjs }
2369 1.1 rjs /* check and strip embedded scope junk */
2370 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2371 1.1 rjs &lsa6);
2372 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2373 1.1 rjs sctp_m_freem(m_notify);
2374 1.1 rjs return;
2375 1.1 rjs }
2376 1.1 rjs /* append to socket */
2377 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2378 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2379 1.1 rjs SCTP_TCB_LOCK(stcb);
2380 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2381 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2382 1.1 rjs /* not enough room */
2383 1.1 rjs sctp_m_freem(m_notify);
2384 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2385 1.1 rjs return;
2386 1.1 rjs }
2387 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2388 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2389 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2390 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2391 1.1 rjs }
2392 1.1 rjs } else {
2393 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2394 1.1 rjs }
2395 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2396 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2397 1.1 rjs }
2398 1.1 rjs
2399 1.1 rjs static void
2400 1.1 rjs sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
2401 1.1 rjs u_int32_t error)
2402 1.1 rjs {
2403 1.1 rjs struct mbuf *m_notify;
2404 1.1 rjs struct sctp_pdapi_event *pdapi;
2405 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2406 1.1 rjs const struct sockaddr *to;
2407 1.1 rjs
2408 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT))
2409 1.1 rjs /* event not enabled */
2410 1.1 rjs return;
2411 1.1 rjs
2412 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2413 1.1 rjs if (m_notify == NULL)
2414 1.1 rjs /* no space left */
2415 1.1 rjs return;
2416 1.1 rjs m_notify->m_len = 0;
2417 1.1 rjs pdapi = mtod(m_notify, struct sctp_pdapi_event *);
2418 1.1 rjs pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
2419 1.1 rjs pdapi->pdapi_flags = 0;
2420 1.1 rjs pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
2421 1.1 rjs pdapi->pdapi_indication = error;
2422 1.1 rjs pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
2423 1.1 rjs
2424 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2425 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
2426 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2427 1.1 rjs m_notify->m_len = sizeof(struct sctp_pdapi_event);
2428 1.1 rjs m_notify->m_next = NULL;
2429 1.1 rjs
2430 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2431 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2432 1.1 rjs (to->sa_family == AF_INET)) {
2433 1.1 rjs const struct sockaddr_in *sin;
2434 1.1 rjs
2435 1.1 rjs sin = satocsin(to);
2436 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2437 1.1 rjs sin6.sin6_family = AF_INET6;
2438 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2439 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2440 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2441 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2442 1.1 rjs sin6.sin6_port = sin->sin_port;
2443 1.1 rjs to = (struct sockaddr *)&sin6;
2444 1.1 rjs }
2445 1.1 rjs /* check and strip embedded scope junk */
2446 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2447 1.1 rjs &lsa6);
2448 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2449 1.1 rjs sctp_m_freem(m_notify);
2450 1.1 rjs return;
2451 1.1 rjs }
2452 1.1 rjs /* append to socket */
2453 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2454 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2455 1.1 rjs SCTP_TCB_LOCK(stcb);
2456 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2457 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2458 1.1 rjs /* not enough room */
2459 1.1 rjs sctp_m_freem(m_notify);
2460 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2461 1.1 rjs return;
2462 1.1 rjs }
2463 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2464 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2465 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2466 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2467 1.1 rjs }
2468 1.1 rjs } else {
2469 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2470 1.1 rjs }
2471 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2472 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2473 1.1 rjs }
2474 1.1 rjs
2475 1.1 rjs static void
2476 1.1 rjs sctp_notify_shutdown_event(struct sctp_tcb *stcb)
2477 1.1 rjs {
2478 1.1 rjs struct mbuf *m_notify;
2479 1.1 rjs struct sctp_shutdown_event *sse;
2480 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2481 1.1 rjs const struct sockaddr *to;
2482 1.1 rjs
2483 1.1 rjs /*
2484 1.1 rjs * For TCP model AND UDP connected sockets we will send
2485 1.1 rjs * an error up when an SHUTDOWN completes
2486 1.1 rjs */
2487 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2488 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
2489 1.1 rjs /* mark socket closed for read/write and wakeup! */
2490 1.1 rjs socantrcvmore(stcb->sctp_socket);
2491 1.1 rjs socantsendmore(stcb->sctp_socket);
2492 1.1 rjs }
2493 1.1 rjs
2494 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
2495 1.1 rjs /* event not enabled */
2496 1.1 rjs return;
2497 1.1 rjs
2498 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2499 1.1 rjs if (m_notify == NULL)
2500 1.1 rjs /* no space left */
2501 1.1 rjs return;
2502 1.1 rjs m_notify->m_len = 0;
2503 1.1 rjs sse = mtod(m_notify, struct sctp_shutdown_event *);
2504 1.1 rjs sse->sse_type = SCTP_SHUTDOWN_EVENT;
2505 1.1 rjs sse->sse_flags = 0;
2506 1.1 rjs sse->sse_length = sizeof(struct sctp_shutdown_event);
2507 1.1 rjs sse->sse_assoc_id = sctp_get_associd(stcb);
2508 1.1 rjs
2509 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2510 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
2511 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2512 1.1 rjs m_notify->m_len = sizeof(struct sctp_shutdown_event);
2513 1.1 rjs m_notify->m_next = NULL;
2514 1.1 rjs
2515 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2516 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2517 1.1 rjs to->sa_family == AF_INET) {
2518 1.1 rjs const struct sockaddr_in *sin;
2519 1.1 rjs
2520 1.1 rjs sin = satocsin(to);
2521 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2522 1.1 rjs sin6.sin6_family = AF_INET6;
2523 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2524 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2525 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2526 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2527 1.1 rjs sin6.sin6_port = sin->sin_port;
2528 1.1 rjs to = (struct sockaddr *)&sin6;
2529 1.1 rjs }
2530 1.1 rjs /* check and strip embedded scope junk */
2531 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2532 1.1 rjs &lsa6);
2533 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2534 1.1 rjs sctp_m_freem(m_notify);
2535 1.1 rjs return;
2536 1.1 rjs }
2537 1.1 rjs /* append to socket */
2538 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2539 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2540 1.1 rjs SCTP_TCB_LOCK(stcb);
2541 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2542 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2543 1.1 rjs /* not enough room */
2544 1.1 rjs sctp_m_freem(m_notify);
2545 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2546 1.1 rjs return;
2547 1.1 rjs }
2548 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2549 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2550 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2551 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2552 1.1 rjs }
2553 1.1 rjs } else {
2554 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2555 1.1 rjs }
2556 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2557 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2558 1.1 rjs }
2559 1.1 rjs
2560 1.1 rjs static void
2561 1.1 rjs sctp_notify_stream_reset(struct sctp_tcb *stcb,
2562 1.1 rjs int number_entries, uint16_t *list, int flag)
2563 1.1 rjs {
2564 1.1 rjs struct mbuf *m_notify;
2565 1.1 rjs struct sctp_stream_reset_event *strreset;
2566 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2567 1.1 rjs const struct sockaddr *to;
2568 1.1 rjs int len;
2569 1.1 rjs
2570 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT))
2571 1.1 rjs /* event not enabled */
2572 1.1 rjs return;
2573 1.1 rjs
2574 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2575 1.1 rjs if (m_notify == NULL)
2576 1.1 rjs /* no space left */
2577 1.1 rjs return;
2578 1.1 rjs m_notify->m_len = 0;
2579 1.1 rjs len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
2580 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) {
2581 1.1 rjs MCLGET(m_notify, M_WAIT);
2582 1.1 rjs }
2583 1.1 rjs if (m_notify == NULL)
2584 1.1 rjs /* no clusters */
2585 1.1 rjs return;
2586 1.1 rjs
2587 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) {
2588 1.1 rjs /* never enough room */
2589 1.1 rjs m_freem(m_notify);
2590 1.1 rjs return;
2591 1.1 rjs }
2592 1.1 rjs strreset = mtod(m_notify, struct sctp_stream_reset_event *);
2593 1.1 rjs strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
2594 1.1 rjs if (number_entries == 0) {
2595 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
2596 1.1 rjs } else {
2597 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
2598 1.1 rjs }
2599 1.1 rjs strreset->strreset_length = len;
2600 1.1 rjs strreset->strreset_assoc_id = sctp_get_associd(stcb);
2601 1.1 rjs if (number_entries) {
2602 1.1 rjs int i;
2603 1.1 rjs for (i=0; i<number_entries; i++) {
2604 1.1 rjs strreset->strreset_list[i] = list[i];
2605 1.1 rjs }
2606 1.1 rjs }
2607 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2608 1.1 rjs m_notify->m_pkthdr.len = len;
2609 1.1 rjs m_notify->m_pkthdr.rcvif = 0;
2610 1.1 rjs m_notify->m_len = len;
2611 1.1 rjs m_notify->m_next = NULL;
2612 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2613 1.1 rjs /* no space */
2614 1.1 rjs sctp_m_freem(m_notify);
2615 1.1 rjs return;
2616 1.1 rjs }
2617 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2618 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2619 1.1 rjs to->sa_family == AF_INET) {
2620 1.1 rjs const struct sockaddr_in *sin;
2621 1.1 rjs
2622 1.1 rjs sin = satocsin(to);
2623 1.1 rjs memset(&sin6, 0, sizeof(sin6));
2624 1.1 rjs sin6.sin6_family = AF_INET6;
2625 1.1 rjs sin6.sin6_len = sizeof(struct sockaddr_in6);
2626 1.1 rjs sin6.sin6_addr.s6_addr16[2] = 0xffff;
2627 1.1 rjs bcopy(&sin->sin_addr, &sin6.sin6_addr.s6_addr16[3],
2628 1.1 rjs sizeof(sin6.sin6_addr.s6_addr16[3]));
2629 1.1 rjs sin6.sin6_port = sin->sin_port;
2630 1.1 rjs to = (struct sockaddr *)&sin6;
2631 1.1 rjs }
2632 1.1 rjs /* check and strip embedded scope junk */
2633 1.1 rjs to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to,
2634 1.1 rjs &lsa6);
2635 1.1 rjs /* append to socket */
2636 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2637 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2638 1.1 rjs SCTP_TCB_LOCK(stcb);
2639 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2640 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2641 1.1 rjs /* not enough room */
2642 1.1 rjs sctp_m_freem(m_notify);
2643 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2644 1.1 rjs return;
2645 1.1 rjs }
2646 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2647 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2648 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2649 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2650 1.1 rjs }
2651 1.1 rjs } else {
2652 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2653 1.1 rjs }
2654 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2655 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2656 1.1 rjs }
2657 1.1 rjs
2658 1.1 rjs
2659 1.1 rjs void
2660 1.1 rjs sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb,
2661 1.1 rjs u_int32_t error, void *data)
2662 1.1 rjs {
2663 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2664 1.1 rjs /* No notifications up when we are in a no socket state */
2665 1.1 rjs return;
2666 1.1 rjs }
2667 1.1 rjs if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2668 1.1 rjs /* Can't send up to a closed socket any notifications */
2669 1.1 rjs return;
2670 1.1 rjs }
2671 1.1 rjs switch (notification) {
2672 1.1 rjs case SCTP_NOTIFY_ASSOC_UP:
2673 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error);
2674 1.1 rjs break;
2675 1.1 rjs case SCTP_NOTIFY_ASSOC_DOWN:
2676 1.1 rjs sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error);
2677 1.1 rjs break;
2678 1.1 rjs case SCTP_NOTIFY_INTERFACE_DOWN:
2679 1.1 rjs {
2680 1.1 rjs struct sctp_nets *net;
2681 1.1 rjs net = (struct sctp_nets *)data;
2682 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
2683 1.1 rjs rtcache_getdst(&net->ro), error);
2684 1.1 rjs break;
2685 1.1 rjs }
2686 1.1 rjs case SCTP_NOTIFY_INTERFACE_UP:
2687 1.1 rjs {
2688 1.1 rjs struct sctp_nets *net;
2689 1.1 rjs net = (struct sctp_nets *)data;
2690 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
2691 1.1 rjs rtcache_getdst(&net->ro), error);
2692 1.1 rjs break;
2693 1.1 rjs }
2694 1.1 rjs case SCTP_NOTIFY_INTERFACE_CONFIRMED:
2695 1.1 rjs {
2696 1.1 rjs struct sctp_nets *net;
2697 1.1 rjs net = (struct sctp_nets *)data;
2698 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
2699 1.1 rjs rtcache_getdst(&net->ro), error);
2700 1.1 rjs break;
2701 1.1 rjs }
2702 1.1 rjs case SCTP_NOTIFY_DG_FAIL:
2703 1.1 rjs sctp_notify_send_failed(stcb, error,
2704 1.1 rjs (struct sctp_tmit_chunk *)data);
2705 1.1 rjs break;
2706 1.1 rjs case SCTP_NOTIFY_ADAPTION_INDICATION:
2707 1.1 rjs /* Here the error is the adaption indication */
2708 1.1 rjs sctp_notify_adaption_layer(stcb, error);
2709 1.1 rjs break;
2710 1.1 rjs case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
2711 1.1 rjs sctp_notify_partial_delivery_indication(stcb, error);
2712 1.1 rjs break;
2713 1.1 rjs case SCTP_NOTIFY_STRDATA_ERR:
2714 1.1 rjs break;
2715 1.1 rjs case SCTP_NOTIFY_ASSOC_ABORTED:
2716 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error);
2717 1.1 rjs break;
2718 1.1 rjs case SCTP_NOTIFY_PEER_OPENED_STREAM:
2719 1.1 rjs break;
2720 1.1 rjs case SCTP_NOTIFY_STREAM_OPENED_OK:
2721 1.1 rjs break;
2722 1.1 rjs case SCTP_NOTIFY_ASSOC_RESTART:
2723 1.1 rjs sctp_notify_assoc_change(SCTP_RESTART, stcb, error);
2724 1.1 rjs break;
2725 1.1 rjs case SCTP_NOTIFY_HB_RESP:
2726 1.1 rjs break;
2727 1.1 rjs case SCTP_NOTIFY_STR_RESET_SEND:
2728 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR);
2729 1.1 rjs break;
2730 1.1 rjs case SCTP_NOTIFY_STR_RESET_RECV:
2731 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR);
2732 1.1 rjs break;
2733 1.1 rjs case SCTP_NOTIFY_ASCONF_ADD_IP:
2734 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
2735 1.1 rjs error);
2736 1.1 rjs break;
2737 1.1 rjs case SCTP_NOTIFY_ASCONF_DELETE_IP:
2738 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
2739 1.1 rjs error);
2740 1.1 rjs break;
2741 1.1 rjs case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
2742 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
2743 1.1 rjs error);
2744 1.1 rjs break;
2745 1.1 rjs case SCTP_NOTIFY_ASCONF_SUCCESS:
2746 1.1 rjs break;
2747 1.1 rjs case SCTP_NOTIFY_ASCONF_FAILED:
2748 1.1 rjs break;
2749 1.1 rjs case SCTP_NOTIFY_PEER_SHUTDOWN:
2750 1.1 rjs sctp_notify_shutdown_event(stcb);
2751 1.1 rjs break;
2752 1.1 rjs default:
2753 1.1 rjs #ifdef SCTP_DEBUG
2754 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_UTIL1) {
2755 1.1 rjs printf("NOTIFY: unknown notification %xh (%u)\n",
2756 1.1 rjs notification, notification);
2757 1.1 rjs }
2758 1.1 rjs #endif /* SCTP_DEBUG */
2759 1.1 rjs break;
2760 1.1 rjs } /* end switch */
2761 1.1 rjs }
2762 1.1 rjs
2763 1.1 rjs void
2764 1.1 rjs sctp_report_all_outbound(struct sctp_tcb *stcb)
2765 1.1 rjs {
2766 1.1 rjs struct sctp_association *asoc;
2767 1.1 rjs struct sctp_stream_out *outs;
2768 1.1 rjs struct sctp_tmit_chunk *chk;
2769 1.1 rjs
2770 1.1 rjs asoc = &stcb->asoc;
2771 1.1 rjs
2772 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2773 1.1 rjs return;
2774 1.1 rjs }
2775 1.1 rjs /* now through all the gunk freeing chunks */
2776 1.1 rjs TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
2777 1.1 rjs /* now clean up any chunks here */
2778 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue);
2779 1.1 rjs while (chk) {
2780 1.1 rjs stcb->asoc.stream_queue_cnt--;
2781 1.1 rjs TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
2782 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
2783 1.1 rjs SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
2784 1.1 rjs if (chk->data) {
2785 1.1 rjs sctp_m_freem(chk->data);
2786 1.1 rjs chk->data = NULL;
2787 1.1 rjs }
2788 1.1 rjs if (chk->whoTo)
2789 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2790 1.1 rjs chk->whoTo = NULL;
2791 1.1 rjs chk->asoc = NULL;
2792 1.1 rjs /* Free the chunk */
2793 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2794 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2795 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2796 1.1 rjs panic("Chunk count is negative");
2797 1.1 rjs }
2798 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2799 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue);
2800 1.1 rjs }
2801 1.1 rjs }
2802 1.1 rjs /* pending send queue SHOULD be empty */
2803 1.1 rjs if (!TAILQ_EMPTY(&asoc->send_queue)) {
2804 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue);
2805 1.1 rjs while (chk) {
2806 1.1 rjs TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
2807 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
2808 1.1 rjs if (chk->data) {
2809 1.1 rjs sctp_m_freem(chk->data);
2810 1.1 rjs chk->data = NULL;
2811 1.1 rjs }
2812 1.1 rjs if (chk->whoTo)
2813 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2814 1.1 rjs chk->whoTo = NULL;
2815 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2816 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2817 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2818 1.1 rjs panic("Chunk count is negative");
2819 1.1 rjs }
2820 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2821 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue);
2822 1.1 rjs }
2823 1.1 rjs }
2824 1.1 rjs /* sent queue SHOULD be empty */
2825 1.1 rjs if (!TAILQ_EMPTY(&asoc->sent_queue)) {
2826 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue);
2827 1.1 rjs while (chk) {
2828 1.1 rjs TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
2829 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
2830 1.1 rjs SCTP_NOTIFY_DATAGRAM_SENT, chk);
2831 1.1 rjs if (chk->data) {
2832 1.1 rjs sctp_m_freem(chk->data);
2833 1.1 rjs chk->data = NULL;
2834 1.1 rjs }
2835 1.1 rjs if (chk->whoTo)
2836 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2837 1.1 rjs chk->whoTo = NULL;
2838 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2839 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2840 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2841 1.1 rjs panic("Chunk count is negative");
2842 1.1 rjs }
2843 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2844 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue);
2845 1.1 rjs }
2846 1.1 rjs }
2847 1.1 rjs }
2848 1.1 rjs
2849 1.1 rjs void
2850 1.1 rjs sctp_abort_notification(struct sctp_tcb *stcb, int error)
2851 1.1 rjs {
2852 1.1 rjs
2853 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2854 1.1 rjs return;
2855 1.1 rjs }
2856 1.1 rjs /* Tell them we lost the asoc */
2857 1.1 rjs sctp_report_all_outbound(stcb);
2858 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL);
2859 1.1 rjs }
2860 1.1 rjs
2861 1.1 rjs void
2862 1.1 rjs sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2863 1.1 rjs struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err)
2864 1.1 rjs {
2865 1.1 rjs u_int32_t vtag;
2866 1.1 rjs
2867 1.1 rjs vtag = 0;
2868 1.1 rjs if (stcb != NULL) {
2869 1.1 rjs /* We have a TCB to abort, send notification too */
2870 1.1 rjs vtag = stcb->asoc.peer_vtag;
2871 1.1 rjs sctp_abort_notification(stcb, 0);
2872 1.1 rjs }
2873 1.1 rjs sctp_send_abort(m, iphlen, sh, vtag, op_err);
2874 1.1 rjs if (stcb != NULL) {
2875 1.1 rjs /* Ok, now lets free it */
2876 1.1 rjs sctp_free_assoc(inp, stcb);
2877 1.1 rjs } else {
2878 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2879 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2880 1.1 rjs sctp_inpcb_free(inp, 1);
2881 1.1 rjs }
2882 1.1 rjs }
2883 1.1 rjs }
2884 1.1 rjs }
2885 1.1 rjs
2886 1.1 rjs void
2887 1.1 rjs sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2888 1.1 rjs int error, struct mbuf *op_err)
2889 1.1 rjs {
2890 1.1 rjs
2891 1.1 rjs if (stcb == NULL) {
2892 1.1 rjs /* Got to have a TCB */
2893 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2894 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2895 1.1 rjs sctp_inpcb_free(inp, 1);
2896 1.1 rjs }
2897 1.1 rjs }
2898 1.1 rjs return;
2899 1.1 rjs }
2900 1.1 rjs /* notify the ulp */
2901 1.1 rjs if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
2902 1.1 rjs sctp_abort_notification(stcb, error);
2903 1.1 rjs /* notify the peer */
2904 1.1 rjs sctp_send_abort_tcb(stcb, op_err);
2905 1.1 rjs /* now free the asoc */
2906 1.1 rjs sctp_free_assoc(inp, stcb);
2907 1.1 rjs }
2908 1.1 rjs
2909 1.1 rjs void
2910 1.1 rjs sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
2911 1.1 rjs struct sctp_inpcb *inp, struct mbuf *op_err)
2912 1.1 rjs {
2913 1.1 rjs struct sctp_chunkhdr *ch, chunk_buf;
2914 1.1 rjs unsigned int chk_length;
2915 1.1 rjs
2916 1.1 rjs /* Generate a TO address for future reference */
2917 1.1 rjs if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
2918 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2919 1.1 rjs sctp_inpcb_free(inp, 1);
2920 1.1 rjs }
2921 1.1 rjs }
2922 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
2923 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf);
2924 1.1 rjs while (ch != NULL) {
2925 1.1 rjs chk_length = ntohs(ch->chunk_length);
2926 1.1 rjs if (chk_length < sizeof(*ch)) {
2927 1.1 rjs /* break to abort land */
2928 1.1 rjs break;
2929 1.1 rjs }
2930 1.1 rjs switch (ch->chunk_type) {
2931 1.1 rjs case SCTP_PACKET_DROPPED:
2932 1.1 rjs /* we don't respond to pkt-dropped */
2933 1.1 rjs return;
2934 1.1 rjs case SCTP_ABORT_ASSOCIATION:
2935 1.1 rjs /* we don't respond with an ABORT to an ABORT */
2936 1.1 rjs return;
2937 1.1 rjs case SCTP_SHUTDOWN_COMPLETE:
2938 1.1 rjs /*
2939 1.1 rjs * we ignore it since we are not waiting for it
2940 1.1 rjs * and peer is gone
2941 1.1 rjs */
2942 1.1 rjs return;
2943 1.1 rjs case SCTP_SHUTDOWN_ACK:
2944 1.1 rjs sctp_send_shutdown_complete2(m, iphlen, sh);
2945 1.1 rjs return;
2946 1.1 rjs default:
2947 1.1 rjs break;
2948 1.1 rjs }
2949 1.1 rjs offset += SCTP_SIZE32(chk_length);
2950 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
2951 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf);
2952 1.1 rjs }
2953 1.1 rjs sctp_send_abort(m, iphlen, sh, 0, op_err);
2954 1.1 rjs }
2955 1.1 rjs
2956 1.1 rjs /*
2957 1.1 rjs * check the inbound datagram to make sure there is not an abort
2958 1.1 rjs * inside it, if there is return 1, else return 0.
2959 1.1 rjs */
2960 1.1 rjs int
2961 1.1 rjs sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill)
2962 1.1 rjs {
2963 1.1 rjs struct sctp_chunkhdr *ch;
2964 1.1 rjs struct sctp_init_chunk *init_chk, chunk_buf;
2965 1.1 rjs int offset;
2966 1.1 rjs unsigned int chk_length;
2967 1.1 rjs
2968 1.1 rjs offset = iphlen + sizeof(struct sctphdr);
2969 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
2970 1.1 rjs (u_int8_t *)&chunk_buf);
2971 1.1 rjs while (ch != NULL) {
2972 1.1 rjs chk_length = ntohs(ch->chunk_length);
2973 1.1 rjs if (chk_length < sizeof(*ch)) {
2974 1.1 rjs /* packet is probably corrupt */
2975 1.1 rjs break;
2976 1.1 rjs }
2977 1.1 rjs /* we seem to be ok, is it an abort? */
2978 1.1 rjs if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
2979 1.1 rjs /* yep, tell them */
2980 1.1 rjs return (1);
2981 1.1 rjs }
2982 1.1 rjs if (ch->chunk_type == SCTP_INITIATION) {
2983 1.1 rjs /* need to update the Vtag */
2984 1.1 rjs init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
2985 1.1 rjs offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf);
2986 1.1 rjs if (init_chk != NULL) {
2987 1.1 rjs *vtagfill = ntohl(init_chk->init.initiate_tag);
2988 1.1 rjs }
2989 1.1 rjs }
2990 1.1 rjs /* Nope, move to the next chunk */
2991 1.1 rjs offset += SCTP_SIZE32(chk_length);
2992 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
2993 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf);
2994 1.1 rjs }
2995 1.1 rjs return (0);
2996 1.1 rjs }
2997 1.1 rjs
2998 1.1 rjs /*
2999 1.1 rjs * currently (2/02), ifa_addr embeds scope_id's and don't
3000 1.1 rjs * have sin6_scope_id set (i.e. it's 0)
3001 1.1 rjs * so, create this function to compare link local scopes
3002 1.1 rjs */
3003 1.1 rjs uint32_t
3004 1.1 rjs sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2)
3005 1.1 rjs {
3006 1.1 rjs struct sockaddr_in6 a, b;
3007 1.1 rjs
3008 1.1 rjs /* save copies */
3009 1.1 rjs a = *addr1;
3010 1.1 rjs b = *addr2;
3011 1.1 rjs
3012 1.1 rjs if (a.sin6_scope_id == 0)
3013 1.1 rjs if (sa6_recoverscope(&a)) {
3014 1.1 rjs /* can't get scope, so can't match */
3015 1.1 rjs return (0);
3016 1.1 rjs }
3017 1.1 rjs if (b.sin6_scope_id == 0)
3018 1.1 rjs if (sa6_recoverscope(&b)) {
3019 1.1 rjs /* can't get scope, so can't match */
3020 1.1 rjs return (0);
3021 1.1 rjs }
3022 1.1 rjs if (a.sin6_scope_id != b.sin6_scope_id)
3023 1.1 rjs return (0);
3024 1.1 rjs
3025 1.1 rjs return (1);
3026 1.1 rjs }
3027 1.1 rjs
3028 1.1 rjs /*
3029 1.1 rjs * returns a sockaddr_in6 with embedded scope recovered and removed
3030 1.1 rjs */
3031 1.1 rjs const struct sockaddr_in6 *
3032 1.1 rjs sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
3033 1.1 rjs {
3034 1.1 rjs const struct sockaddr_in6 *newaddr;
3035 1.1 rjs
3036 1.1 rjs newaddr = addr;
3037 1.1 rjs /* check and strip embedded scope junk */
3038 1.1 rjs if (addr->sin6_family == AF_INET6) {
3039 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
3040 1.1 rjs if (addr->sin6_scope_id == 0) {
3041 1.1 rjs *store = *addr;
3042 1.1 rjs if (sa6_recoverscope(store) == 0) {
3043 1.1 rjs /* use the recovered scope */
3044 1.1 rjs newaddr = store;
3045 1.1 rjs }
3046 1.1 rjs /* else, return the original "to" addr */
3047 1.1 rjs }
3048 1.1 rjs }
3049 1.1 rjs }
3050 1.1 rjs return (newaddr);
3051 1.1 rjs }
3052 1.1 rjs
3053 1.1 rjs /*
3054 1.1 rjs * are the two addresses the same? currently a "scopeless" check
3055 1.1 rjs * returns: 1 if same, 0 if not
3056 1.1 rjs */
3057 1.1 rjs int
3058 1.1 rjs sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
3059 1.1 rjs {
3060 1.1 rjs
3061 1.1 rjs /* must be valid */
3062 1.1 rjs if (sa1 == NULL || sa2 == NULL)
3063 1.1 rjs return (0);
3064 1.1 rjs
3065 1.1 rjs /* must be the same family */
3066 1.1 rjs if (sa1->sa_family != sa2->sa_family)
3067 1.1 rjs return (0);
3068 1.1 rjs
3069 1.1 rjs if (sa1->sa_family == AF_INET6) {
3070 1.1 rjs /* IPv6 addresses */
3071 1.1 rjs const struct sockaddr_in6 *sin6_1, *sin6_2;
3072 1.1 rjs
3073 1.1 rjs sin6_1 = (const struct sockaddr_in6 *)sa1;
3074 1.1 rjs sin6_2 = (const struct sockaddr_in6 *)sa2;
3075 1.1 rjs return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
3076 1.1 rjs &sin6_2->sin6_addr));
3077 1.1 rjs } else if (sa1->sa_family == AF_INET) {
3078 1.1 rjs /* IPv4 addresses */
3079 1.1 rjs const struct sockaddr_in *sin_1, *sin_2;
3080 1.1 rjs
3081 1.1 rjs sin_1 = (const struct sockaddr_in *)sa1;
3082 1.1 rjs sin_2 = (const struct sockaddr_in *)sa2;
3083 1.1 rjs return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
3084 1.1 rjs } else {
3085 1.1 rjs /* we don't do these... */
3086 1.1 rjs return (0);
3087 1.1 rjs }
3088 1.1 rjs }
3089 1.1 rjs
3090 1.1 rjs void
3091 1.1 rjs sctp_print_address(const struct sockaddr *sa)
3092 1.1 rjs {
3093 1.1 rjs
3094 1.1 rjs if (sa->sa_family == AF_INET6) {
3095 1.1 rjs const struct sockaddr_in6 *sin6;
3096 1.1 rjs sin6 = (const struct sockaddr_in6 *)sa;
3097 1.1 rjs printf("IPv6 address: %s:%d scope:%u\n",
3098 1.1 rjs ip6_sprintf(&sin6->sin6_addr), ntohs(sin6->sin6_port),
3099 1.1 rjs sin6->sin6_scope_id);
3100 1.1 rjs } else if (sa->sa_family == AF_INET) {
3101 1.1 rjs const struct sockaddr_in *sin;
3102 1.1 rjs sin = (const struct sockaddr_in *)sa;
3103 1.1 rjs printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr),
3104 1.1 rjs ntohs(sin->sin_port));
3105 1.1 rjs } else {
3106 1.1 rjs printf("?\n");
3107 1.1 rjs }
3108 1.1 rjs }
3109 1.1 rjs
3110 1.1 rjs void
3111 1.1 rjs sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
3112 1.1 rjs {
3113 1.1 rjs if (iph->ip_v == IPVERSION) {
3114 1.1 rjs struct sockaddr_in lsa, fsa;
3115 1.1 rjs
3116 1.1 rjs memset(&lsa, 0, sizeof(lsa));
3117 1.1 rjs lsa.sin_len = sizeof(lsa);
3118 1.1 rjs lsa.sin_family = AF_INET;
3119 1.1 rjs lsa.sin_addr = iph->ip_src;
3120 1.1 rjs lsa.sin_port = sh->src_port;
3121 1.1 rjs memset(&fsa, 0, sizeof(fsa));
3122 1.1 rjs fsa.sin_len = sizeof(fsa);
3123 1.1 rjs fsa.sin_family = AF_INET;
3124 1.1 rjs fsa.sin_addr = iph->ip_dst;
3125 1.1 rjs fsa.sin_port = sh->dest_port;
3126 1.1 rjs printf("src: ");
3127 1.1 rjs sctp_print_address((struct sockaddr *)&lsa);
3128 1.1 rjs printf("dest: ");
3129 1.1 rjs sctp_print_address((struct sockaddr *)&fsa);
3130 1.1 rjs } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
3131 1.1 rjs struct ip6_hdr *ip6;
3132 1.1 rjs struct sockaddr_in6 lsa6, fsa6;
3133 1.1 rjs
3134 1.1 rjs ip6 = (struct ip6_hdr *)iph;
3135 1.1 rjs memset(&lsa6, 0, sizeof(lsa6));
3136 1.1 rjs lsa6.sin6_len = sizeof(lsa6);
3137 1.1 rjs lsa6.sin6_family = AF_INET6;
3138 1.1 rjs lsa6.sin6_addr = ip6->ip6_src;
3139 1.1 rjs lsa6.sin6_port = sh->src_port;
3140 1.1 rjs memset(&fsa6, 0, sizeof(fsa6));
3141 1.1 rjs fsa6.sin6_len = sizeof(fsa6);
3142 1.1 rjs fsa6.sin6_family = AF_INET6;
3143 1.1 rjs fsa6.sin6_addr = ip6->ip6_dst;
3144 1.1 rjs fsa6.sin6_port = sh->dest_port;
3145 1.1 rjs printf("src: ");
3146 1.1 rjs sctp_print_address((struct sockaddr *)&lsa6);
3147 1.1 rjs printf("dest: ");
3148 1.1 rjs sctp_print_address((struct sockaddr *)&fsa6);
3149 1.1 rjs }
3150 1.1 rjs }
3151 1.1 rjs
3152 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__)
3153 1.1 rjs
3154 1.1 rjs /* cloned from uipc_socket.c */
3155 1.1 rjs
3156 1.1 rjs #define SCTP_SBLINKRECORD(sb, m0) do { \
3157 1.1 rjs if ((sb)->sb_lastrecord != NULL) \
3158 1.1 rjs (sb)->sb_lastrecord->m_nextpkt = (m0); \
3159 1.1 rjs else \
3160 1.1 rjs (sb)->sb_mb = (m0); \
3161 1.1 rjs (sb)->sb_lastrecord = (m0); \
3162 1.1 rjs } while (/*CONSTCOND*/0)
3163 1.1 rjs #endif
3164 1.1 rjs
3165 1.1 rjs
3166 1.1 rjs int
3167 1.1 rjs sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa,
3168 1.1 rjs struct mbuf *m0, struct mbuf *control,
3169 1.1 rjs u_int32_t tag, struct sctp_inpcb *inp)
3170 1.1 rjs {
3171 1.1 rjs #ifdef __NetBSD__
3172 1.1 rjs struct mbuf *m, *n;
3173 1.1 rjs
3174 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3175 1.1 rjs panic("sbappendaddr_nocheck");
3176 1.1 rjs
3177 1.1 rjs m0->m_pkthdr.csum_data = (int)tag;
3178 1.1 rjs
3179 1.1 rjs for (n = control; n; n = n->m_next) {
3180 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */
3181 1.1 rjs break;
3182 1.1 rjs }
3183 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3184 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3185 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3186 1.1 rjs if (m == 0)
3187 1.1 rjs return (0);
3188 1.1 rjs
3189 1.1 rjs m->m_len = asa->sa_len;
3190 1.1 rjs memcpy(mtod(m, void *), (const void *)asa, asa->sa_len);
3191 1.1 rjs } else {
3192 1.1 rjs m = NULL;
3193 1.1 rjs }
3194 1.1 rjs if (n) {
3195 1.1 rjs n->m_next = m0; /* concatenate data to control */
3196 1.1 rjs }else {
3197 1.1 rjs control = m0;
3198 1.1 rjs }
3199 1.1 rjs if (m)
3200 1.1 rjs m->m_next = control;
3201 1.1 rjs else
3202 1.1 rjs m = control;
3203 1.1 rjs m->m_pkthdr.csum_data = tag;
3204 1.1 rjs
3205 1.1 rjs for (n = m; n; n = n->m_next)
3206 1.1 rjs sballoc(sb, n);
3207 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3208 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3209 1.1 rjs inp->sb_last_mpkt = NULL;
3210 1.1 rjs }
3211 1.1 rjs if (inp->sb_last_mpkt)
3212 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3213 1.1 rjs else {
3214 1.1 rjs while (n->m_nextpkt) {
3215 1.1 rjs n = n->m_nextpkt;
3216 1.1 rjs }
3217 1.1 rjs n->m_nextpkt = m;
3218 1.1 rjs }
3219 1.1 rjs inp->sb_last_mpkt = m;
3220 1.1 rjs } else {
3221 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3222 1.1 rjs inp->sctp_vtag_first = tag;
3223 1.1 rjs }
3224 1.1 rjs return (1);
3225 1.1 rjs #endif
3226 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__)
3227 1.1 rjs struct mbuf *m, *n, *nlast;
3228 1.1 rjs int cnt=0;
3229 1.1 rjs
3230 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3231 1.1 rjs panic("sbappendaddr_nocheck");
3232 1.1 rjs
3233 1.1 rjs for (n = control; n; n = n->m_next) {
3234 1.1 rjs if (n->m_next == 0) /* get pointer to last control buf */
3235 1.1 rjs break;
3236 1.1 rjs }
3237 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3238 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3239 1.1 rjs if (asa->sa_len > MHLEN)
3240 1.1 rjs return (0);
3241 1.1 rjs try_again:
3242 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3243 1.1 rjs if (m == 0)
3244 1.1 rjs return (0);
3245 1.1 rjs m->m_len = 0;
3246 1.1 rjs /* safety */
3247 1.1 rjs if (m == m0) {
3248 1.1 rjs printf("Duplicate mbuf allocated %p in and mget returned %p?\n",
3249 1.1 rjs m0, m);
3250 1.1 rjs if (cnt) {
3251 1.1 rjs panic("more than once");
3252 1.1 rjs }
3253 1.1 rjs cnt++;
3254 1.1 rjs goto try_again;
3255 1.1 rjs }
3256 1.1 rjs m->m_len = asa->sa_len;
3257 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len);
3258 1.1 rjs }
3259 1.1 rjs else {
3260 1.1 rjs m = NULL;
3261 1.1 rjs }
3262 1.1 rjs if (n)
3263 1.1 rjs n->m_next = m0; /* concatenate data to control */
3264 1.1 rjs else
3265 1.1 rjs control = m0;
3266 1.1 rjs if (m)
3267 1.1 rjs m->m_next = control;
3268 1.1 rjs else
3269 1.1 rjs m = control;
3270 1.1 rjs m->m_pkthdr.csum_data = (int)tag;
3271 1.1 rjs
3272 1.1 rjs for (n = m; n; n = n->m_next)
3273 1.1 rjs sballoc(sb, n);
3274 1.1 rjs nlast = n;
3275 1.1 rjs if (sb->sb_mb == NULL) {
3276 1.1 rjs inp->sctp_vtag_first = tag;
3277 1.1 rjs }
3278 1.1 rjs
3279 1.1 rjs #ifdef __FREEBSD__
3280 1.1 rjs if (sb->sb_mb == NULL)
3281 1.1 rjs inp->sctp_vtag_first = tag;
3282 1.1 rjs SCTP_SBLINKRECORD(sb, m);
3283 1.1 rjs sb->sb_mbtail = nlast;
3284 1.1 rjs #else
3285 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3286 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3287 1.1 rjs inp->sb_last_mpkt = NULL;
3288 1.1 rjs }
3289 1.1 rjs if (inp->sb_last_mpkt)
3290 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3291 1.1 rjs else {
3292 1.1 rjs while (n->m_nextpkt) {
3293 1.1 rjs n = n->m_nextpkt;
3294 1.1 rjs }
3295 1.1 rjs n->m_nextpkt = m;
3296 1.1 rjs }
3297 1.1 rjs inp->sb_last_mpkt = m;
3298 1.1 rjs } else {
3299 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3300 1.1 rjs inp->sctp_vtag_first = tag;
3301 1.1 rjs }
3302 1.1 rjs #endif
3303 1.1 rjs return (1);
3304 1.1 rjs #endif
3305 1.1 rjs #ifdef __OpenBSD__
3306 1.1 rjs struct mbuf *m, *n;
3307 1.1 rjs
3308 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3309 1.1 rjs panic("sbappendaddr_nocheck");
3310 1.1 rjs m0->m_pkthdr.csum = (int)tag;
3311 1.1 rjs for (n = control; n; n = n->m_next) {
3312 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */
3313 1.1 rjs break;
3314 1.1 rjs }
3315 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3316 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3317 1.1 rjs if (asa->sa_len > MHLEN)
3318 1.1 rjs return (0);
3319 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3320 1.1 rjs if (m == 0)
3321 1.1 rjs return (0);
3322 1.1 rjs m->m_len = asa->sa_len;
3323 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len);
3324 1.1 rjs } else {
3325 1.1 rjs m = NULL;
3326 1.1 rjs }
3327 1.1 rjs if (n)
3328 1.1 rjs n->m_next = m0; /* concatenate data to control */
3329 1.1 rjs else
3330 1.1 rjs control = m0;
3331 1.1 rjs
3332 1.1 rjs m->m_pkthdr.csum = (int)tag;
3333 1.1 rjs m->m_next = control;
3334 1.1 rjs for (n = m; n; n = n->m_next)
3335 1.1 rjs sballoc(sb, n);
3336 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3337 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3338 1.1 rjs inp->sb_last_mpkt = NULL;
3339 1.1 rjs }
3340 1.1 rjs if (inp->sb_last_mpkt)
3341 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3342 1.1 rjs else {
3343 1.1 rjs while (n->m_nextpkt) {
3344 1.1 rjs n = n->m_nextpkt;
3345 1.1 rjs }
3346 1.1 rjs n->m_nextpkt = m;
3347 1.1 rjs }
3348 1.1 rjs inp->sb_last_mpkt = m;
3349 1.1 rjs } else {
3350 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3351 1.1 rjs inp->sctp_vtag_first = tag;
3352 1.1 rjs }
3353 1.1 rjs return (1);
3354 1.1 rjs #endif
3355 1.1 rjs }
3356 1.1 rjs
3357 1.1 rjs /*************HOLD THIS COMMENT FOR PATCH FILE OF
3358 1.1 rjs *************ALTERNATE ROUTING CODE
3359 1.1 rjs */
3360 1.1 rjs
3361 1.1 rjs /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
3362 1.1 rjs *************ALTERNATE ROUTING CODE
3363 1.1 rjs */
3364 1.1 rjs
3365 1.1 rjs struct mbuf *
3366 1.1 rjs sctp_generate_invmanparam(int err)
3367 1.1 rjs {
3368 1.1 rjs /* Return a MBUF with a invalid mandatory parameter */
3369 1.1 rjs struct mbuf *m;
3370 1.1 rjs
3371 1.1 rjs MGET(m, M_DONTWAIT, MT_DATA);
3372 1.1 rjs if (m) {
3373 1.1 rjs struct sctp_paramhdr *ph;
3374 1.1 rjs m->m_len = sizeof(struct sctp_paramhdr);
3375 1.1 rjs ph = mtod(m, struct sctp_paramhdr *);
3376 1.1 rjs ph->param_length = htons(sizeof(struct sctp_paramhdr));
3377 1.1 rjs ph->param_type = htons(err);
3378 1.1 rjs }
3379 1.1 rjs return (m);
3380 1.1 rjs }
3381 1.1 rjs
3382 1.1 rjs static int
3383 1.1 rjs sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc)
3384 1.1 rjs {
3385 1.1 rjs struct mbuf *m;
3386 1.1 rjs /*
3387 1.1 rjs * given a mbuf chain, look through it finding
3388 1.1 rjs * the M_PKTHDR and return 1 if it belongs to
3389 1.1 rjs * the association given. We tell this by
3390 1.1 rjs * a kludge where we stuff the my_vtag of the asoc
3391 1.1 rjs * into the m->m_pkthdr.csum_data/csum field.
3392 1.1 rjs */
3393 1.1 rjs m = this;
3394 1.1 rjs while (m) {
3395 1.1 rjs if (m->m_flags & M_PKTHDR) {
3396 1.1 rjs /* check it */
3397 1.1 rjs #if defined(__OpenBSD__)
3398 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag)
3399 1.1 rjs #else
3400 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag)
3401 1.1 rjs #endif
3402 1.1 rjs {
3403 1.1 rjs /* Yep */
3404 1.1 rjs return (1);
3405 1.1 rjs }
3406 1.1 rjs }
3407 1.1 rjs m = m->m_next;
3408 1.1 rjs }
3409 1.1 rjs return (0);
3410 1.1 rjs }
3411 1.1 rjs
3412 1.1 rjs u_int32_t
3413 1.1 rjs sctp_get_first_vtag_from_sb(struct socket *so)
3414 1.1 rjs {
3415 1.1 rjs struct mbuf *this, *at;
3416 1.1 rjs u_int32_t retval;
3417 1.1 rjs
3418 1.1 rjs retval = 0;
3419 1.1 rjs if (so->so_rcv.sb_mb) {
3420 1.1 rjs /* grubbing time */
3421 1.1 rjs this = so->so_rcv.sb_mb;
3422 1.1 rjs while (this) {
3423 1.1 rjs at = this;
3424 1.1 rjs /* get to the m_pkthdr */
3425 1.1 rjs while (at) {
3426 1.1 rjs if (at->m_flags & M_PKTHDR)
3427 1.1 rjs break;
3428 1.1 rjs else {
3429 1.1 rjs at = at->m_next;
3430 1.1 rjs }
3431 1.1 rjs }
3432 1.1 rjs /* now do we have a m_pkthdr */
3433 1.1 rjs if (at && (at->m_flags & M_PKTHDR)) {
3434 1.1 rjs /* check it */
3435 1.1 rjs #if defined(__OpenBSD__)
3436 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum != 0)
3437 1.1 rjs #else
3438 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum_data != 0)
3439 1.1 rjs #endif
3440 1.1 rjs {
3441 1.1 rjs /* its the one */
3442 1.1 rjs #if defined(__OpenBSD__)
3443 1.1 rjs retval = (u_int32_t)at->m_pkthdr.csum;
3444 1.1 rjs #else
3445 1.1 rjs retval =
3446 1.1 rjs (u_int32_t)at->m_pkthdr.csum_data;
3447 1.1 rjs #endif
3448 1.1 rjs break;
3449 1.1 rjs }
3450 1.1 rjs }
3451 1.1 rjs this = this->m_nextpkt;
3452 1.1 rjs }
3453 1.1 rjs
3454 1.1 rjs }
3455 1.1 rjs return (retval);
3456 1.1 rjs
3457 1.1 rjs }
3458 1.1 rjs void
3459 1.1 rjs sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old,
3460 1.1 rjs struct socket *new, struct sctp_tcb *stcb)
3461 1.1 rjs {
3462 1.1 rjs struct mbuf **put, **take, *next, *this;
3463 1.1 rjs struct sockbuf *old_sb, *new_sb;
3464 1.1 rjs struct sctp_association *asoc;
3465 1.1 rjs int moved_top = 0;
3466 1.1 rjs
3467 1.1 rjs asoc = &stcb->asoc;
3468 1.1 rjs old_sb = &old->so_rcv;
3469 1.1 rjs new_sb = &new->so_rcv;
3470 1.1 rjs if (old_sb->sb_mb == NULL) {
3471 1.1 rjs /* Nothing to move */
3472 1.1 rjs return;
3473 1.1 rjs }
3474 1.1 rjs
3475 1.1 rjs if (inp->sctp_vtag_first == asoc->my_vtag) {
3476 1.1 rjs /* First one must be moved */
3477 1.1 rjs struct mbuf *mm;
3478 1.1 rjs for (mm = old_sb->sb_mb; mm; mm = mm->m_next) {
3479 1.1 rjs /*
3480 1.1 rjs * Go down the chain and fix
3481 1.1 rjs * the space allocation of the
3482 1.1 rjs * two sockets.
3483 1.1 rjs */
3484 1.1 rjs sbfree(old_sb, mm);
3485 1.1 rjs sballoc(new_sb, mm);
3486 1.1 rjs }
3487 1.1 rjs new_sb->sb_mb = old_sb->sb_mb;
3488 1.1 rjs old_sb->sb_mb = new_sb->sb_mb->m_nextpkt;
3489 1.1 rjs new_sb->sb_mb->m_nextpkt = NULL;
3490 1.1 rjs put = &new_sb->sb_mb->m_nextpkt;
3491 1.1 rjs moved_top = 1;
3492 1.1 rjs } else {
3493 1.1 rjs put = &new_sb->sb_mb;
3494 1.1 rjs }
3495 1.1 rjs
3496 1.1 rjs take = &old_sb->sb_mb;
3497 1.1 rjs next = old_sb->sb_mb;
3498 1.1 rjs while (next) {
3499 1.1 rjs this = next;
3500 1.1 rjs /* postion for next one */
3501 1.1 rjs next = this->m_nextpkt;
3502 1.1 rjs /* check the tag of this packet */
3503 1.1 rjs if (sctp_should_be_moved(this, asoc)) {
3504 1.1 rjs /* yes this needs to be moved */
3505 1.1 rjs struct mbuf *mm;
3506 1.1 rjs *take = this->m_nextpkt;
3507 1.1 rjs this->m_nextpkt = NULL;
3508 1.1 rjs *put = this;
3509 1.1 rjs for (mm = this; mm; mm = mm->m_next) {
3510 1.1 rjs /*
3511 1.1 rjs * Go down the chain and fix
3512 1.1 rjs * the space allocation of the
3513 1.1 rjs * two sockets.
3514 1.1 rjs */
3515 1.1 rjs sbfree(old_sb, mm);
3516 1.1 rjs sballoc(new_sb, mm);
3517 1.1 rjs }
3518 1.1 rjs put = &this->m_nextpkt;
3519 1.1 rjs
3520 1.1 rjs } else {
3521 1.1 rjs /* no advance our take point. */
3522 1.1 rjs take = &this->m_nextpkt;
3523 1.1 rjs }
3524 1.1 rjs }
3525 1.1 rjs if (moved_top) {
3526 1.1 rjs /*
3527 1.1 rjs * Ok so now we must re-postion vtag_first to
3528 1.1 rjs * match the new first one since we moved the
3529 1.1 rjs * mbuf at the top.
3530 1.1 rjs */
3531 1.1 rjs inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old);
3532 1.1 rjs }
3533 1.1 rjs }
3534 1.1 rjs
3535 1.1 rjs void
3536 1.1 rjs sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
3537 1.1 rjs struct sctp_tmit_chunk *tp1)
3538 1.1 rjs {
3539 1.1 rjs if (tp1->data == NULL) {
3540 1.1 rjs return;
3541 1.1 rjs }
3542 1.1 rjs #ifdef SCTP_MBCNT_LOGGING
3543 1.1 rjs sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
3544 1.1 rjs asoc->total_output_queue_size,
3545 1.1 rjs tp1->book_size,
3546 1.1 rjs asoc->total_output_mbuf_queue_size,
3547 1.1 rjs tp1->mbcnt);
3548 1.1 rjs #endif
3549 1.1 rjs if (asoc->total_output_queue_size >= tp1->book_size) {
3550 1.1 rjs asoc->total_output_queue_size -= tp1->book_size;
3551 1.1 rjs } else {
3552 1.1 rjs asoc->total_output_queue_size = 0;
3553 1.1 rjs }
3554 1.1 rjs
3555 1.1 rjs /* Now free the mbuf */
3556 1.1 rjs if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) {
3557 1.1 rjs asoc->total_output_mbuf_queue_size -= tp1->mbcnt;
3558 1.1 rjs } else {
3559 1.1 rjs asoc->total_output_mbuf_queue_size = 0;
3560 1.1 rjs }
3561 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3562 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
3563 1.1 rjs if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
3564 1.1 rjs stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
3565 1.1 rjs } else {
3566 1.1 rjs stcb->sctp_socket->so_snd.sb_cc = 0;
3567 1.1 rjs
3568 1.1 rjs }
3569 1.1 rjs if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) {
3570 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt;
3571 1.1 rjs } else {
3572 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt = 0;
3573 1.1 rjs }
3574 1.1 rjs }
3575 1.1 rjs }
3576 1.1 rjs
3577 1.1 rjs int
3578 1.1 rjs sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
3579 1.1 rjs int reason, struct sctpchunk_listhead *queue)
3580 1.1 rjs {
3581 1.1 rjs int ret_sz = 0;
3582 1.1 rjs int notdone;
3583 1.1 rjs uint8_t foundeom = 0;
3584 1.1 rjs
3585 1.1 rjs do {
3586 1.1 rjs ret_sz += tp1->book_size;
3587 1.1 rjs tp1->sent = SCTP_FORWARD_TSN_SKIP;
3588 1.1 rjs if (tp1->data) {
3589 1.1 rjs sctp_free_bufspace(stcb, &stcb->asoc, tp1);
3590 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1);
3591 1.1 rjs sctp_m_freem(tp1->data);
3592 1.1 rjs tp1->data = NULL;
3593 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
3594 1.1 rjs }
3595 1.1 rjs if (tp1->flags & SCTP_PR_SCTP_BUFFER) {
3596 1.1 rjs stcb->asoc.sent_queue_cnt_removeable--;
3597 1.1 rjs }
3598 1.1 rjs if (queue == &stcb->asoc.send_queue) {
3599 1.1 rjs TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
3600 1.1 rjs /* on to the sent queue */
3601 1.1 rjs TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
3602 1.1 rjs sctp_next);
3603 1.1 rjs stcb->asoc.sent_queue_cnt++;
3604 1.1 rjs }
3605 1.1 rjs if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
3606 1.1 rjs SCTP_DATA_NOT_FRAG) {
3607 1.1 rjs /* not frag'ed we ae done */
3608 1.1 rjs notdone = 0;
3609 1.1 rjs foundeom = 1;
3610 1.1 rjs } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
3611 1.1 rjs /* end of frag, we are done */
3612 1.1 rjs notdone = 0;
3613 1.1 rjs foundeom = 1;
3614 1.1 rjs } else {
3615 1.1 rjs /* Its a begin or middle piece, we must mark all of it */
3616 1.1 rjs notdone = 1;
3617 1.1 rjs tp1 = TAILQ_NEXT(tp1, sctp_next);
3618 1.1 rjs }
3619 1.1 rjs } while (tp1 && notdone);
3620 1.1 rjs if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
3621 1.1 rjs /*
3622 1.1 rjs * The multi-part message was scattered
3623 1.1 rjs * across the send and sent queue.
3624 1.1 rjs */
3625 1.1 rjs tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
3626 1.1 rjs /*
3627 1.1 rjs * recurse throught the send_queue too, starting at the
3628 1.1 rjs * beginning.
3629 1.1 rjs */
3630 1.1 rjs if (tp1) {
3631 1.1 rjs ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
3632 1.1 rjs &stcb->asoc.send_queue);
3633 1.1 rjs } else {
3634 1.1 rjs printf("hmm, nothing on the send queue and no EOM?\n");
3635 1.1 rjs }
3636 1.1 rjs }
3637 1.1 rjs return (ret_sz);
3638 1.1 rjs }
3639 1.1 rjs
3640 1.1 rjs /*
3641 1.1 rjs * checks to see if the given address, sa, is one that is currently
3642 1.1 rjs * known by the kernel
3643 1.1 rjs * note: can't distinguish the same address on multiple interfaces and
3644 1.1 rjs * doesn't handle multiple addresses with different zone/scope id's
3645 1.1 rjs * note: ifa_ifwithaddr() compares the entire sockaddr struct
3646 1.1 rjs */
3647 1.1 rjs struct ifaddr *
3648 1.1 rjs sctp_find_ifa_by_addr(struct sockaddr *sa)
3649 1.1 rjs {
3650 1.1 rjs struct ifnet *ifn;
3651 1.1 rjs struct ifaddr *ifa;
3652 1.1 rjs
3653 1.1 rjs /* go through all our known interfaces */
3654 1.1 rjs TAILQ_FOREACH(ifn, &ifnet_list, if_list) {
3655 1.1 rjs /* go through each interface addresses */
3656 1.1 rjs TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
3657 1.1 rjs /* correct family? */
3658 1.1 rjs if (ifa->ifa_addr->sa_family != sa->sa_family)
3659 1.1 rjs continue;
3660 1.1 rjs
3661 1.1 rjs #ifdef INET6
3662 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET6) {
3663 1.1 rjs /* IPv6 address */
3664 1.1 rjs struct sockaddr_in6 *sin1, *sin2, sin6_tmp;
3665 1.1 rjs sin1 = (struct sockaddr_in6 *)ifa->ifa_addr;
3666 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) {
3667 1.1 rjs /* create a copy and clear scope */
3668 1.1 rjs memcpy(&sin6_tmp, sin1,
3669 1.1 rjs sizeof(struct sockaddr_in6));
3670 1.1 rjs sin1 = &sin6_tmp;
3671 1.1 rjs in6_clearscope(&sin1->sin6_addr);
3672 1.1 rjs }
3673 1.1 rjs sin2 = (struct sockaddr_in6 *)sa;
3674 1.1 rjs if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
3675 1.1 rjs sizeof(struct in6_addr)) == 0) {
3676 1.1 rjs /* found it */
3677 1.1 rjs return (ifa);
3678 1.1 rjs }
3679 1.1 rjs } else
3680 1.1 rjs #endif
3681 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET) {
3682 1.1 rjs /* IPv4 address */
3683 1.1 rjs struct sockaddr_in *sin1, *sin2;
3684 1.1 rjs sin1 = (struct sockaddr_in *)ifa->ifa_addr;
3685 1.1 rjs sin2 = (struct sockaddr_in *)sa;
3686 1.1 rjs if (sin1->sin_addr.s_addr ==
3687 1.1 rjs sin2->sin_addr.s_addr) {
3688 1.1 rjs /* found it */
3689 1.1 rjs return (ifa);
3690 1.1 rjs }
3691 1.1 rjs }
3692 1.1 rjs /* else, not AF_INET or AF_INET6, so skip */
3693 1.1 rjs } /* end foreach ifa */
3694 1.1 rjs } /* end foreach ifn */
3695 1.1 rjs /* not found! */
3696 1.1 rjs return (NULL);
3697 1.1 rjs }
3698 1.1 rjs
3699 1.1 rjs
3700 1.1 rjs #ifdef __APPLE__
3701 1.1 rjs /*
3702 1.1 rjs * here we hack in a fix for Apple's m_copym for the case where the first mbuf
3703 1.1 rjs * in the chain is a M_PKTHDR and the length is zero
3704 1.1 rjs */
3705 1.1 rjs static void
3706 1.1 rjs sctp_pkthdr_fix(struct mbuf *m)
3707 1.1 rjs {
3708 1.1 rjs struct mbuf *m_nxt;
3709 1.1 rjs
3710 1.1 rjs if ((m->m_flags & M_PKTHDR) == 0) {
3711 1.1 rjs /* not a PKTHDR */
3712 1.1 rjs return;
3713 1.1 rjs }
3714 1.1 rjs
3715 1.1 rjs if (m->m_len != 0) {
3716 1.1 rjs /* not a zero length PKTHDR mbuf */
3717 1.1 rjs return;
3718 1.1 rjs }
3719 1.1 rjs
3720 1.1 rjs /* let's move in a word into the first mbuf... yes, ugly! */
3721 1.1 rjs m_nxt = m->m_next;
3722 1.1 rjs if (m_nxt == NULL) {
3723 1.1 rjs /* umm... not a very useful mbuf chain... */
3724 1.1 rjs return;
3725 1.1 rjs }
3726 1.1 rjs if ((size_t)m_nxt->m_len > sizeof(long)) {
3727 1.1 rjs /* move over a long */
3728 1.1 rjs bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long));
3729 1.1 rjs /* update mbuf data pointers and lengths */
3730 1.1 rjs m->m_len += sizeof(long);
3731 1.1 rjs m_nxt->m_data += sizeof(long);
3732 1.1 rjs m_nxt->m_len -= sizeof(long);
3733 1.1 rjs }
3734 1.1 rjs }
3735 1.1 rjs
3736 1.1 rjs inline struct mbuf *
3737 1.1 rjs sctp_m_copym(struct mbuf *m, int off, int len, int wait)
3738 1.1 rjs {
3739 1.1 rjs sctp_pkthdr_fix(m);
3740 1.1 rjs return (m_copym(m, off, len, wait));
3741 1.1 rjs }
3742 1.1 rjs #endif /* __APPLE__ */
3743