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