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