sctputil.c revision 1.12 1 1.1 rjs /* $KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $ */
2 1.12 christos /* $NetBSD: sctputil.c,v 1.12 2017/01/16 15:44:47 christos 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.12 christos __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.12 2017/01/16 15:44:47 christos 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/route.h>
61 1.1 rjs
62 1.1 rjs #ifdef INET6
63 1.1 rjs #include <sys/domain.h>
64 1.1 rjs #endif
65 1.1 rjs
66 1.1 rjs #include <machine/limits.h>
67 1.1 rjs
68 1.1 rjs #include <net/if.h>
69 1.1 rjs #include <net/if_types.h>
70 1.1 rjs #include <net/route.h>
71 1.1 rjs
72 1.1 rjs #include <netinet/in.h>
73 1.1 rjs #include <netinet/in_systm.h>
74 1.1 rjs #include <netinet/ip.h>
75 1.1 rjs #include <netinet/in_pcb.h>
76 1.1 rjs #include <netinet/in_var.h>
77 1.1 rjs #include <netinet/ip_var.h>
78 1.1 rjs
79 1.1 rjs #ifdef INET6
80 1.1 rjs #include <netinet/ip6.h>
81 1.1 rjs #include <netinet6/ip6_var.h>
82 1.1 rjs #include <netinet6/scope6_var.h>
83 1.1 rjs #include <netinet6/in6_pcb.h>
84 1.1 rjs
85 1.1 rjs #endif /* INET6 */
86 1.1 rjs
87 1.1 rjs #include <netinet/sctp_pcb.h>
88 1.1 rjs
89 1.1 rjs #ifdef IPSEC
90 1.6 rjs #include <netipsec/ipsec.h>
91 1.6 rjs #include <netipsec/key.h>
92 1.1 rjs #endif /* IPSEC */
93 1.1 rjs
94 1.1 rjs #include <netinet/sctputil.h>
95 1.1 rjs #include <netinet/sctp_var.h>
96 1.1 rjs #ifdef INET6
97 1.1 rjs #include <netinet6/sctp6_var.h>
98 1.1 rjs #endif
99 1.1 rjs #include <netinet/sctp_header.h>
100 1.1 rjs #include <netinet/sctp_output.h>
101 1.1 rjs #include <netinet/sctp_hashdriver.h>
102 1.1 rjs #include <netinet/sctp_uio.h>
103 1.1 rjs #include <netinet/sctp_timer.h>
104 1.1 rjs #include <netinet/sctp_crc32.h>
105 1.1 rjs #include <netinet/sctp_indata.h> /* for sctp_deliver_data() */
106 1.1 rjs #define NUMBER_OF_MTU_SIZES 18
107 1.1 rjs
108 1.1 rjs #ifdef SCTP_DEBUG
109 1.1 rjs extern u_int32_t sctp_debug_on;
110 1.1 rjs #endif
111 1.1 rjs
112 1.1 rjs #ifdef SCTP_STAT_LOGGING
113 1.1 rjs int sctp_cwnd_log_at=0;
114 1.1 rjs int sctp_cwnd_log_rolled=0;
115 1.1 rjs struct sctp_cwnd_log sctp_clog[SCTP_STAT_LOG_SIZE];
116 1.1 rjs
117 1.1 rjs void sctp_clr_stat_log(void)
118 1.1 rjs {
119 1.1 rjs sctp_cwnd_log_at=0;
120 1.1 rjs sctp_cwnd_log_rolled=0;
121 1.1 rjs }
122 1.1 rjs
123 1.1 rjs void
124 1.1 rjs sctp_log_strm_del_alt(u_int32_t tsn, u_int16_t sseq, int from)
125 1.1 rjs {
126 1.1 rjs
127 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
128 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
129 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = tsn;
130 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = sseq;
131 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
132 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
133 1.1 rjs sctp_cwnd_log_at++;
134 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
135 1.1 rjs sctp_cwnd_log_at = 0;
136 1.1 rjs sctp_cwnd_log_rolled = 1;
137 1.1 rjs }
138 1.1 rjs
139 1.1 rjs }
140 1.1 rjs
141 1.1 rjs void
142 1.1 rjs sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
143 1.1 rjs {
144 1.1 rjs
145 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
146 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAP;
147 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.base = map;
148 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.cum = cum;
149 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.high = high;
150 1.1 rjs sctp_cwnd_log_at++;
151 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
152 1.1 rjs sctp_cwnd_log_at = 0;
153 1.1 rjs sctp_cwnd_log_rolled = 1;
154 1.1 rjs }
155 1.1 rjs }
156 1.1 rjs
157 1.1 rjs void
158 1.1 rjs sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
159 1.1 rjs int from)
160 1.1 rjs {
161 1.1 rjs
162 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
163 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_FR;
164 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_tsn = biggest_tsn;
165 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_new_tsn = biggest_new_tsn;
166 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.tsn = tsn;
167 1.1 rjs sctp_cwnd_log_at++;
168 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
169 1.1 rjs sctp_cwnd_log_at = 0;
170 1.1 rjs sctp_cwnd_log_rolled = 1;
171 1.1 rjs }
172 1.1 rjs }
173 1.1 rjs
174 1.1 rjs void
175 1.1 rjs sctp_log_strm_del(struct sctp_tmit_chunk *chk, struct sctp_tmit_chunk *poschk,
176 1.1 rjs int from)
177 1.1 rjs {
178 1.1 rjs
179 1.1 rjs if (chk == NULL) {
180 1.1 rjs printf("Gak log of NULL?\n");
181 1.1 rjs return;
182 1.1 rjs }
183 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
184 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM;
185 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = chk->rec.data.TSN_seq;
186 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = chk->rec.data.stream_seq;
187 1.1 rjs if (poschk != NULL) {
188 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn =
189 1.1 rjs poschk->rec.data.TSN_seq;
190 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq =
191 1.1 rjs poschk->rec.data.stream_seq;
192 1.1 rjs } else {
193 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0;
194 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0;
195 1.1 rjs }
196 1.1 rjs sctp_cwnd_log_at++;
197 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
198 1.1 rjs sctp_cwnd_log_at = 0;
199 1.1 rjs sctp_cwnd_log_rolled = 1;
200 1.1 rjs }
201 1.1 rjs }
202 1.1 rjs
203 1.1 rjs void
204 1.1 rjs sctp_log_cwnd(struct sctp_nets *net, int augment, uint8_t from)
205 1.1 rjs {
206 1.1 rjs
207 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
208 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_CWND;
209 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
210 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = net->cwnd;
211 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
212 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = augment;
213 1.1 rjs sctp_cwnd_log_at++;
214 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
215 1.1 rjs sctp_cwnd_log_at = 0;
216 1.1 rjs sctp_cwnd_log_rolled = 1;
217 1.1 rjs }
218 1.1 rjs }
219 1.1 rjs
220 1.1 rjs void
221 1.1 rjs sctp_log_maxburst(struct sctp_nets *net, int error, int burst, uint8_t from)
222 1.1 rjs {
223 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
224 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAXBURST;
225 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net;
226 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = error;
227 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size;
228 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = burst;
229 1.1 rjs sctp_cwnd_log_at++;
230 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
231 1.1 rjs sctp_cwnd_log_at = 0;
232 1.1 rjs sctp_cwnd_log_rolled = 1;
233 1.1 rjs }
234 1.1 rjs }
235 1.1 rjs
236 1.1 rjs void
237 1.1 rjs sctp_log_rwnd(uint8_t from, u_int32_t peers_rwnd , u_int32_t snd_size, u_int32_t overhead)
238 1.1 rjs {
239 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
240 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
241 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
242 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = snd_size;
243 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
244 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = 0;
245 1.1 rjs sctp_cwnd_log_at++;
246 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
247 1.1 rjs sctp_cwnd_log_at = 0;
248 1.1 rjs sctp_cwnd_log_rolled = 1;
249 1.1 rjs }
250 1.1 rjs }
251 1.1 rjs
252 1.1 rjs void
253 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)
254 1.1 rjs {
255 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
256 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND;
257 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd;
258 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = flight_size;
259 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead;
260 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = a_rwndval;
261 1.1 rjs sctp_cwnd_log_at++;
262 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
263 1.1 rjs sctp_cwnd_log_at = 0;
264 1.1 rjs sctp_cwnd_log_rolled = 1;
265 1.1 rjs }
266 1.1 rjs }
267 1.1 rjs
268 1.1 rjs void
269 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)
270 1.1 rjs {
271 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
272 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MBCNT;
273 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_size = total_oq;
274 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.size_change = book;
275 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_mb_size = total_mbcnt_q;
276 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.mbcnt_change = mbcnt;
277 1.1 rjs sctp_cwnd_log_at++;
278 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
279 1.1 rjs sctp_cwnd_log_at = 0;
280 1.1 rjs sctp_cwnd_log_rolled = 1;
281 1.1 rjs }
282 1.1 rjs }
283 1.1 rjs
284 1.1 rjs void
285 1.1 rjs sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc)
286 1.1 rjs {
287 1.1 rjs
288 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from;
289 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_BLOCK;
290 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxmb = (u_int16_t)(so->so_snd.sb_mbmax/1024);
291 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onmb = asoc->total_output_mbuf_queue_size;
292 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxsb = (u_int16_t)(so->so_snd.sb_hiwat/1024);
293 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onsb = asoc->total_output_queue_size;
294 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);
295 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.stream_qcnt = (u_int16_t)asoc->stream_queue_cnt;
296 1.1 rjs sctp_cwnd_log_at++;
297 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) {
298 1.1 rjs sctp_cwnd_log_at = 0;
299 1.1 rjs sctp_cwnd_log_rolled = 1;
300 1.1 rjs }
301 1.1 rjs }
302 1.1 rjs
303 1.1 rjs int
304 1.1 rjs sctp_fill_stat_log(struct mbuf *m)
305 1.1 rjs {
306 1.1 rjs struct sctp_cwnd_log_req *req;
307 1.1 rjs int size_limit, num, i, at, cnt_out=0;
308 1.1 rjs
309 1.1 rjs if (m == NULL)
310 1.1 rjs return (EINVAL);
311 1.1 rjs
312 1.1 rjs size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req));
313 1.1 rjs if (size_limit < sizeof(struct sctp_cwnd_log)) {
314 1.1 rjs return (EINVAL);
315 1.1 rjs }
316 1.1 rjs req = mtod(m, struct sctp_cwnd_log_req *);
317 1.1 rjs num = size_limit/sizeof(struct sctp_cwnd_log);
318 1.1 rjs if (sctp_cwnd_log_rolled) {
319 1.1 rjs req->num_in_log = SCTP_STAT_LOG_SIZE;
320 1.1 rjs } else {
321 1.1 rjs req->num_in_log = sctp_cwnd_log_at;
322 1.1 rjs /* if the log has not rolled, we don't
323 1.1 rjs * let you have old data.
324 1.1 rjs */
325 1.1 rjs if (req->end_at > sctp_cwnd_log_at) {
326 1.1 rjs req->end_at = sctp_cwnd_log_at;
327 1.1 rjs }
328 1.1 rjs }
329 1.1 rjs if ((num < SCTP_STAT_LOG_SIZE) &&
330 1.1 rjs ((sctp_cwnd_log_rolled) || (sctp_cwnd_log_at > num))) {
331 1.1 rjs /* we can't return all of it */
332 1.1 rjs if (((req->start_at == 0) && (req->end_at == 0)) ||
333 1.1 rjs (req->start_at >= SCTP_STAT_LOG_SIZE) ||
334 1.1 rjs (req->end_at >= SCTP_STAT_LOG_SIZE)) {
335 1.1 rjs /* No user request or user is wacked. */
336 1.1 rjs req->num_ret = num;
337 1.1 rjs req->end_at = sctp_cwnd_log_at - 1;
338 1.1 rjs if ((sctp_cwnd_log_at - num) < 0) {
339 1.1 rjs int cc;
340 1.1 rjs cc = num - sctp_cwnd_log_at;
341 1.1 rjs req->start_at = SCTP_STAT_LOG_SIZE - cc;
342 1.1 rjs } else {
343 1.1 rjs req->start_at = sctp_cwnd_log_at - num;
344 1.1 rjs }
345 1.1 rjs } else {
346 1.1 rjs /* a user request */
347 1.1 rjs int cc;
348 1.1 rjs if (req->start_at > req->end_at) {
349 1.1 rjs cc = (SCTP_STAT_LOG_SIZE - req->start_at) +
350 1.1 rjs (req->end_at + 1);
351 1.1 rjs } else {
352 1.1 rjs
353 1.1 rjs cc = req->end_at - req->start_at;
354 1.1 rjs }
355 1.1 rjs if (cc < num) {
356 1.1 rjs num = cc;
357 1.1 rjs }
358 1.1 rjs req->num_ret = num;
359 1.1 rjs }
360 1.1 rjs } else {
361 1.1 rjs /* We can return all of it */
362 1.1 rjs req->start_at = 0;
363 1.1 rjs req->end_at = sctp_cwnd_log_at - 1;
364 1.1 rjs req->num_ret = sctp_cwnd_log_at;
365 1.1 rjs }
366 1.1 rjs for (i = 0, at = req->start_at; i < req->num_ret; i++) {
367 1.1 rjs req->log[i] = sctp_clog[at];
368 1.1 rjs cnt_out++;
369 1.1 rjs at++;
370 1.1 rjs if (at >= SCTP_STAT_LOG_SIZE)
371 1.1 rjs at = 0;
372 1.1 rjs }
373 1.1 rjs m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log_req)) + sizeof(struct sctp_cwnd_log_req);
374 1.1 rjs return (0);
375 1.1 rjs }
376 1.1 rjs
377 1.1 rjs #endif
378 1.1 rjs
379 1.1 rjs #ifdef SCTP_AUDITING_ENABLED
380 1.1 rjs u_int8_t sctp_audit_data[SCTP_AUDIT_SIZE][2];
381 1.1 rjs static int sctp_audit_indx = 0;
382 1.1 rjs
383 1.1 rjs static
384 1.1 rjs void sctp_print_audit_report(void)
385 1.1 rjs {
386 1.1 rjs int i;
387 1.1 rjs int cnt;
388 1.1 rjs cnt = 0;
389 1.1 rjs for (i=sctp_audit_indx;i<SCTP_AUDIT_SIZE;i++) {
390 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) &&
391 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
392 1.1 rjs cnt = 0;
393 1.1 rjs printf("\n");
394 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) {
395 1.1 rjs cnt = 0;
396 1.1 rjs printf("\n");
397 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) &&
398 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
399 1.1 rjs printf("\n");
400 1.1 rjs cnt = 0;
401 1.1 rjs }
402 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
403 1.1 rjs (uint32_t)sctp_audit_data[i][1]);
404 1.1 rjs cnt++;
405 1.1 rjs if ((cnt % 14) == 0)
406 1.1 rjs printf("\n");
407 1.1 rjs }
408 1.1 rjs for (i=0;i<sctp_audit_indx;i++) {
409 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) &&
410 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
411 1.1 rjs cnt = 0;
412 1.1 rjs printf("\n");
413 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) {
414 1.1 rjs cnt = 0;
415 1.1 rjs printf("\n");
416 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) &&
417 1.1 rjs (sctp_audit_data[i][1] == 0x01)) {
418 1.1 rjs printf("\n");
419 1.1 rjs cnt = 0;
420 1.1 rjs }
421 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0],
422 1.1 rjs (uint32_t)sctp_audit_data[i][1]);
423 1.1 rjs cnt++;
424 1.1 rjs if ((cnt % 14) == 0)
425 1.1 rjs printf("\n");
426 1.1 rjs }
427 1.1 rjs printf("\n");
428 1.1 rjs }
429 1.1 rjs
430 1.1 rjs void sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
431 1.1 rjs struct sctp_nets *net)
432 1.1 rjs {
433 1.1 rjs int resend_cnt, tot_out, rep, tot_book_cnt;
434 1.1 rjs struct sctp_nets *lnet;
435 1.1 rjs struct sctp_tmit_chunk *chk;
436 1.1 rjs
437 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAA;
438 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from;
439 1.1 rjs sctp_audit_indx++;
440 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
441 1.1 rjs sctp_audit_indx = 0;
442 1.1 rjs }
443 1.1 rjs if (inp == NULL) {
444 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
445 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x01;
446 1.1 rjs sctp_audit_indx++;
447 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
448 1.1 rjs sctp_audit_indx = 0;
449 1.1 rjs }
450 1.1 rjs return;
451 1.1 rjs }
452 1.1 rjs if (stcb == NULL) {
453 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
454 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x02;
455 1.1 rjs sctp_audit_indx++;
456 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
457 1.1 rjs sctp_audit_indx = 0;
458 1.1 rjs }
459 1.1 rjs return;
460 1.1 rjs }
461 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA1;
462 1.1 rjs sctp_audit_data[sctp_audit_indx][1] =
463 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
464 1.1 rjs sctp_audit_indx++;
465 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
466 1.1 rjs sctp_audit_indx = 0;
467 1.1 rjs }
468 1.1 rjs rep = 0;
469 1.1 rjs tot_book_cnt = 0;
470 1.1 rjs resend_cnt = tot_out = 0;
471 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
472 1.1 rjs if (chk->sent == SCTP_DATAGRAM_RESEND) {
473 1.1 rjs resend_cnt++;
474 1.1 rjs } else if (chk->sent < SCTP_DATAGRAM_RESEND) {
475 1.1 rjs tot_out += chk->book_size;
476 1.1 rjs tot_book_cnt++;
477 1.1 rjs }
478 1.1 rjs }
479 1.1 rjs if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) {
480 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
481 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA1;
482 1.1 rjs sctp_audit_indx++;
483 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
484 1.1 rjs sctp_audit_indx = 0;
485 1.1 rjs }
486 1.1 rjs printf("resend_cnt:%d asoc-tot:%d\n",
487 1.1 rjs resend_cnt, stcb->asoc.sent_queue_retran_cnt);
488 1.1 rjs rep = 1;
489 1.1 rjs stcb->asoc.sent_queue_retran_cnt = resend_cnt;
490 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA2;
491 1.1 rjs sctp_audit_data[sctp_audit_indx][1] =
492 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt);
493 1.1 rjs sctp_audit_indx++;
494 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
495 1.1 rjs sctp_audit_indx = 0;
496 1.1 rjs }
497 1.1 rjs }
498 1.1 rjs if (tot_out != stcb->asoc.total_flight) {
499 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
500 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA2;
501 1.1 rjs sctp_audit_indx++;
502 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
503 1.1 rjs sctp_audit_indx = 0;
504 1.1 rjs }
505 1.1 rjs rep = 1;
506 1.1 rjs printf("tot_flt:%d asoc_tot:%d\n", tot_out,
507 1.1 rjs (int)stcb->asoc.total_flight);
508 1.1 rjs stcb->asoc.total_flight = tot_out;
509 1.1 rjs }
510 1.1 rjs if (tot_book_cnt != stcb->asoc.total_flight_count) {
511 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
512 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA5;
513 1.1 rjs sctp_audit_indx++;
514 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
515 1.1 rjs sctp_audit_indx = 0;
516 1.1 rjs }
517 1.1 rjs rep = 1;
518 1.1 rjs printf("tot_flt_book:%d\n", tot_book);
519 1.1 rjs
520 1.1 rjs stcb->asoc.total_flight_count = tot_book_cnt;
521 1.1 rjs }
522 1.1 rjs tot_out = 0;
523 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
524 1.1 rjs tot_out += lnet->flight_size;
525 1.1 rjs }
526 1.1 rjs if (tot_out != stcb->asoc.total_flight) {
527 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF;
528 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA3;
529 1.1 rjs sctp_audit_indx++;
530 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
531 1.1 rjs sctp_audit_indx = 0;
532 1.1 rjs }
533 1.1 rjs rep = 1;
534 1.1 rjs printf("real flight:%d net total was %d\n",
535 1.1 rjs stcb->asoc.total_flight, tot_out);
536 1.1 rjs /* now corrective action */
537 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
538 1.1 rjs tot_out = 0;
539 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
540 1.1 rjs if ((chk->whoTo == lnet) &&
541 1.1 rjs (chk->sent < SCTP_DATAGRAM_RESEND)) {
542 1.1 rjs tot_out += chk->book_size;
543 1.1 rjs }
544 1.1 rjs }
545 1.1 rjs if (lnet->flight_size != tot_out) {
546 1.1 rjs printf("net:%x flight was %d corrected to %d\n",
547 1.1 rjs (uint32_t)lnet, lnet->flight_size, tot_out);
548 1.1 rjs lnet->flight_size = tot_out;
549 1.1 rjs }
550 1.1 rjs
551 1.1 rjs }
552 1.1 rjs }
553 1.1 rjs
554 1.1 rjs if (rep) {
555 1.1 rjs sctp_print_audit_report();
556 1.1 rjs }
557 1.1 rjs }
558 1.1 rjs
559 1.1 rjs void
560 1.1 rjs sctp_audit_log(u_int8_t ev, u_int8_t fd)
561 1.1 rjs {
562 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = ev;
563 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = fd;
564 1.1 rjs sctp_audit_indx++;
565 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) {
566 1.1 rjs sctp_audit_indx = 0;
567 1.1 rjs }
568 1.1 rjs }
569 1.1 rjs
570 1.1 rjs #endif
571 1.1 rjs
572 1.1 rjs /*
573 1.1 rjs * a list of sizes based on typical mtu's, used only if next hop
574 1.1 rjs * size not returned.
575 1.1 rjs */
576 1.1 rjs static int sctp_mtu_sizes[] = {
577 1.1 rjs 68,
578 1.1 rjs 296,
579 1.1 rjs 508,
580 1.1 rjs 512,
581 1.1 rjs 544,
582 1.1 rjs 576,
583 1.1 rjs 1006,
584 1.1 rjs 1492,
585 1.1 rjs 1500,
586 1.1 rjs 1536,
587 1.1 rjs 2002,
588 1.1 rjs 2048,
589 1.1 rjs 4352,
590 1.1 rjs 4464,
591 1.1 rjs 8166,
592 1.1 rjs 17914,
593 1.1 rjs 32000,
594 1.1 rjs 65535
595 1.1 rjs };
596 1.1 rjs
597 1.1 rjs int
598 1.1 rjs find_next_best_mtu(int totsz)
599 1.1 rjs {
600 1.1 rjs int i, perfer;
601 1.1 rjs /*
602 1.1 rjs * if we are in here we must find the next best fit based on the
603 1.1 rjs * size of the dg that failed to be sent.
604 1.1 rjs */
605 1.1 rjs perfer = 0;
606 1.1 rjs for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) {
607 1.1 rjs if (totsz < sctp_mtu_sizes[i]) {
608 1.1 rjs perfer = i - 1;
609 1.1 rjs if (perfer < 0)
610 1.1 rjs perfer = 0;
611 1.1 rjs break;
612 1.1 rjs }
613 1.1 rjs }
614 1.1 rjs return (sctp_mtu_sizes[perfer]);
615 1.1 rjs }
616 1.1 rjs
617 1.1 rjs void
618 1.1 rjs sctp_fill_random_store(struct sctp_pcb *m)
619 1.1 rjs {
620 1.1 rjs /*
621 1.1 rjs * Here we use the MD5/SHA-1 to hash with our good randomNumbers
622 1.1 rjs * and our counter. The result becomes our good random numbers and
623 1.1 rjs * we then setup to give these out. Note that we do no lockig
624 1.1 rjs * to protect this. This is ok, since if competing folks call
625 1.1 rjs * this we will get more gobbled gook in the random store whic
626 1.1 rjs * is what we want. There is a danger that two guys will use
627 1.1 rjs * the same random numbers, but thats ok too since that
628 1.1 rjs * is random as well :->
629 1.1 rjs */
630 1.1 rjs m->store_at = 0;
631 1.1 rjs sctp_hash_digest((char *)m->random_numbers, sizeof(m->random_numbers),
632 1.1 rjs (char *)&m->random_counter, sizeof(m->random_counter),
633 1.1 rjs (char *)m->random_store);
634 1.1 rjs m->random_counter++;
635 1.1 rjs }
636 1.1 rjs
637 1.1 rjs uint32_t
638 1.1 rjs sctp_select_initial_TSN(struct sctp_pcb *m)
639 1.1 rjs {
640 1.1 rjs /*
641 1.1 rjs * A true implementation should use random selection process to
642 1.1 rjs * get the initial stream sequence number, using RFC1750 as a
643 1.1 rjs * good guideline
644 1.1 rjs */
645 1.1 rjs u_long x, *xp;
646 1.1 rjs uint8_t *p;
647 1.1 rjs
648 1.1 rjs if (m->initial_sequence_debug != 0) {
649 1.1 rjs u_int32_t ret;
650 1.1 rjs ret = m->initial_sequence_debug;
651 1.1 rjs m->initial_sequence_debug++;
652 1.1 rjs return (ret);
653 1.1 rjs }
654 1.1 rjs if ((m->store_at+sizeof(u_long)) > SCTP_SIGNATURE_SIZE) {
655 1.1 rjs /* Refill the random store */
656 1.1 rjs sctp_fill_random_store(m);
657 1.1 rjs }
658 1.1 rjs p = &m->random_store[(int)m->store_at];
659 1.1 rjs xp = (u_long *)p;
660 1.1 rjs x = *xp;
661 1.1 rjs m->store_at += sizeof(u_long);
662 1.1 rjs return (x);
663 1.1 rjs }
664 1.1 rjs
665 1.1 rjs u_int32_t sctp_select_a_tag(struct sctp_inpcb *m)
666 1.1 rjs {
667 1.1 rjs u_long x, not_done;
668 1.1 rjs struct timeval now;
669 1.1 rjs
670 1.1 rjs SCTP_GETTIME_TIMEVAL(&now);
671 1.1 rjs not_done = 1;
672 1.1 rjs while (not_done) {
673 1.1 rjs x = sctp_select_initial_TSN(&m->sctp_ep);
674 1.1 rjs if (x == 0) {
675 1.1 rjs /* we never use 0 */
676 1.1 rjs continue;
677 1.1 rjs }
678 1.1 rjs if (sctp_is_vtag_good(m, x, &now)) {
679 1.1 rjs not_done = 0;
680 1.1 rjs }
681 1.1 rjs }
682 1.1 rjs return (x);
683 1.1 rjs }
684 1.1 rjs
685 1.1 rjs
686 1.1 rjs int
687 1.1 rjs sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
688 1.1 rjs int for_a_init, uint32_t override_tag )
689 1.1 rjs {
690 1.1 rjs /*
691 1.1 rjs * Anything set to zero is taken care of by the allocation
692 1.1 rjs * routine's bzero
693 1.1 rjs */
694 1.1 rjs
695 1.1 rjs /*
696 1.1 rjs * Up front select what scoping to apply on addresses I tell my peer
697 1.1 rjs * Not sure what to do with these right now, we will need to come up
698 1.1 rjs * with a way to set them. We may need to pass them through from the
699 1.1 rjs * caller in the sctp_aloc_assoc() function.
700 1.1 rjs */
701 1.1 rjs int i;
702 1.1 rjs /* init all variables to a known value.*/
703 1.1 rjs asoc->state = SCTP_STATE_INUSE;
704 1.1 rjs asoc->max_burst = m->sctp_ep.max_burst;
705 1.1 rjs asoc->heart_beat_delay = m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
706 1.1 rjs asoc->cookie_life = m->sctp_ep.def_cookie_life;
707 1.1 rjs
708 1.1 rjs if (override_tag) {
709 1.1 rjs asoc->my_vtag = override_tag;
710 1.1 rjs } else {
711 1.1 rjs asoc->my_vtag = sctp_select_a_tag(m);
712 1.1 rjs }
713 1.1 rjs asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq =
714 1.1 rjs sctp_select_initial_TSN(&m->sctp_ep);
715 1.1 rjs asoc->t3timeout_highest_marked = asoc->asconf_seq_out;
716 1.1 rjs /* we are opptimisitic here */
717 1.1 rjs asoc->peer_supports_asconf = 1;
718 1.1 rjs asoc->peer_supports_asconf_setprim = 1;
719 1.1 rjs asoc->peer_supports_pktdrop = 1;
720 1.1 rjs
721 1.1 rjs asoc->sent_queue_retran_cnt = 0;
722 1.1 rjs /* This will need to be adjusted */
723 1.1 rjs asoc->last_cwr_tsn = asoc->init_seq_number - 1;
724 1.1 rjs asoc->last_acked_seq = asoc->init_seq_number - 1;
725 1.1 rjs asoc->advanced_peer_ack_point = asoc->last_acked_seq;
726 1.1 rjs asoc->asconf_seq_in = asoc->last_acked_seq;
727 1.1 rjs
728 1.1 rjs /* here we are different, we hold the next one we expect */
729 1.1 rjs asoc->str_reset_seq_in = asoc->last_acked_seq + 1;
730 1.1 rjs
731 1.1 rjs asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max;
732 1.1 rjs asoc->initial_rto = m->sctp_ep.initial_rto;
733 1.1 rjs
734 1.1 rjs asoc->max_init_times = m->sctp_ep.max_init_times;
735 1.1 rjs asoc->max_send_times = m->sctp_ep.max_send_times;
736 1.1 rjs asoc->def_net_failure = m->sctp_ep.def_net_failure;
737 1.1 rjs
738 1.1 rjs /* ECN Nonce initialization */
739 1.1 rjs asoc->ecn_nonce_allowed = 0;
740 1.1 rjs asoc->receiver_nonce_sum = 1;
741 1.1 rjs asoc->nonce_sum_expect_base = 1;
742 1.1 rjs asoc->nonce_sum_check = 1;
743 1.1 rjs asoc->nonce_resync_tsn = 0;
744 1.1 rjs asoc->nonce_wait_for_ecne = 0;
745 1.1 rjs asoc->nonce_wait_tsn = 0;
746 1.1 rjs
747 1.1 rjs if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
748 1.1 rjs struct in6pcb *inp6;
749 1.1 rjs
750 1.1 rjs
751 1.1 rjs /* Its a V6 socket */
752 1.1 rjs inp6 = (struct in6pcb *)m;
753 1.1 rjs asoc->ipv6_addr_legal = 1;
754 1.1 rjs /* Now look at the binding flag to see if V4 will be legal */
755 1.1 rjs if (
756 1.1 rjs #if defined(__OpenBSD__)
757 1.1 rjs (0) /* we always do dual bind */
758 1.1 rjs #elif defined (__NetBSD__)
759 1.1 rjs (inp6->in6p_flags & IN6P_IPV6_V6ONLY)
760 1.1 rjs #else
761 1.1 rjs (inp6->inp_flags & IN6P_IPV6_V6ONLY)
762 1.1 rjs #endif
763 1.1 rjs == 0) {
764 1.1 rjs asoc->ipv4_addr_legal = 1;
765 1.1 rjs } else {
766 1.1 rjs /* V4 addresses are NOT legal on the association */
767 1.1 rjs asoc->ipv4_addr_legal = 0;
768 1.1 rjs }
769 1.1 rjs } else {
770 1.1 rjs /* Its a V4 socket, no - V6 */
771 1.1 rjs asoc->ipv4_addr_legal = 1;
772 1.1 rjs asoc->ipv6_addr_legal = 0;
773 1.1 rjs }
774 1.1 rjs
775 1.1 rjs
776 1.1 rjs asoc->my_rwnd = max(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND);
777 1.1 rjs asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat;
778 1.1 rjs
779 1.1 rjs asoc->smallest_mtu = m->sctp_frag_point;
780 1.1 rjs asoc->minrto = m->sctp_ep.sctp_minrto;
781 1.1 rjs asoc->maxrto = m->sctp_ep.sctp_maxrto;
782 1.1 rjs
783 1.1 rjs LIST_INIT(&asoc->sctp_local_addr_list);
784 1.1 rjs TAILQ_INIT(&asoc->nets);
785 1.1 rjs TAILQ_INIT(&asoc->pending_reply_queue);
786 1.1 rjs asoc->last_asconf_ack_sent = NULL;
787 1.1 rjs /* Setup to fill the hb random cache at first HB */
788 1.1 rjs asoc->hb_random_idx = 4;
789 1.1 rjs
790 1.1 rjs asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time;
791 1.1 rjs
792 1.1 rjs /*
793 1.1 rjs * Now the stream parameters, here we allocate space for all
794 1.1 rjs * streams that we request by default.
795 1.1 rjs */
796 1.1 rjs asoc->streamoutcnt = asoc->pre_open_streams =
797 1.1 rjs m->sctp_ep.pre_open_stream_count;
798 1.1 rjs asoc->strmout = malloc(asoc->streamoutcnt *
799 1.1 rjs sizeof(struct sctp_stream_out), M_PCB, M_NOWAIT);
800 1.1 rjs if (asoc->strmout == NULL) {
801 1.1 rjs /* big trouble no memory */
802 1.1 rjs return (ENOMEM);
803 1.1 rjs }
804 1.1 rjs for (i = 0; i < asoc->streamoutcnt; i++) {
805 1.1 rjs /*
806 1.1 rjs * inbound side must be set to 0xffff,
807 1.1 rjs * also NOTE when we get the INIT-ACK back (for INIT sender)
808 1.1 rjs * we MUST reduce the count (streamoutcnt) but first check
809 1.1 rjs * if we sent to any of the upper streams that were dropped
810 1.1 rjs * (if some were). Those that were dropped must be notified
811 1.1 rjs * to the upper layer as failed to send.
812 1.1 rjs */
813 1.1 rjs asoc->strmout[i].next_sequence_sent = 0x0;
814 1.1 rjs TAILQ_INIT(&asoc->strmout[i].outqueue);
815 1.1 rjs asoc->strmout[i].stream_no = i;
816 1.1 rjs asoc->strmout[i].next_spoke.tqe_next = 0;
817 1.1 rjs asoc->strmout[i].next_spoke.tqe_prev = 0;
818 1.1 rjs }
819 1.1 rjs /* Now the mapping array */
820 1.1 rjs asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
821 1.1 rjs asoc->mapping_array = malloc(asoc->mapping_array_size,
822 1.1 rjs M_PCB, M_NOWAIT);
823 1.1 rjs if (asoc->mapping_array == NULL) {
824 1.1 rjs free(asoc->strmout, M_PCB);
825 1.1 rjs return (ENOMEM);
826 1.1 rjs }
827 1.1 rjs memset(asoc->mapping_array, 0, asoc->mapping_array_size);
828 1.1 rjs /* Now the init of the other outqueues */
829 1.1 rjs TAILQ_INIT(&asoc->out_wheel);
830 1.1 rjs TAILQ_INIT(&asoc->control_send_queue);
831 1.1 rjs TAILQ_INIT(&asoc->send_queue);
832 1.1 rjs TAILQ_INIT(&asoc->sent_queue);
833 1.1 rjs TAILQ_INIT(&asoc->reasmqueue);
834 1.1 rjs TAILQ_INIT(&asoc->delivery_queue);
835 1.1 rjs asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome;
836 1.1 rjs
837 1.1 rjs TAILQ_INIT(&asoc->asconf_queue);
838 1.1 rjs return (0);
839 1.1 rjs }
840 1.1 rjs
841 1.1 rjs int
842 1.1 rjs sctp_expand_mapping_array(struct sctp_association *asoc)
843 1.1 rjs {
844 1.1 rjs /* mapping array needs to grow */
845 1.1 rjs u_int8_t *new_array;
846 1.3 christos uint16_t new_size, old_size;
847 1.1 rjs
848 1.3 christos old_size = asoc->mapping_array_size;
849 1.3 christos new_size = old_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.3 christos memcpy(new_array, asoc->mapping_array, old_size);
858 1.3 christos memset(new_array + old_size, 0, SCTP_MAPPING_ARRAY_INCR);
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.9 ozaki m_reset_rcvif(m_notify);
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.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2091 1.1 rjs to = (struct sockaddr *)&sin6;
2092 1.1 rjs }
2093 1.1 rjs /* check and strip embedded scope junk */
2094 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2095 1.1 rjs &lsa6);
2096 1.1 rjs /*
2097 1.1 rjs * We need to always notify comm changes.
2098 1.1 rjs * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2099 1.1 rjs * sctp_m_freem(m_notify);
2100 1.1 rjs * return;
2101 1.1 rjs * }
2102 1.1 rjs */
2103 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2104 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2105 1.1 rjs SCTP_TCB_LOCK(stcb);
2106 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv,
2107 1.1 rjs to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2108 1.1 rjs /* not enough room */
2109 1.1 rjs sctp_m_freem(m_notify);
2110 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2111 1.1 rjs return;
2112 1.1 rjs }
2113 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2114 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2115 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2116 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2117 1.1 rjs }
2118 1.1 rjs } else {
2119 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2120 1.1 rjs }
2121 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2122 1.1 rjs /* Wake up any sleeper */
2123 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2124 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
2125 1.1 rjs }
2126 1.1 rjs
2127 1.1 rjs static void
2128 1.1 rjs sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
2129 1.1 rjs const struct sockaddr *sa, uint32_t error)
2130 1.1 rjs {
2131 1.1 rjs struct mbuf *m_notify;
2132 1.1 rjs struct sctp_paddr_change *spc;
2133 1.1 rjs const struct sockaddr *to;
2134 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2135 1.1 rjs
2136 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT))
2137 1.1 rjs /* event not enabled */
2138 1.1 rjs return;
2139 1.1 rjs
2140 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2141 1.1 rjs if (m_notify == NULL)
2142 1.1 rjs return;
2143 1.1 rjs m_notify->m_len = 0;
2144 1.1 rjs
2145 1.1 rjs MCLGET(m_notify, M_DONTWAIT);
2146 1.1 rjs if ((m_notify->m_flags & M_EXT) != M_EXT) {
2147 1.1 rjs sctp_m_freem(m_notify);
2148 1.1 rjs return;
2149 1.1 rjs }
2150 1.1 rjs
2151 1.1 rjs spc = mtod(m_notify, struct sctp_paddr_change *);
2152 1.1 rjs spc->spc_type = SCTP_PEER_ADDR_CHANGE;
2153 1.1 rjs spc->spc_flags = 0;
2154 1.1 rjs spc->spc_length = sizeof(struct sctp_paddr_change);
2155 1.1 rjs if (sa->sa_family == AF_INET) {
2156 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
2157 1.1 rjs } else {
2158 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
2159 1.1 rjs }
2160 1.1 rjs spc->spc_state = state;
2161 1.1 rjs spc->spc_error = error;
2162 1.1 rjs spc->spc_assoc_id = sctp_get_associd(stcb);
2163 1.1 rjs
2164 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2165 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
2166 1.9 ozaki m_reset_rcvif(m_notify);
2167 1.1 rjs m_notify->m_len = sizeof(struct sctp_paddr_change);
2168 1.1 rjs m_notify->m_next = NULL;
2169 1.1 rjs
2170 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2171 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2172 1.1 rjs to->sa_family == AF_INET) {
2173 1.1 rjs const struct sockaddr_in *sin;
2174 1.1 rjs
2175 1.1 rjs sin = (const struct sockaddr_in *)to;
2176 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2177 1.1 rjs to = (struct sockaddr *)&sin6;
2178 1.1 rjs }
2179 1.1 rjs /* check and strip embedded scope junk */
2180 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2181 1.1 rjs &lsa6);
2182 1.1 rjs
2183 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2184 1.1 rjs sctp_m_freem(m_notify);
2185 1.1 rjs return;
2186 1.1 rjs }
2187 1.1 rjs /* append to socket */
2188 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2189 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2190 1.1 rjs SCTP_TCB_LOCK(stcb);
2191 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2192 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2193 1.1 rjs /* not enough room */
2194 1.1 rjs sctp_m_freem(m_notify);
2195 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2196 1.1 rjs return;
2197 1.1 rjs }
2198 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2199 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2200 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2201 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2202 1.1 rjs }
2203 1.1 rjs } else {
2204 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2205 1.1 rjs }
2206 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2207 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2208 1.1 rjs }
2209 1.1 rjs
2210 1.1 rjs
2211 1.1 rjs static void
2212 1.1 rjs sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error,
2213 1.1 rjs struct sctp_tmit_chunk *chk)
2214 1.1 rjs {
2215 1.1 rjs struct mbuf *m_notify;
2216 1.1 rjs struct sctp_send_failed *ssf;
2217 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2218 1.1 rjs const struct sockaddr *to;
2219 1.1 rjs int length;
2220 1.1 rjs
2221 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
2222 1.1 rjs /* event not enabled */
2223 1.1 rjs return;
2224 1.1 rjs
2225 1.1 rjs length = sizeof(struct sctp_send_failed) + chk->send_size;
2226 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2227 1.1 rjs if (m_notify == NULL)
2228 1.1 rjs /* no space left */
2229 1.1 rjs return;
2230 1.1 rjs m_notify->m_len = 0;
2231 1.1 rjs ssf = mtod(m_notify, struct sctp_send_failed *);
2232 1.1 rjs ssf->ssf_type = SCTP_SEND_FAILED;
2233 1.1 rjs if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
2234 1.1 rjs ssf->ssf_flags = SCTP_DATA_UNSENT;
2235 1.1 rjs else
2236 1.1 rjs ssf->ssf_flags = SCTP_DATA_SENT;
2237 1.1 rjs ssf->ssf_length = length;
2238 1.1 rjs ssf->ssf_error = error;
2239 1.1 rjs /* not exactly what the user sent in, but should be close :) */
2240 1.1 rjs ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
2241 1.1 rjs ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
2242 1.1 rjs ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
2243 1.1 rjs ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
2244 1.1 rjs ssf->ssf_info.sinfo_context = chk->rec.data.context;
2245 1.1 rjs ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
2246 1.1 rjs ssf->ssf_assoc_id = sctp_get_associd(stcb);
2247 1.1 rjs m_notify->m_next = chk->data;
2248 1.1 rjs if (m_notify->m_next == NULL)
2249 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2250 1.1 rjs else {
2251 1.1 rjs struct mbuf *m;
2252 1.1 rjs m_notify->m_flags |= M_NOTIFICATION;
2253 1.1 rjs m = m_notify;
2254 1.1 rjs while (m->m_next != NULL)
2255 1.1 rjs m = m->m_next;
2256 1.1 rjs m->m_flags |= M_EOR;
2257 1.1 rjs }
2258 1.1 rjs m_notify->m_pkthdr.len = length;
2259 1.9 ozaki m_reset_rcvif(m_notify);
2260 1.1 rjs m_notify->m_len = sizeof(struct sctp_send_failed);
2261 1.1 rjs
2262 1.1 rjs /* Steal off the mbuf */
2263 1.1 rjs chk->data = NULL;
2264 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2265 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2266 1.1 rjs to->sa_family == AF_INET) {
2267 1.1 rjs const struct sockaddr_in *sin;
2268 1.1 rjs
2269 1.1 rjs sin = satocsin(to);
2270 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2271 1.1 rjs to = (struct sockaddr *)&sin6;
2272 1.1 rjs }
2273 1.1 rjs /* check and strip embedded scope junk */
2274 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2275 1.1 rjs &lsa6);
2276 1.1 rjs
2277 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2278 1.1 rjs sctp_m_freem(m_notify);
2279 1.1 rjs return;
2280 1.1 rjs }
2281 1.1 rjs
2282 1.1 rjs /* append to socket */
2283 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2284 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2285 1.1 rjs SCTP_TCB_LOCK(stcb);
2286 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2287 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2288 1.1 rjs /* not enough room */
2289 1.1 rjs sctp_m_freem(m_notify);
2290 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2291 1.1 rjs return;
2292 1.1 rjs }
2293 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2294 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2295 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2296 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2297 1.1 rjs }
2298 1.1 rjs } else {
2299 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2300 1.1 rjs }
2301 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2302 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2303 1.1 rjs }
2304 1.1 rjs
2305 1.1 rjs static void
2306 1.1 rjs sctp_notify_adaption_layer(struct sctp_tcb *stcb,
2307 1.1 rjs u_int32_t error)
2308 1.1 rjs {
2309 1.1 rjs struct mbuf *m_notify;
2310 1.1 rjs struct sctp_adaption_event *sai;
2311 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2312 1.1 rjs const struct sockaddr *to;
2313 1.1 rjs
2314 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT))
2315 1.1 rjs /* event not enabled */
2316 1.1 rjs return;
2317 1.1 rjs
2318 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2319 1.1 rjs if (m_notify == NULL)
2320 1.1 rjs /* no space left */
2321 1.1 rjs return;
2322 1.1 rjs m_notify->m_len = 0;
2323 1.1 rjs sai = mtod(m_notify, struct sctp_adaption_event *);
2324 1.1 rjs sai->sai_type = SCTP_ADAPTION_INDICATION;
2325 1.1 rjs sai->sai_flags = 0;
2326 1.1 rjs sai->sai_length = sizeof(struct sctp_adaption_event);
2327 1.1 rjs sai->sai_adaption_ind = error;
2328 1.1 rjs sai->sai_assoc_id = sctp_get_associd(stcb);
2329 1.1 rjs
2330 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2331 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event);
2332 1.9 ozaki m_reset_rcvif(m_notify);
2333 1.1 rjs m_notify->m_len = sizeof(struct sctp_adaption_event);
2334 1.1 rjs m_notify->m_next = NULL;
2335 1.1 rjs
2336 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2337 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2338 1.1 rjs (to->sa_family == AF_INET)) {
2339 1.1 rjs const struct sockaddr_in *sin;
2340 1.1 rjs
2341 1.1 rjs sin = satocsin(to);
2342 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2343 1.1 rjs to = (struct sockaddr *)&sin6;
2344 1.1 rjs }
2345 1.1 rjs /* check and strip embedded scope junk */
2346 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2347 1.1 rjs &lsa6);
2348 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2349 1.1 rjs sctp_m_freem(m_notify);
2350 1.1 rjs return;
2351 1.1 rjs }
2352 1.1 rjs /* append to socket */
2353 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2354 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2355 1.1 rjs SCTP_TCB_LOCK(stcb);
2356 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2357 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2358 1.1 rjs /* not enough room */
2359 1.1 rjs sctp_m_freem(m_notify);
2360 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2361 1.1 rjs return;
2362 1.1 rjs }
2363 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2364 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2365 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2366 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2367 1.1 rjs }
2368 1.1 rjs } else {
2369 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2370 1.1 rjs }
2371 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2372 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2373 1.1 rjs }
2374 1.1 rjs
2375 1.1 rjs static void
2376 1.1 rjs sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
2377 1.1 rjs u_int32_t error)
2378 1.1 rjs {
2379 1.1 rjs struct mbuf *m_notify;
2380 1.1 rjs struct sctp_pdapi_event *pdapi;
2381 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2382 1.1 rjs const struct sockaddr *to;
2383 1.1 rjs
2384 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT))
2385 1.1 rjs /* event not enabled */
2386 1.1 rjs return;
2387 1.1 rjs
2388 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2389 1.1 rjs if (m_notify == NULL)
2390 1.1 rjs /* no space left */
2391 1.1 rjs return;
2392 1.1 rjs m_notify->m_len = 0;
2393 1.1 rjs pdapi = mtod(m_notify, struct sctp_pdapi_event *);
2394 1.1 rjs pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
2395 1.1 rjs pdapi->pdapi_flags = 0;
2396 1.1 rjs pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
2397 1.1 rjs pdapi->pdapi_indication = error;
2398 1.1 rjs pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
2399 1.1 rjs
2400 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2401 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
2402 1.9 ozaki m_reset_rcvif(m_notify);
2403 1.1 rjs m_notify->m_len = sizeof(struct sctp_pdapi_event);
2404 1.1 rjs m_notify->m_next = NULL;
2405 1.1 rjs
2406 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2407 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2408 1.1 rjs (to->sa_family == AF_INET)) {
2409 1.1 rjs const struct sockaddr_in *sin;
2410 1.1 rjs
2411 1.1 rjs sin = satocsin(to);
2412 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2413 1.1 rjs to = (struct sockaddr *)&sin6;
2414 1.1 rjs }
2415 1.1 rjs /* check and strip embedded scope junk */
2416 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2417 1.1 rjs &lsa6);
2418 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2419 1.1 rjs sctp_m_freem(m_notify);
2420 1.1 rjs return;
2421 1.1 rjs }
2422 1.1 rjs /* append to socket */
2423 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2424 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2425 1.1 rjs SCTP_TCB_LOCK(stcb);
2426 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2427 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2428 1.1 rjs /* not enough room */
2429 1.1 rjs sctp_m_freem(m_notify);
2430 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2431 1.1 rjs return;
2432 1.1 rjs }
2433 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2434 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2435 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2436 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2437 1.1 rjs }
2438 1.1 rjs } else {
2439 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2440 1.1 rjs }
2441 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2442 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2443 1.1 rjs }
2444 1.1 rjs
2445 1.1 rjs static void
2446 1.1 rjs sctp_notify_shutdown_event(struct sctp_tcb *stcb)
2447 1.1 rjs {
2448 1.1 rjs struct mbuf *m_notify;
2449 1.1 rjs struct sctp_shutdown_event *sse;
2450 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2451 1.1 rjs const struct sockaddr *to;
2452 1.1 rjs
2453 1.1 rjs /*
2454 1.1 rjs * For TCP model AND UDP connected sockets we will send
2455 1.1 rjs * an error up when an SHUTDOWN completes
2456 1.1 rjs */
2457 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
2458 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
2459 1.1 rjs /* mark socket closed for read/write and wakeup! */
2460 1.1 rjs socantrcvmore(stcb->sctp_socket);
2461 1.1 rjs socantsendmore(stcb->sctp_socket);
2462 1.1 rjs }
2463 1.1 rjs
2464 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
2465 1.1 rjs /* event not enabled */
2466 1.1 rjs return;
2467 1.1 rjs
2468 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2469 1.1 rjs if (m_notify == NULL)
2470 1.1 rjs /* no space left */
2471 1.1 rjs return;
2472 1.1 rjs m_notify->m_len = 0;
2473 1.1 rjs sse = mtod(m_notify, struct sctp_shutdown_event *);
2474 1.1 rjs sse->sse_type = SCTP_SHUTDOWN_EVENT;
2475 1.1 rjs sse->sse_flags = 0;
2476 1.1 rjs sse->sse_length = sizeof(struct sctp_shutdown_event);
2477 1.1 rjs sse->sse_assoc_id = sctp_get_associd(stcb);
2478 1.1 rjs
2479 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2480 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
2481 1.9 ozaki m_reset_rcvif(m_notify);
2482 1.1 rjs m_notify->m_len = sizeof(struct sctp_shutdown_event);
2483 1.1 rjs m_notify->m_next = NULL;
2484 1.1 rjs
2485 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2486 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2487 1.1 rjs to->sa_family == AF_INET) {
2488 1.1 rjs const struct sockaddr_in *sin;
2489 1.1 rjs
2490 1.1 rjs sin = satocsin(to);
2491 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2492 1.1 rjs to = (struct sockaddr *)&sin6;
2493 1.1 rjs }
2494 1.1 rjs /* check and strip embedded scope junk */
2495 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to,
2496 1.1 rjs &lsa6);
2497 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2498 1.1 rjs sctp_m_freem(m_notify);
2499 1.1 rjs return;
2500 1.1 rjs }
2501 1.1 rjs /* append to socket */
2502 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2503 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2504 1.1 rjs SCTP_TCB_LOCK(stcb);
2505 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2506 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2507 1.1 rjs /* not enough room */
2508 1.1 rjs sctp_m_freem(m_notify);
2509 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2510 1.1 rjs return;
2511 1.1 rjs }
2512 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2513 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2514 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2515 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2516 1.1 rjs }
2517 1.1 rjs } else {
2518 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2519 1.1 rjs }
2520 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2521 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2522 1.1 rjs }
2523 1.1 rjs
2524 1.1 rjs static void
2525 1.1 rjs sctp_notify_stream_reset(struct sctp_tcb *stcb,
2526 1.1 rjs int number_entries, uint16_t *list, int flag)
2527 1.1 rjs {
2528 1.1 rjs struct mbuf *m_notify;
2529 1.1 rjs struct sctp_stream_reset_event *strreset;
2530 1.1 rjs struct sockaddr_in6 sin6, lsa6;
2531 1.1 rjs const struct sockaddr *to;
2532 1.1 rjs int len;
2533 1.1 rjs
2534 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT))
2535 1.1 rjs /* event not enabled */
2536 1.1 rjs return;
2537 1.1 rjs
2538 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA);
2539 1.1 rjs if (m_notify == NULL)
2540 1.1 rjs /* no space left */
2541 1.1 rjs return;
2542 1.1 rjs m_notify->m_len = 0;
2543 1.1 rjs len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
2544 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) {
2545 1.1 rjs MCLGET(m_notify, M_WAIT);
2546 1.1 rjs }
2547 1.1 rjs if (m_notify == NULL)
2548 1.1 rjs /* no clusters */
2549 1.1 rjs return;
2550 1.1 rjs
2551 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) {
2552 1.1 rjs /* never enough room */
2553 1.1 rjs m_freem(m_notify);
2554 1.1 rjs return;
2555 1.1 rjs }
2556 1.1 rjs strreset = mtod(m_notify, struct sctp_stream_reset_event *);
2557 1.1 rjs strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
2558 1.1 rjs if (number_entries == 0) {
2559 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS;
2560 1.1 rjs } else {
2561 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST;
2562 1.1 rjs }
2563 1.1 rjs strreset->strreset_length = len;
2564 1.1 rjs strreset->strreset_assoc_id = sctp_get_associd(stcb);
2565 1.1 rjs if (number_entries) {
2566 1.1 rjs int i;
2567 1.1 rjs for (i=0; i<number_entries; i++) {
2568 1.1 rjs strreset->strreset_list[i] = list[i];
2569 1.1 rjs }
2570 1.1 rjs }
2571 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION;
2572 1.1 rjs m_notify->m_pkthdr.len = len;
2573 1.9 ozaki m_reset_rcvif(m_notify);
2574 1.1 rjs m_notify->m_len = len;
2575 1.1 rjs m_notify->m_next = NULL;
2576 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
2577 1.1 rjs /* no space */
2578 1.1 rjs sctp_m_freem(m_notify);
2579 1.1 rjs return;
2580 1.1 rjs }
2581 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro);
2582 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
2583 1.1 rjs to->sa_family == AF_INET) {
2584 1.1 rjs const struct sockaddr_in *sin;
2585 1.1 rjs
2586 1.1 rjs sin = satocsin(to);
2587 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6);
2588 1.1 rjs to = (struct sockaddr *)&sin6;
2589 1.1 rjs }
2590 1.1 rjs /* check and strip embedded scope junk */
2591 1.1 rjs to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to,
2592 1.1 rjs &lsa6);
2593 1.1 rjs /* append to socket */
2594 1.1 rjs SCTP_TCB_UNLOCK(stcb);
2595 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep);
2596 1.1 rjs SCTP_TCB_LOCK(stcb);
2597 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to,
2598 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) {
2599 1.1 rjs /* not enough room */
2600 1.1 rjs sctp_m_freem(m_notify);
2601 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2602 1.1 rjs return;
2603 1.1 rjs }
2604 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) &&
2605 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){
2606 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) {
2607 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2608 1.1 rjs }
2609 1.1 rjs } else {
2610 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf);
2611 1.1 rjs }
2612 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep);
2613 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
2614 1.1 rjs }
2615 1.1 rjs
2616 1.1 rjs
2617 1.1 rjs void
2618 1.1 rjs sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb,
2619 1.1 rjs u_int32_t error, void *data)
2620 1.1 rjs {
2621 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2622 1.1 rjs /* No notifications up when we are in a no socket state */
2623 1.1 rjs return;
2624 1.1 rjs }
2625 1.1 rjs if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
2626 1.1 rjs /* Can't send up to a closed socket any notifications */
2627 1.1 rjs return;
2628 1.1 rjs }
2629 1.1 rjs switch (notification) {
2630 1.1 rjs case SCTP_NOTIFY_ASSOC_UP:
2631 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error);
2632 1.1 rjs break;
2633 1.1 rjs case SCTP_NOTIFY_ASSOC_DOWN:
2634 1.1 rjs sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error);
2635 1.1 rjs break;
2636 1.1 rjs case SCTP_NOTIFY_INTERFACE_DOWN:
2637 1.1 rjs {
2638 1.1 rjs struct sctp_nets *net;
2639 1.1 rjs net = (struct sctp_nets *)data;
2640 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE,
2641 1.1 rjs rtcache_getdst(&net->ro), error);
2642 1.1 rjs break;
2643 1.1 rjs }
2644 1.1 rjs case SCTP_NOTIFY_INTERFACE_UP:
2645 1.1 rjs {
2646 1.1 rjs struct sctp_nets *net;
2647 1.1 rjs net = (struct sctp_nets *)data;
2648 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE,
2649 1.1 rjs rtcache_getdst(&net->ro), error);
2650 1.1 rjs break;
2651 1.1 rjs }
2652 1.1 rjs case SCTP_NOTIFY_INTERFACE_CONFIRMED:
2653 1.1 rjs {
2654 1.1 rjs struct sctp_nets *net;
2655 1.1 rjs net = (struct sctp_nets *)data;
2656 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED,
2657 1.1 rjs rtcache_getdst(&net->ro), error);
2658 1.1 rjs break;
2659 1.1 rjs }
2660 1.1 rjs case SCTP_NOTIFY_DG_FAIL:
2661 1.1 rjs sctp_notify_send_failed(stcb, error,
2662 1.1 rjs (struct sctp_tmit_chunk *)data);
2663 1.1 rjs break;
2664 1.1 rjs case SCTP_NOTIFY_ADAPTION_INDICATION:
2665 1.1 rjs /* Here the error is the adaption indication */
2666 1.1 rjs sctp_notify_adaption_layer(stcb, error);
2667 1.1 rjs break;
2668 1.1 rjs case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
2669 1.1 rjs sctp_notify_partial_delivery_indication(stcb, error);
2670 1.1 rjs break;
2671 1.1 rjs case SCTP_NOTIFY_STRDATA_ERR:
2672 1.1 rjs break;
2673 1.1 rjs case SCTP_NOTIFY_ASSOC_ABORTED:
2674 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error);
2675 1.1 rjs break;
2676 1.1 rjs case SCTP_NOTIFY_PEER_OPENED_STREAM:
2677 1.1 rjs break;
2678 1.1 rjs case SCTP_NOTIFY_STREAM_OPENED_OK:
2679 1.1 rjs break;
2680 1.1 rjs case SCTP_NOTIFY_ASSOC_RESTART:
2681 1.1 rjs sctp_notify_assoc_change(SCTP_RESTART, stcb, error);
2682 1.1 rjs break;
2683 1.1 rjs case SCTP_NOTIFY_HB_RESP:
2684 1.1 rjs break;
2685 1.1 rjs case SCTP_NOTIFY_STR_RESET_SEND:
2686 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR);
2687 1.1 rjs break;
2688 1.1 rjs case SCTP_NOTIFY_STR_RESET_RECV:
2689 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR);
2690 1.1 rjs break;
2691 1.1 rjs case SCTP_NOTIFY_ASCONF_ADD_IP:
2692 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data,
2693 1.1 rjs error);
2694 1.1 rjs break;
2695 1.1 rjs case SCTP_NOTIFY_ASCONF_DELETE_IP:
2696 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
2697 1.1 rjs error);
2698 1.1 rjs break;
2699 1.1 rjs case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
2700 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
2701 1.1 rjs error);
2702 1.1 rjs break;
2703 1.1 rjs case SCTP_NOTIFY_ASCONF_SUCCESS:
2704 1.1 rjs break;
2705 1.1 rjs case SCTP_NOTIFY_ASCONF_FAILED:
2706 1.1 rjs break;
2707 1.1 rjs case SCTP_NOTIFY_PEER_SHUTDOWN:
2708 1.1 rjs sctp_notify_shutdown_event(stcb);
2709 1.1 rjs break;
2710 1.1 rjs default:
2711 1.1 rjs #ifdef SCTP_DEBUG
2712 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_UTIL1) {
2713 1.1 rjs printf("NOTIFY: unknown notification %xh (%u)\n",
2714 1.1 rjs notification, notification);
2715 1.1 rjs }
2716 1.1 rjs #endif /* SCTP_DEBUG */
2717 1.1 rjs break;
2718 1.1 rjs } /* end switch */
2719 1.1 rjs }
2720 1.1 rjs
2721 1.1 rjs void
2722 1.1 rjs sctp_report_all_outbound(struct sctp_tcb *stcb)
2723 1.1 rjs {
2724 1.1 rjs struct sctp_association *asoc;
2725 1.1 rjs struct sctp_stream_out *outs;
2726 1.1 rjs struct sctp_tmit_chunk *chk;
2727 1.1 rjs
2728 1.1 rjs asoc = &stcb->asoc;
2729 1.1 rjs
2730 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2731 1.1 rjs return;
2732 1.1 rjs }
2733 1.1 rjs /* now through all the gunk freeing chunks */
2734 1.1 rjs TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
2735 1.1 rjs /* now clean up any chunks here */
2736 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue);
2737 1.1 rjs while (chk) {
2738 1.1 rjs stcb->asoc.stream_queue_cnt--;
2739 1.1 rjs TAILQ_REMOVE(&outs->outqueue, chk, sctp_next);
2740 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
2741 1.1 rjs SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
2742 1.1 rjs if (chk->data) {
2743 1.1 rjs sctp_m_freem(chk->data);
2744 1.1 rjs chk->data = NULL;
2745 1.1 rjs }
2746 1.1 rjs if (chk->whoTo)
2747 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2748 1.1 rjs chk->whoTo = NULL;
2749 1.1 rjs chk->asoc = NULL;
2750 1.1 rjs /* Free the chunk */
2751 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2752 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2753 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2754 1.1 rjs panic("Chunk count is negative");
2755 1.1 rjs }
2756 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2757 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue);
2758 1.1 rjs }
2759 1.1 rjs }
2760 1.1 rjs /* pending send queue SHOULD be empty */
2761 1.1 rjs if (!TAILQ_EMPTY(&asoc->send_queue)) {
2762 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue);
2763 1.1 rjs while (chk) {
2764 1.1 rjs TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next);
2765 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk);
2766 1.1 rjs if (chk->data) {
2767 1.1 rjs sctp_m_freem(chk->data);
2768 1.1 rjs chk->data = NULL;
2769 1.1 rjs }
2770 1.1 rjs if (chk->whoTo)
2771 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2772 1.1 rjs chk->whoTo = NULL;
2773 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2774 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2775 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2776 1.1 rjs panic("Chunk count is negative");
2777 1.1 rjs }
2778 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2779 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue);
2780 1.1 rjs }
2781 1.1 rjs }
2782 1.1 rjs /* sent queue SHOULD be empty */
2783 1.1 rjs if (!TAILQ_EMPTY(&asoc->sent_queue)) {
2784 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue);
2785 1.1 rjs while (chk) {
2786 1.1 rjs TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
2787 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
2788 1.1 rjs SCTP_NOTIFY_DATAGRAM_SENT, chk);
2789 1.1 rjs if (chk->data) {
2790 1.1 rjs sctp_m_freem(chk->data);
2791 1.1 rjs chk->data = NULL;
2792 1.1 rjs }
2793 1.1 rjs if (chk->whoTo)
2794 1.1 rjs sctp_free_remote_addr(chk->whoTo);
2795 1.1 rjs chk->whoTo = NULL;
2796 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk);
2797 1.1 rjs sctppcbinfo.ipi_count_chunk--;
2798 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) {
2799 1.1 rjs panic("Chunk count is negative");
2800 1.1 rjs }
2801 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++;
2802 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue);
2803 1.1 rjs }
2804 1.1 rjs }
2805 1.1 rjs }
2806 1.1 rjs
2807 1.1 rjs void
2808 1.1 rjs sctp_abort_notification(struct sctp_tcb *stcb, int error)
2809 1.1 rjs {
2810 1.1 rjs
2811 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2812 1.1 rjs return;
2813 1.1 rjs }
2814 1.1 rjs /* Tell them we lost the asoc */
2815 1.1 rjs sctp_report_all_outbound(stcb);
2816 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL);
2817 1.1 rjs }
2818 1.1 rjs
2819 1.1 rjs void
2820 1.1 rjs sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2821 1.1 rjs struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err)
2822 1.1 rjs {
2823 1.1 rjs u_int32_t vtag;
2824 1.1 rjs
2825 1.1 rjs vtag = 0;
2826 1.1 rjs if (stcb != NULL) {
2827 1.1 rjs /* We have a TCB to abort, send notification too */
2828 1.1 rjs vtag = stcb->asoc.peer_vtag;
2829 1.1 rjs sctp_abort_notification(stcb, 0);
2830 1.1 rjs }
2831 1.1 rjs sctp_send_abort(m, iphlen, sh, vtag, op_err);
2832 1.1 rjs if (stcb != NULL) {
2833 1.1 rjs /* Ok, now lets free it */
2834 1.1 rjs sctp_free_assoc(inp, stcb);
2835 1.1 rjs } else {
2836 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2837 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2838 1.1 rjs sctp_inpcb_free(inp, 1);
2839 1.1 rjs }
2840 1.1 rjs }
2841 1.1 rjs }
2842 1.1 rjs }
2843 1.1 rjs
2844 1.1 rjs void
2845 1.1 rjs sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2846 1.1 rjs int error, struct mbuf *op_err)
2847 1.1 rjs {
2848 1.1 rjs
2849 1.1 rjs if (stcb == NULL) {
2850 1.1 rjs /* Got to have a TCB */
2851 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
2852 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2853 1.1 rjs sctp_inpcb_free(inp, 1);
2854 1.1 rjs }
2855 1.1 rjs }
2856 1.1 rjs return;
2857 1.1 rjs }
2858 1.1 rjs /* notify the ulp */
2859 1.1 rjs if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)
2860 1.1 rjs sctp_abort_notification(stcb, error);
2861 1.1 rjs /* notify the peer */
2862 1.1 rjs sctp_send_abort_tcb(stcb, op_err);
2863 1.1 rjs /* now free the asoc */
2864 1.1 rjs sctp_free_assoc(inp, stcb);
2865 1.1 rjs }
2866 1.1 rjs
2867 1.1 rjs void
2868 1.1 rjs sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
2869 1.1 rjs struct sctp_inpcb *inp, struct mbuf *op_err)
2870 1.1 rjs {
2871 1.1 rjs struct sctp_chunkhdr *ch, chunk_buf;
2872 1.1 rjs unsigned int chk_length;
2873 1.1 rjs
2874 1.1 rjs /* Generate a TO address for future reference */
2875 1.1 rjs if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
2876 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
2877 1.1 rjs sctp_inpcb_free(inp, 1);
2878 1.1 rjs }
2879 1.1 rjs }
2880 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
2881 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf);
2882 1.1 rjs while (ch != NULL) {
2883 1.1 rjs chk_length = ntohs(ch->chunk_length);
2884 1.1 rjs if (chk_length < sizeof(*ch)) {
2885 1.1 rjs /* break to abort land */
2886 1.1 rjs break;
2887 1.1 rjs }
2888 1.1 rjs switch (ch->chunk_type) {
2889 1.1 rjs case SCTP_PACKET_DROPPED:
2890 1.1 rjs /* we don't respond to pkt-dropped */
2891 1.1 rjs return;
2892 1.1 rjs case SCTP_ABORT_ASSOCIATION:
2893 1.1 rjs /* we don't respond with an ABORT to an ABORT */
2894 1.1 rjs return;
2895 1.1 rjs case SCTP_SHUTDOWN_COMPLETE:
2896 1.1 rjs /*
2897 1.1 rjs * we ignore it since we are not waiting for it
2898 1.1 rjs * and peer is gone
2899 1.1 rjs */
2900 1.1 rjs return;
2901 1.1 rjs case SCTP_SHUTDOWN_ACK:
2902 1.1 rjs sctp_send_shutdown_complete2(m, iphlen, sh);
2903 1.1 rjs return;
2904 1.1 rjs default:
2905 1.1 rjs break;
2906 1.1 rjs }
2907 1.1 rjs offset += SCTP_SIZE32(chk_length);
2908 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
2909 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf);
2910 1.1 rjs }
2911 1.1 rjs sctp_send_abort(m, iphlen, sh, 0, op_err);
2912 1.1 rjs }
2913 1.1 rjs
2914 1.1 rjs /*
2915 1.1 rjs * check the inbound datagram to make sure there is not an abort
2916 1.1 rjs * inside it, if there is return 1, else return 0.
2917 1.1 rjs */
2918 1.1 rjs int
2919 1.1 rjs sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill)
2920 1.1 rjs {
2921 1.1 rjs struct sctp_chunkhdr *ch;
2922 1.1 rjs struct sctp_init_chunk *init_chk, chunk_buf;
2923 1.1 rjs int offset;
2924 1.1 rjs unsigned int chk_length;
2925 1.1 rjs
2926 1.1 rjs offset = iphlen + sizeof(struct sctphdr);
2927 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch),
2928 1.1 rjs (u_int8_t *)&chunk_buf);
2929 1.1 rjs while (ch != NULL) {
2930 1.1 rjs chk_length = ntohs(ch->chunk_length);
2931 1.1 rjs if (chk_length < sizeof(*ch)) {
2932 1.1 rjs /* packet is probably corrupt */
2933 1.1 rjs break;
2934 1.1 rjs }
2935 1.1 rjs /* we seem to be ok, is it an abort? */
2936 1.1 rjs if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) {
2937 1.1 rjs /* yep, tell them */
2938 1.1 rjs return (1);
2939 1.1 rjs }
2940 1.1 rjs if (ch->chunk_type == SCTP_INITIATION) {
2941 1.1 rjs /* need to update the Vtag */
2942 1.1 rjs init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
2943 1.1 rjs offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf);
2944 1.1 rjs if (init_chk != NULL) {
2945 1.1 rjs *vtagfill = ntohl(init_chk->init.initiate_tag);
2946 1.1 rjs }
2947 1.1 rjs }
2948 1.1 rjs /* Nope, move to the next chunk */
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 return (0);
2954 1.1 rjs }
2955 1.1 rjs
2956 1.1 rjs /*
2957 1.1 rjs * currently (2/02), ifa_addr embeds scope_id's and don't
2958 1.1 rjs * have sin6_scope_id set (i.e. it's 0)
2959 1.1 rjs * so, create this function to compare link local scopes
2960 1.1 rjs */
2961 1.1 rjs uint32_t
2962 1.8 rjs sctp_is_same_scope(const struct sockaddr_in6 *addr1, const struct sockaddr_in6 *addr2)
2963 1.1 rjs {
2964 1.1 rjs struct sockaddr_in6 a, b;
2965 1.1 rjs
2966 1.1 rjs /* save copies */
2967 1.1 rjs a = *addr1;
2968 1.1 rjs b = *addr2;
2969 1.1 rjs
2970 1.1 rjs if (a.sin6_scope_id == 0)
2971 1.1 rjs if (sa6_recoverscope(&a)) {
2972 1.1 rjs /* can't get scope, so can't match */
2973 1.1 rjs return (0);
2974 1.1 rjs }
2975 1.1 rjs if (b.sin6_scope_id == 0)
2976 1.1 rjs if (sa6_recoverscope(&b)) {
2977 1.1 rjs /* can't get scope, so can't match */
2978 1.1 rjs return (0);
2979 1.1 rjs }
2980 1.1 rjs if (a.sin6_scope_id != b.sin6_scope_id)
2981 1.1 rjs return (0);
2982 1.1 rjs
2983 1.1 rjs return (1);
2984 1.1 rjs }
2985 1.1 rjs
2986 1.1 rjs /*
2987 1.1 rjs * returns a sockaddr_in6 with embedded scope recovered and removed
2988 1.1 rjs */
2989 1.1 rjs const struct sockaddr_in6 *
2990 1.1 rjs sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
2991 1.1 rjs {
2992 1.1 rjs const struct sockaddr_in6 *newaddr;
2993 1.1 rjs
2994 1.1 rjs newaddr = addr;
2995 1.1 rjs /* check and strip embedded scope junk */
2996 1.1 rjs if (addr->sin6_family == AF_INET6) {
2997 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) {
2998 1.1 rjs if (addr->sin6_scope_id == 0) {
2999 1.1 rjs *store = *addr;
3000 1.1 rjs if (sa6_recoverscope(store) == 0) {
3001 1.1 rjs /* use the recovered scope */
3002 1.1 rjs newaddr = store;
3003 1.1 rjs }
3004 1.1 rjs /* else, return the original "to" addr */
3005 1.1 rjs }
3006 1.1 rjs }
3007 1.1 rjs }
3008 1.1 rjs return (newaddr);
3009 1.1 rjs }
3010 1.1 rjs
3011 1.1 rjs /*
3012 1.1 rjs * are the two addresses the same? currently a "scopeless" check
3013 1.1 rjs * returns: 1 if same, 0 if not
3014 1.1 rjs */
3015 1.1 rjs int
3016 1.1 rjs sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
3017 1.1 rjs {
3018 1.1 rjs
3019 1.1 rjs /* must be valid */
3020 1.1 rjs if (sa1 == NULL || sa2 == NULL)
3021 1.1 rjs return (0);
3022 1.1 rjs
3023 1.1 rjs /* must be the same family */
3024 1.1 rjs if (sa1->sa_family != sa2->sa_family)
3025 1.1 rjs return (0);
3026 1.1 rjs
3027 1.1 rjs if (sa1->sa_family == AF_INET6) {
3028 1.1 rjs /* IPv6 addresses */
3029 1.1 rjs const struct sockaddr_in6 *sin6_1, *sin6_2;
3030 1.1 rjs
3031 1.1 rjs sin6_1 = (const struct sockaddr_in6 *)sa1;
3032 1.1 rjs sin6_2 = (const struct sockaddr_in6 *)sa2;
3033 1.1 rjs return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
3034 1.1 rjs &sin6_2->sin6_addr));
3035 1.1 rjs } else if (sa1->sa_family == AF_INET) {
3036 1.1 rjs /* IPv4 addresses */
3037 1.1 rjs const struct sockaddr_in *sin_1, *sin_2;
3038 1.1 rjs
3039 1.1 rjs sin_1 = (const struct sockaddr_in *)sa1;
3040 1.1 rjs sin_2 = (const struct sockaddr_in *)sa2;
3041 1.1 rjs return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
3042 1.1 rjs } else {
3043 1.1 rjs /* we don't do these... */
3044 1.1 rjs return (0);
3045 1.1 rjs }
3046 1.1 rjs }
3047 1.1 rjs
3048 1.1 rjs void
3049 1.1 rjs sctp_print_address(const struct sockaddr *sa)
3050 1.1 rjs {
3051 1.11 ryo char ip6buf[INET6_ADDRSTRLEN];
3052 1.1 rjs
3053 1.1 rjs if (sa->sa_family == AF_INET6) {
3054 1.1 rjs const struct sockaddr_in6 *sin6;
3055 1.1 rjs sin6 = (const struct sockaddr_in6 *)sa;
3056 1.1 rjs printf("IPv6 address: %s:%d scope:%u\n",
3057 1.12 christos IN6_PRINT(ip6buf, &sin6->sin6_addr), ntohs(sin6->sin6_port),
3058 1.1 rjs sin6->sin6_scope_id);
3059 1.1 rjs } else if (sa->sa_family == AF_INET) {
3060 1.1 rjs const struct sockaddr_in *sin;
3061 1.1 rjs sin = (const struct sockaddr_in *)sa;
3062 1.1 rjs printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr),
3063 1.1 rjs ntohs(sin->sin_port));
3064 1.1 rjs } else {
3065 1.1 rjs printf("?\n");
3066 1.1 rjs }
3067 1.1 rjs }
3068 1.1 rjs
3069 1.1 rjs void
3070 1.1 rjs sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
3071 1.1 rjs {
3072 1.1 rjs if (iph->ip_v == IPVERSION) {
3073 1.1 rjs struct sockaddr_in lsa, fsa;
3074 1.1 rjs
3075 1.1 rjs memset(&lsa, 0, sizeof(lsa));
3076 1.1 rjs lsa.sin_len = sizeof(lsa);
3077 1.1 rjs lsa.sin_family = AF_INET;
3078 1.1 rjs lsa.sin_addr = iph->ip_src;
3079 1.1 rjs lsa.sin_port = sh->src_port;
3080 1.1 rjs memset(&fsa, 0, sizeof(fsa));
3081 1.1 rjs fsa.sin_len = sizeof(fsa);
3082 1.1 rjs fsa.sin_family = AF_INET;
3083 1.1 rjs fsa.sin_addr = iph->ip_dst;
3084 1.1 rjs fsa.sin_port = sh->dest_port;
3085 1.1 rjs printf("src: ");
3086 1.1 rjs sctp_print_address((struct sockaddr *)&lsa);
3087 1.1 rjs printf("dest: ");
3088 1.1 rjs sctp_print_address((struct sockaddr *)&fsa);
3089 1.1 rjs } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
3090 1.1 rjs struct ip6_hdr *ip6;
3091 1.1 rjs struct sockaddr_in6 lsa6, fsa6;
3092 1.1 rjs
3093 1.1 rjs ip6 = (struct ip6_hdr *)iph;
3094 1.1 rjs memset(&lsa6, 0, sizeof(lsa6));
3095 1.1 rjs lsa6.sin6_len = sizeof(lsa6);
3096 1.1 rjs lsa6.sin6_family = AF_INET6;
3097 1.1 rjs lsa6.sin6_addr = ip6->ip6_src;
3098 1.1 rjs lsa6.sin6_port = sh->src_port;
3099 1.1 rjs memset(&fsa6, 0, sizeof(fsa6));
3100 1.1 rjs fsa6.sin6_len = sizeof(fsa6);
3101 1.1 rjs fsa6.sin6_family = AF_INET6;
3102 1.1 rjs fsa6.sin6_addr = ip6->ip6_dst;
3103 1.1 rjs fsa6.sin6_port = sh->dest_port;
3104 1.1 rjs printf("src: ");
3105 1.1 rjs sctp_print_address((struct sockaddr *)&lsa6);
3106 1.1 rjs printf("dest: ");
3107 1.1 rjs sctp_print_address((struct sockaddr *)&fsa6);
3108 1.1 rjs }
3109 1.1 rjs }
3110 1.1 rjs
3111 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__)
3112 1.1 rjs
3113 1.1 rjs /* cloned from uipc_socket.c */
3114 1.1 rjs
3115 1.1 rjs #define SCTP_SBLINKRECORD(sb, m0) do { \
3116 1.1 rjs if ((sb)->sb_lastrecord != NULL) \
3117 1.1 rjs (sb)->sb_lastrecord->m_nextpkt = (m0); \
3118 1.1 rjs else \
3119 1.1 rjs (sb)->sb_mb = (m0); \
3120 1.1 rjs (sb)->sb_lastrecord = (m0); \
3121 1.1 rjs } while (/*CONSTCOND*/0)
3122 1.1 rjs #endif
3123 1.1 rjs
3124 1.1 rjs
3125 1.1 rjs int
3126 1.1 rjs sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa,
3127 1.1 rjs struct mbuf *m0, struct mbuf *control,
3128 1.1 rjs u_int32_t tag, struct sctp_inpcb *inp)
3129 1.1 rjs {
3130 1.1 rjs #ifdef __NetBSD__
3131 1.1 rjs struct mbuf *m, *n;
3132 1.1 rjs
3133 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3134 1.1 rjs panic("sbappendaddr_nocheck");
3135 1.1 rjs
3136 1.1 rjs m0->m_pkthdr.csum_data = (int)tag;
3137 1.1 rjs
3138 1.1 rjs for (n = control; n; n = n->m_next) {
3139 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */
3140 1.1 rjs break;
3141 1.1 rjs }
3142 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3143 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3144 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3145 1.1 rjs if (m == 0)
3146 1.1 rjs return (0);
3147 1.1 rjs
3148 1.1 rjs m->m_len = asa->sa_len;
3149 1.1 rjs memcpy(mtod(m, void *), (const void *)asa, asa->sa_len);
3150 1.1 rjs } else {
3151 1.1 rjs m = NULL;
3152 1.1 rjs }
3153 1.1 rjs if (n) {
3154 1.1 rjs n->m_next = m0; /* concatenate data to control */
3155 1.1 rjs }else {
3156 1.1 rjs control = m0;
3157 1.1 rjs }
3158 1.1 rjs if (m)
3159 1.1 rjs m->m_next = control;
3160 1.1 rjs else
3161 1.1 rjs m = control;
3162 1.1 rjs m->m_pkthdr.csum_data = tag;
3163 1.1 rjs
3164 1.1 rjs for (n = m; n; n = n->m_next)
3165 1.1 rjs sballoc(sb, n);
3166 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3167 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3168 1.1 rjs inp->sb_last_mpkt = NULL;
3169 1.1 rjs }
3170 1.1 rjs if (inp->sb_last_mpkt)
3171 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3172 1.1 rjs else {
3173 1.1 rjs while (n->m_nextpkt) {
3174 1.1 rjs n = n->m_nextpkt;
3175 1.1 rjs }
3176 1.1 rjs n->m_nextpkt = m;
3177 1.1 rjs }
3178 1.1 rjs inp->sb_last_mpkt = m;
3179 1.1 rjs } else {
3180 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3181 1.1 rjs inp->sctp_vtag_first = tag;
3182 1.1 rjs }
3183 1.1 rjs return (1);
3184 1.1 rjs #endif
3185 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__)
3186 1.1 rjs struct mbuf *m, *n, *nlast;
3187 1.1 rjs int cnt=0;
3188 1.1 rjs
3189 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3190 1.1 rjs panic("sbappendaddr_nocheck");
3191 1.1 rjs
3192 1.1 rjs for (n = control; n; n = n->m_next) {
3193 1.1 rjs if (n->m_next == 0) /* get pointer to last control buf */
3194 1.1 rjs break;
3195 1.1 rjs }
3196 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3197 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3198 1.1 rjs if (asa->sa_len > MHLEN)
3199 1.1 rjs return (0);
3200 1.1 rjs try_again:
3201 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3202 1.1 rjs if (m == 0)
3203 1.1 rjs return (0);
3204 1.1 rjs m->m_len = 0;
3205 1.1 rjs /* safety */
3206 1.1 rjs if (m == m0) {
3207 1.1 rjs printf("Duplicate mbuf allocated %p in and mget returned %p?\n",
3208 1.1 rjs m0, m);
3209 1.1 rjs if (cnt) {
3210 1.1 rjs panic("more than once");
3211 1.1 rjs }
3212 1.1 rjs cnt++;
3213 1.1 rjs goto try_again;
3214 1.1 rjs }
3215 1.1 rjs m->m_len = asa->sa_len;
3216 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len);
3217 1.1 rjs }
3218 1.1 rjs else {
3219 1.1 rjs m = NULL;
3220 1.1 rjs }
3221 1.1 rjs if (n)
3222 1.1 rjs n->m_next = m0; /* concatenate data to control */
3223 1.1 rjs else
3224 1.1 rjs control = m0;
3225 1.1 rjs if (m)
3226 1.1 rjs m->m_next = control;
3227 1.1 rjs else
3228 1.1 rjs m = control;
3229 1.1 rjs m->m_pkthdr.csum_data = (int)tag;
3230 1.1 rjs
3231 1.1 rjs for (n = m; n; n = n->m_next)
3232 1.1 rjs sballoc(sb, n);
3233 1.1 rjs nlast = n;
3234 1.1 rjs if (sb->sb_mb == NULL) {
3235 1.1 rjs inp->sctp_vtag_first = tag;
3236 1.1 rjs }
3237 1.1 rjs
3238 1.1 rjs #ifdef __FREEBSD__
3239 1.1 rjs if (sb->sb_mb == NULL)
3240 1.1 rjs inp->sctp_vtag_first = tag;
3241 1.1 rjs SCTP_SBLINKRECORD(sb, m);
3242 1.1 rjs sb->sb_mbtail = nlast;
3243 1.1 rjs #else
3244 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3245 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3246 1.1 rjs inp->sb_last_mpkt = NULL;
3247 1.1 rjs }
3248 1.1 rjs if (inp->sb_last_mpkt)
3249 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3250 1.1 rjs else {
3251 1.1 rjs while (n->m_nextpkt) {
3252 1.1 rjs n = n->m_nextpkt;
3253 1.1 rjs }
3254 1.1 rjs n->m_nextpkt = m;
3255 1.1 rjs }
3256 1.1 rjs inp->sb_last_mpkt = m;
3257 1.1 rjs } else {
3258 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3259 1.1 rjs inp->sctp_vtag_first = tag;
3260 1.1 rjs }
3261 1.1 rjs #endif
3262 1.1 rjs return (1);
3263 1.1 rjs #endif
3264 1.1 rjs #ifdef __OpenBSD__
3265 1.1 rjs struct mbuf *m, *n;
3266 1.1 rjs
3267 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0)
3268 1.1 rjs panic("sbappendaddr_nocheck");
3269 1.1 rjs m0->m_pkthdr.csum = (int)tag;
3270 1.1 rjs for (n = control; n; n = n->m_next) {
3271 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */
3272 1.1 rjs break;
3273 1.1 rjs }
3274 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) ||
3275 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) {
3276 1.1 rjs if (asa->sa_len > MHLEN)
3277 1.1 rjs return (0);
3278 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME);
3279 1.1 rjs if (m == 0)
3280 1.1 rjs return (0);
3281 1.1 rjs m->m_len = asa->sa_len;
3282 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len);
3283 1.1 rjs } else {
3284 1.1 rjs m = NULL;
3285 1.1 rjs }
3286 1.1 rjs if (n)
3287 1.1 rjs n->m_next = m0; /* concatenate data to control */
3288 1.1 rjs else
3289 1.1 rjs control = m0;
3290 1.1 rjs
3291 1.1 rjs m->m_pkthdr.csum = (int)tag;
3292 1.1 rjs m->m_next = control;
3293 1.1 rjs for (n = m; n; n = n->m_next)
3294 1.1 rjs sballoc(sb, n);
3295 1.1 rjs if ((n = sb->sb_mb) != NULL) {
3296 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) {
3297 1.1 rjs inp->sb_last_mpkt = NULL;
3298 1.1 rjs }
3299 1.1 rjs if (inp->sb_last_mpkt)
3300 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m;
3301 1.1 rjs else {
3302 1.1 rjs while (n->m_nextpkt) {
3303 1.1 rjs n = n->m_nextpkt;
3304 1.1 rjs }
3305 1.1 rjs n->m_nextpkt = m;
3306 1.1 rjs }
3307 1.1 rjs inp->sb_last_mpkt = m;
3308 1.1 rjs } else {
3309 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m;
3310 1.1 rjs inp->sctp_vtag_first = tag;
3311 1.1 rjs }
3312 1.1 rjs return (1);
3313 1.1 rjs #endif
3314 1.1 rjs }
3315 1.1 rjs
3316 1.1 rjs /*************HOLD THIS COMMENT FOR PATCH FILE OF
3317 1.1 rjs *************ALTERNATE ROUTING CODE
3318 1.1 rjs */
3319 1.1 rjs
3320 1.1 rjs /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF
3321 1.1 rjs *************ALTERNATE ROUTING CODE
3322 1.1 rjs */
3323 1.1 rjs
3324 1.1 rjs struct mbuf *
3325 1.1 rjs sctp_generate_invmanparam(int err)
3326 1.1 rjs {
3327 1.1 rjs /* Return a MBUF with a invalid mandatory parameter */
3328 1.1 rjs struct mbuf *m;
3329 1.1 rjs
3330 1.1 rjs MGET(m, M_DONTWAIT, MT_DATA);
3331 1.1 rjs if (m) {
3332 1.1 rjs struct sctp_paramhdr *ph;
3333 1.1 rjs m->m_len = sizeof(struct sctp_paramhdr);
3334 1.1 rjs ph = mtod(m, struct sctp_paramhdr *);
3335 1.1 rjs ph->param_length = htons(sizeof(struct sctp_paramhdr));
3336 1.1 rjs ph->param_type = htons(err);
3337 1.1 rjs }
3338 1.1 rjs return (m);
3339 1.1 rjs }
3340 1.1 rjs
3341 1.1 rjs static int
3342 1.1 rjs sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc)
3343 1.1 rjs {
3344 1.1 rjs struct mbuf *m;
3345 1.1 rjs /*
3346 1.1 rjs * given a mbuf chain, look through it finding
3347 1.1 rjs * the M_PKTHDR and return 1 if it belongs to
3348 1.1 rjs * the association given. We tell this by
3349 1.1 rjs * a kludge where we stuff the my_vtag of the asoc
3350 1.1 rjs * into the m->m_pkthdr.csum_data/csum field.
3351 1.1 rjs */
3352 1.1 rjs m = this;
3353 1.1 rjs while (m) {
3354 1.1 rjs if (m->m_flags & M_PKTHDR) {
3355 1.1 rjs /* check it */
3356 1.1 rjs #if defined(__OpenBSD__)
3357 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag)
3358 1.1 rjs #else
3359 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag)
3360 1.1 rjs #endif
3361 1.1 rjs {
3362 1.1 rjs /* Yep */
3363 1.1 rjs return (1);
3364 1.1 rjs }
3365 1.1 rjs }
3366 1.1 rjs m = m->m_next;
3367 1.1 rjs }
3368 1.1 rjs return (0);
3369 1.1 rjs }
3370 1.1 rjs
3371 1.1 rjs u_int32_t
3372 1.1 rjs sctp_get_first_vtag_from_sb(struct socket *so)
3373 1.1 rjs {
3374 1.1 rjs struct mbuf *this, *at;
3375 1.1 rjs u_int32_t retval;
3376 1.1 rjs
3377 1.1 rjs retval = 0;
3378 1.1 rjs if (so->so_rcv.sb_mb) {
3379 1.1 rjs /* grubbing time */
3380 1.1 rjs this = so->so_rcv.sb_mb;
3381 1.1 rjs while (this) {
3382 1.1 rjs at = this;
3383 1.1 rjs /* get to the m_pkthdr */
3384 1.1 rjs while (at) {
3385 1.1 rjs if (at->m_flags & M_PKTHDR)
3386 1.1 rjs break;
3387 1.1 rjs else {
3388 1.1 rjs at = at->m_next;
3389 1.1 rjs }
3390 1.1 rjs }
3391 1.1 rjs /* now do we have a m_pkthdr */
3392 1.1 rjs if (at && (at->m_flags & M_PKTHDR)) {
3393 1.1 rjs /* check it */
3394 1.1 rjs #if defined(__OpenBSD__)
3395 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum != 0)
3396 1.1 rjs #else
3397 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum_data != 0)
3398 1.1 rjs #endif
3399 1.1 rjs {
3400 1.1 rjs /* its the one */
3401 1.1 rjs #if defined(__OpenBSD__)
3402 1.1 rjs retval = (u_int32_t)at->m_pkthdr.csum;
3403 1.1 rjs #else
3404 1.1 rjs retval =
3405 1.1 rjs (u_int32_t)at->m_pkthdr.csum_data;
3406 1.1 rjs #endif
3407 1.1 rjs break;
3408 1.1 rjs }
3409 1.1 rjs }
3410 1.1 rjs this = this->m_nextpkt;
3411 1.1 rjs }
3412 1.1 rjs
3413 1.1 rjs }
3414 1.1 rjs return (retval);
3415 1.1 rjs
3416 1.1 rjs }
3417 1.1 rjs void
3418 1.1 rjs sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old,
3419 1.1 rjs struct socket *new, struct sctp_tcb *stcb)
3420 1.1 rjs {
3421 1.1 rjs struct mbuf **put, **take, *next, *this;
3422 1.1 rjs struct sockbuf *old_sb, *new_sb;
3423 1.1 rjs struct sctp_association *asoc;
3424 1.1 rjs int moved_top = 0;
3425 1.1 rjs
3426 1.1 rjs asoc = &stcb->asoc;
3427 1.1 rjs old_sb = &old->so_rcv;
3428 1.1 rjs new_sb = &new->so_rcv;
3429 1.1 rjs if (old_sb->sb_mb == NULL) {
3430 1.1 rjs /* Nothing to move */
3431 1.1 rjs return;
3432 1.1 rjs }
3433 1.1 rjs
3434 1.1 rjs if (inp->sctp_vtag_first == asoc->my_vtag) {
3435 1.1 rjs /* First one must be moved */
3436 1.1 rjs struct mbuf *mm;
3437 1.1 rjs for (mm = old_sb->sb_mb; mm; mm = mm->m_next) {
3438 1.1 rjs /*
3439 1.1 rjs * Go down the chain and fix
3440 1.1 rjs * the space allocation of the
3441 1.1 rjs * two sockets.
3442 1.1 rjs */
3443 1.1 rjs sbfree(old_sb, mm);
3444 1.1 rjs sballoc(new_sb, mm);
3445 1.1 rjs }
3446 1.1 rjs new_sb->sb_mb = old_sb->sb_mb;
3447 1.1 rjs old_sb->sb_mb = new_sb->sb_mb->m_nextpkt;
3448 1.1 rjs new_sb->sb_mb->m_nextpkt = NULL;
3449 1.1 rjs put = &new_sb->sb_mb->m_nextpkt;
3450 1.1 rjs moved_top = 1;
3451 1.1 rjs } else {
3452 1.1 rjs put = &new_sb->sb_mb;
3453 1.1 rjs }
3454 1.1 rjs
3455 1.1 rjs take = &old_sb->sb_mb;
3456 1.1 rjs next = old_sb->sb_mb;
3457 1.1 rjs while (next) {
3458 1.1 rjs this = next;
3459 1.1 rjs /* postion for next one */
3460 1.1 rjs next = this->m_nextpkt;
3461 1.1 rjs /* check the tag of this packet */
3462 1.1 rjs if (sctp_should_be_moved(this, asoc)) {
3463 1.1 rjs /* yes this needs to be moved */
3464 1.1 rjs struct mbuf *mm;
3465 1.1 rjs *take = this->m_nextpkt;
3466 1.1 rjs this->m_nextpkt = NULL;
3467 1.1 rjs *put = this;
3468 1.1 rjs for (mm = this; mm; mm = mm->m_next) {
3469 1.1 rjs /*
3470 1.1 rjs * Go down the chain and fix
3471 1.1 rjs * the space allocation of the
3472 1.1 rjs * two sockets.
3473 1.1 rjs */
3474 1.1 rjs sbfree(old_sb, mm);
3475 1.1 rjs sballoc(new_sb, mm);
3476 1.1 rjs }
3477 1.1 rjs put = &this->m_nextpkt;
3478 1.1 rjs
3479 1.1 rjs } else {
3480 1.1 rjs /* no advance our take point. */
3481 1.1 rjs take = &this->m_nextpkt;
3482 1.1 rjs }
3483 1.1 rjs }
3484 1.1 rjs if (moved_top) {
3485 1.1 rjs /*
3486 1.1 rjs * Ok so now we must re-postion vtag_first to
3487 1.1 rjs * match the new first one since we moved the
3488 1.1 rjs * mbuf at the top.
3489 1.1 rjs */
3490 1.1 rjs inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old);
3491 1.1 rjs }
3492 1.1 rjs }
3493 1.1 rjs
3494 1.1 rjs void
3495 1.1 rjs sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
3496 1.1 rjs struct sctp_tmit_chunk *tp1)
3497 1.1 rjs {
3498 1.1 rjs if (tp1->data == NULL) {
3499 1.1 rjs return;
3500 1.1 rjs }
3501 1.1 rjs #ifdef SCTP_MBCNT_LOGGING
3502 1.1 rjs sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE,
3503 1.1 rjs asoc->total_output_queue_size,
3504 1.1 rjs tp1->book_size,
3505 1.1 rjs asoc->total_output_mbuf_queue_size,
3506 1.1 rjs tp1->mbcnt);
3507 1.1 rjs #endif
3508 1.1 rjs if (asoc->total_output_queue_size >= tp1->book_size) {
3509 1.1 rjs asoc->total_output_queue_size -= tp1->book_size;
3510 1.1 rjs } else {
3511 1.1 rjs asoc->total_output_queue_size = 0;
3512 1.1 rjs }
3513 1.1 rjs
3514 1.1 rjs /* Now free the mbuf */
3515 1.1 rjs if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) {
3516 1.1 rjs asoc->total_output_mbuf_queue_size -= tp1->mbcnt;
3517 1.1 rjs } else {
3518 1.1 rjs asoc->total_output_mbuf_queue_size = 0;
3519 1.1 rjs }
3520 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
3521 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
3522 1.1 rjs if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) {
3523 1.1 rjs stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size;
3524 1.1 rjs } else {
3525 1.1 rjs stcb->sctp_socket->so_snd.sb_cc = 0;
3526 1.1 rjs
3527 1.1 rjs }
3528 1.1 rjs if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) {
3529 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt;
3530 1.1 rjs } else {
3531 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt = 0;
3532 1.1 rjs }
3533 1.1 rjs }
3534 1.1 rjs }
3535 1.1 rjs
3536 1.1 rjs int
3537 1.1 rjs sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
3538 1.1 rjs int reason, struct sctpchunk_listhead *queue)
3539 1.1 rjs {
3540 1.1 rjs int ret_sz = 0;
3541 1.1 rjs int notdone;
3542 1.1 rjs uint8_t foundeom = 0;
3543 1.1 rjs
3544 1.1 rjs do {
3545 1.1 rjs ret_sz += tp1->book_size;
3546 1.1 rjs tp1->sent = SCTP_FORWARD_TSN_SKIP;
3547 1.1 rjs if (tp1->data) {
3548 1.1 rjs sctp_free_bufspace(stcb, &stcb->asoc, tp1);
3549 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1);
3550 1.1 rjs sctp_m_freem(tp1->data);
3551 1.1 rjs tp1->data = NULL;
3552 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
3553 1.1 rjs }
3554 1.1 rjs if (tp1->flags & SCTP_PR_SCTP_BUFFER) {
3555 1.1 rjs stcb->asoc.sent_queue_cnt_removeable--;
3556 1.1 rjs }
3557 1.1 rjs if (queue == &stcb->asoc.send_queue) {
3558 1.1 rjs TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next);
3559 1.1 rjs /* on to the sent queue */
3560 1.1 rjs TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1,
3561 1.1 rjs sctp_next);
3562 1.1 rjs stcb->asoc.sent_queue_cnt++;
3563 1.1 rjs }
3564 1.1 rjs if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) ==
3565 1.1 rjs SCTP_DATA_NOT_FRAG) {
3566 1.1 rjs /* not frag'ed we ae done */
3567 1.1 rjs notdone = 0;
3568 1.1 rjs foundeom = 1;
3569 1.1 rjs } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
3570 1.1 rjs /* end of frag, we are done */
3571 1.1 rjs notdone = 0;
3572 1.1 rjs foundeom = 1;
3573 1.1 rjs } else {
3574 1.1 rjs /* Its a begin or middle piece, we must mark all of it */
3575 1.1 rjs notdone = 1;
3576 1.1 rjs tp1 = TAILQ_NEXT(tp1, sctp_next);
3577 1.1 rjs }
3578 1.1 rjs } while (tp1 && notdone);
3579 1.1 rjs if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) {
3580 1.1 rjs /*
3581 1.1 rjs * The multi-part message was scattered
3582 1.1 rjs * across the send and sent queue.
3583 1.1 rjs */
3584 1.1 rjs tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
3585 1.1 rjs /*
3586 1.1 rjs * recurse throught the send_queue too, starting at the
3587 1.1 rjs * beginning.
3588 1.1 rjs */
3589 1.1 rjs if (tp1) {
3590 1.1 rjs ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason,
3591 1.1 rjs &stcb->asoc.send_queue);
3592 1.1 rjs } else {
3593 1.1 rjs printf("hmm, nothing on the send queue and no EOM?\n");
3594 1.1 rjs }
3595 1.1 rjs }
3596 1.1 rjs return (ret_sz);
3597 1.1 rjs }
3598 1.1 rjs
3599 1.1 rjs /*
3600 1.1 rjs * checks to see if the given address, sa, is one that is currently
3601 1.1 rjs * known by the kernel
3602 1.1 rjs * note: can't distinguish the same address on multiple interfaces and
3603 1.1 rjs * doesn't handle multiple addresses with different zone/scope id's
3604 1.1 rjs * note: ifa_ifwithaddr() compares the entire sockaddr struct
3605 1.1 rjs */
3606 1.1 rjs struct ifaddr *
3607 1.1 rjs sctp_find_ifa_by_addr(struct sockaddr *sa)
3608 1.1 rjs {
3609 1.1 rjs struct ifnet *ifn;
3610 1.1 rjs struct ifaddr *ifa;
3611 1.7 ozaki int s;
3612 1.1 rjs
3613 1.1 rjs /* go through all our known interfaces */
3614 1.7 ozaki s = pserialize_read_enter();
3615 1.7 ozaki IFNET_READER_FOREACH(ifn) {
3616 1.1 rjs /* go through each interface addresses */
3617 1.10 ozaki IFADDR_READER_FOREACH(ifa, ifn) {
3618 1.1 rjs /* correct family? */
3619 1.1 rjs if (ifa->ifa_addr->sa_family != sa->sa_family)
3620 1.1 rjs continue;
3621 1.1 rjs
3622 1.1 rjs #ifdef INET6
3623 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET6) {
3624 1.1 rjs /* IPv6 address */
3625 1.1 rjs struct sockaddr_in6 *sin1, *sin2, sin6_tmp;
3626 1.1 rjs sin1 = (struct sockaddr_in6 *)ifa->ifa_addr;
3627 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) {
3628 1.1 rjs /* create a copy and clear scope */
3629 1.1 rjs memcpy(&sin6_tmp, sin1,
3630 1.1 rjs sizeof(struct sockaddr_in6));
3631 1.1 rjs sin1 = &sin6_tmp;
3632 1.1 rjs in6_clearscope(&sin1->sin6_addr);
3633 1.1 rjs }
3634 1.1 rjs sin2 = (struct sockaddr_in6 *)sa;
3635 1.1 rjs if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
3636 1.1 rjs sizeof(struct in6_addr)) == 0) {
3637 1.1 rjs /* found it */
3638 1.7 ozaki pserialize_read_exit(s);
3639 1.1 rjs return (ifa);
3640 1.1 rjs }
3641 1.1 rjs } else
3642 1.1 rjs #endif
3643 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET) {
3644 1.1 rjs /* IPv4 address */
3645 1.1 rjs struct sockaddr_in *sin1, *sin2;
3646 1.1 rjs sin1 = (struct sockaddr_in *)ifa->ifa_addr;
3647 1.1 rjs sin2 = (struct sockaddr_in *)sa;
3648 1.1 rjs if (sin1->sin_addr.s_addr ==
3649 1.1 rjs sin2->sin_addr.s_addr) {
3650 1.1 rjs /* found it */
3651 1.7 ozaki pserialize_read_exit(s);
3652 1.1 rjs return (ifa);
3653 1.1 rjs }
3654 1.1 rjs }
3655 1.1 rjs /* else, not AF_INET or AF_INET6, so skip */
3656 1.1 rjs } /* end foreach ifa */
3657 1.1 rjs } /* end foreach ifn */
3658 1.7 ozaki pserialize_read_exit(s);
3659 1.7 ozaki
3660 1.1 rjs /* not found! */
3661 1.1 rjs return (NULL);
3662 1.1 rjs }
3663 1.1 rjs
3664 1.1 rjs
3665 1.1 rjs #ifdef __APPLE__
3666 1.1 rjs /*
3667 1.1 rjs * here we hack in a fix for Apple's m_copym for the case where the first mbuf
3668 1.1 rjs * in the chain is a M_PKTHDR and the length is zero
3669 1.1 rjs */
3670 1.1 rjs static void
3671 1.1 rjs sctp_pkthdr_fix(struct mbuf *m)
3672 1.1 rjs {
3673 1.1 rjs struct mbuf *m_nxt;
3674 1.1 rjs
3675 1.1 rjs if ((m->m_flags & M_PKTHDR) == 0) {
3676 1.1 rjs /* not a PKTHDR */
3677 1.1 rjs return;
3678 1.1 rjs }
3679 1.1 rjs
3680 1.1 rjs if (m->m_len != 0) {
3681 1.1 rjs /* not a zero length PKTHDR mbuf */
3682 1.1 rjs return;
3683 1.1 rjs }
3684 1.1 rjs
3685 1.1 rjs /* let's move in a word into the first mbuf... yes, ugly! */
3686 1.1 rjs m_nxt = m->m_next;
3687 1.1 rjs if (m_nxt == NULL) {
3688 1.1 rjs /* umm... not a very useful mbuf chain... */
3689 1.1 rjs return;
3690 1.1 rjs }
3691 1.1 rjs if ((size_t)m_nxt->m_len > sizeof(long)) {
3692 1.1 rjs /* move over a long */
3693 1.1 rjs bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long));
3694 1.1 rjs /* update mbuf data pointers and lengths */
3695 1.1 rjs m->m_len += sizeof(long);
3696 1.1 rjs m_nxt->m_data += sizeof(long);
3697 1.1 rjs m_nxt->m_len -= sizeof(long);
3698 1.1 rjs }
3699 1.1 rjs }
3700 1.1 rjs
3701 1.1 rjs inline struct mbuf *
3702 1.1 rjs sctp_m_copym(struct mbuf *m, int off, int len, int wait)
3703 1.1 rjs {
3704 1.1 rjs sctp_pkthdr_fix(m);
3705 1.1 rjs return (m_copym(m, off, len, wait));
3706 1.1 rjs }
3707 1.1 rjs #endif /* __APPLE__ */
3708