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