1 |
1275 |
phoenix |
/* SCTP kernel reference Implementation
|
2 |
|
|
* (C) Copyright IBM Corp. 2001, 2004
|
3 |
|
|
* Copyright (c) 1999-2000 Cisco, Inc.
|
4 |
|
|
* Copyright (c) 1999-2001 Motorola, Inc.
|
5 |
|
|
* Copyright (c) 2001-2002 Intel Corp.
|
6 |
|
|
* Copyright (c) 2002 Nokia Corp.
|
7 |
|
|
*
|
8 |
|
|
* This file is part of the SCTP kernel reference Implementation
|
9 |
|
|
*
|
10 |
|
|
* This is part of the SCTP Linux Kernel Reference Implementation.
|
11 |
|
|
*
|
12 |
|
|
* These are the state functions for the state machine.
|
13 |
|
|
*
|
14 |
|
|
* The SCTP reference implementation is free software;
|
15 |
|
|
* you can redistribute it and/or modify it under the terms of
|
16 |
|
|
* the GNU General Public License as published by
|
17 |
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
18 |
|
|
* any later version.
|
19 |
|
|
*
|
20 |
|
|
* The SCTP reference implementation is distributed in the hope that it
|
21 |
|
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
22 |
|
|
* ************************
|
23 |
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
24 |
|
|
* See the GNU General Public License for more details.
|
25 |
|
|
*
|
26 |
|
|
* You should have received a copy of the GNU General Public License
|
27 |
|
|
* along with GNU CC; see the file COPYING. If not, write to
|
28 |
|
|
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
29 |
|
|
* Boston, MA 02111-1307, USA.
|
30 |
|
|
*
|
31 |
|
|
* Please send any bug reports or fixes you make to the
|
32 |
|
|
* email address(es):
|
33 |
|
|
* lksctp developers <lksctp-developers@lists.sourceforge.net>
|
34 |
|
|
*
|
35 |
|
|
* Or submit a bug report through the following website:
|
36 |
|
|
* http://www.sf.net/projects/lksctp
|
37 |
|
|
*
|
38 |
|
|
* Written or modified by:
|
39 |
|
|
* La Monte H.P. Yarroll <piggy@acm.org>
|
40 |
|
|
* Karl Knutson <karl@athena.chicago.il.us>
|
41 |
|
|
* Mathew Kotowsky <kotowsky@sctp.org>
|
42 |
|
|
* Sridhar Samudrala <samudrala@us.ibm.com>
|
43 |
|
|
* Jon Grimm <jgrimm@us.ibm.com>
|
44 |
|
|
* Hui Huang <hui.huang@nokia.com>
|
45 |
|
|
* Dajiang Zhang <dajiang.zhang@nokia.com>
|
46 |
|
|
* Daisy Chang <daisyc@us.ibm.com>
|
47 |
|
|
* Ardelle Fan <ardelle.fan@intel.com>
|
48 |
|
|
* Ryan Layer <rmlayer@us.ibm.com>
|
49 |
|
|
* Kevin Gao <kevin.gao@intel.com>
|
50 |
|
|
*
|
51 |
|
|
* Any bugs reported given to us we will try to fix... any fixes shared will
|
52 |
|
|
* be incorporated into the next SCTP release.
|
53 |
|
|
*/
|
54 |
|
|
|
55 |
|
|
#include <linux/types.h>
|
56 |
|
|
#include <linux/kernel.h>
|
57 |
|
|
#include <linux/ip.h>
|
58 |
|
|
#include <linux/ipv6.h>
|
59 |
|
|
#include <linux/net.h>
|
60 |
|
|
#include <linux/inet.h>
|
61 |
|
|
#include <net/sock.h>
|
62 |
|
|
#include <net/inet_ecn.h>
|
63 |
|
|
#include <linux/skbuff.h>
|
64 |
|
|
#include <net/sctp/sctp.h>
|
65 |
|
|
#include <net/sctp/sm.h>
|
66 |
|
|
#include <net/sctp/structs.h>
|
67 |
|
|
|
68 |
|
|
/**********************************************************
|
69 |
|
|
* These are the state functions for handling chunk events.
|
70 |
|
|
**********************************************************/
|
71 |
|
|
|
72 |
|
|
/*
|
73 |
|
|
* Process the final SHUTDOWN COMPLETE.
|
74 |
|
|
*
|
75 |
|
|
* Section: 4 (C) (diagram), 9.2
|
76 |
|
|
* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint will verify
|
77 |
|
|
* that it is in SHUTDOWN-ACK-SENT state, if it is not the chunk should be
|
78 |
|
|
* discarded. If the endpoint is in the SHUTDOWN-ACK-SENT state the endpoint
|
79 |
|
|
* should stop the T2-shutdown timer and remove all knowledge of the
|
80 |
|
|
* association (and thus the association enters the CLOSED state).
|
81 |
|
|
*
|
82 |
|
|
* Verification Tag: 8.5.1(C)
|
83 |
|
|
* C) Rules for packet carrying SHUTDOWN COMPLETE:
|
84 |
|
|
* ...
|
85 |
|
|
* - The receiver of a SHUTDOWN COMPLETE shall accept the packet if the
|
86 |
|
|
* Verification Tag field of the packet matches its own tag OR it is
|
87 |
|
|
* set to its peer's tag and the T bit is set in the Chunk Flags.
|
88 |
|
|
* Otherwise, the receiver MUST silently discard the packet and take
|
89 |
|
|
* no further action. An endpoint MUST ignore the SHUTDOWN COMPLETE if
|
90 |
|
|
* it is not in the SHUTDOWN-ACK-SENT state.
|
91 |
|
|
*
|
92 |
|
|
* Inputs
|
93 |
|
|
* (endpoint, asoc, chunk)
|
94 |
|
|
*
|
95 |
|
|
* Outputs
|
96 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
97 |
|
|
*
|
98 |
|
|
* The return value is the disposition of the chunk.
|
99 |
|
|
*/
|
100 |
|
|
sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
|
101 |
|
|
const struct sctp_association *asoc,
|
102 |
|
|
const sctp_subtype_t type,
|
103 |
|
|
void *arg,
|
104 |
|
|
sctp_cmd_seq_t *commands)
|
105 |
|
|
{
|
106 |
|
|
struct sctp_chunk *chunk = arg;
|
107 |
|
|
struct sctp_ulpevent *ev;
|
108 |
|
|
|
109 |
|
|
/* RFC 2960 6.10 Bundling
|
110 |
|
|
*
|
111 |
|
|
* An endpoint MUST NOT bundle INIT, INIT ACK or
|
112 |
|
|
* SHUTDOWN COMPLETE with any other chunks.
|
113 |
|
|
*/
|
114 |
|
|
if (!chunk->singleton)
|
115 |
|
|
return SCTP_DISPOSITION_VIOLATION;
|
116 |
|
|
|
117 |
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
118 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
119 |
|
|
|
120 |
|
|
/* RFC 2960 10.2 SCTP-to-ULP
|
121 |
|
|
*
|
122 |
|
|
* H) SHUTDOWN COMPLETE notification
|
123 |
|
|
*
|
124 |
|
|
* When SCTP completes the shutdown procedures (section 9.2) this
|
125 |
|
|
* notification is passed to the upper layer.
|
126 |
|
|
*/
|
127 |
|
|
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
|
128 |
|
|
0, 0, 0, GFP_ATOMIC);
|
129 |
|
|
if (!ev)
|
130 |
|
|
goto nomem;
|
131 |
|
|
|
132 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
133 |
|
|
|
134 |
|
|
/* Upon reception of the SHUTDOWN COMPLETE chunk the endpoint
|
135 |
|
|
* will verify that it is in SHUTDOWN-ACK-SENT state, if it is
|
136 |
|
|
* not the chunk should be discarded. If the endpoint is in
|
137 |
|
|
* the SHUTDOWN-ACK-SENT state the endpoint should stop the
|
138 |
|
|
* T2-shutdown timer and remove all knowledge of the
|
139 |
|
|
* association (and thus the association enters the CLOSED
|
140 |
|
|
* state).
|
141 |
|
|
*/
|
142 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
143 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
144 |
|
|
|
145 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
146 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
147 |
|
|
|
148 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
149 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
150 |
|
|
|
151 |
|
|
SCTP_INC_STATS(SctpShutdowns);
|
152 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
153 |
|
|
|
154 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
155 |
|
|
|
156 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
157 |
|
|
|
158 |
|
|
nomem:
|
159 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
160 |
|
|
}
|
161 |
|
|
|
162 |
|
|
/*
|
163 |
|
|
* Respond to a normal INIT chunk.
|
164 |
|
|
* We are the side that is being asked for an association.
|
165 |
|
|
*
|
166 |
|
|
* Section: 5.1 Normal Establishment of an Association, B
|
167 |
|
|
* B) "Z" shall respond immediately with an INIT ACK chunk. The
|
168 |
|
|
* destination IP address of the INIT ACK MUST be set to the source
|
169 |
|
|
* IP address of the INIT to which this INIT ACK is responding. In
|
170 |
|
|
* the response, besides filling in other parameters, "Z" must set the
|
171 |
|
|
* Verification Tag field to Tag_A, and also provide its own
|
172 |
|
|
* Verification Tag (Tag_Z) in the Initiate Tag field.
|
173 |
|
|
*
|
174 |
|
|
* Verification Tag: No checking.
|
175 |
|
|
*
|
176 |
|
|
* Inputs
|
177 |
|
|
* (endpoint, asoc, chunk)
|
178 |
|
|
*
|
179 |
|
|
* Outputs
|
180 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
181 |
|
|
*
|
182 |
|
|
* The return value is the disposition of the chunk.
|
183 |
|
|
*/
|
184 |
|
|
sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
|
185 |
|
|
const struct sctp_association *asoc,
|
186 |
|
|
const sctp_subtype_t type,
|
187 |
|
|
void *arg,
|
188 |
|
|
sctp_cmd_seq_t *commands)
|
189 |
|
|
{
|
190 |
|
|
struct sctp_chunk *chunk = arg;
|
191 |
|
|
struct sctp_chunk *repl;
|
192 |
|
|
struct sctp_association *new_asoc;
|
193 |
|
|
struct sctp_chunk *err_chunk;
|
194 |
|
|
struct sctp_packet *packet;
|
195 |
|
|
sctp_unrecognized_param_t *unk_param;
|
196 |
|
|
struct sock *sk;
|
197 |
|
|
int len;
|
198 |
|
|
|
199 |
|
|
/* 6.10 Bundling
|
200 |
|
|
* An endpoint MUST NOT bundle INIT, INIT ACK or
|
201 |
|
|
* SHUTDOWN COMPLETE with any other chunks.
|
202 |
|
|
*/
|
203 |
|
|
if (!chunk->singleton)
|
204 |
|
|
return SCTP_DISPOSITION_VIOLATION;
|
205 |
|
|
|
206 |
|
|
/* If the packet is an OOTB packet which is temporarily on the
|
207 |
|
|
* control endpoint, respond with an ABORT.
|
208 |
|
|
*/
|
209 |
|
|
if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
|
210 |
|
|
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
|
211 |
|
|
|
212 |
|
|
sk = ep->base.sk;
|
213 |
|
|
/* If the endpoint is not listening or if the number of associations
|
214 |
|
|
* on the TCP-style socket exceed the max backlog, respond with an
|
215 |
|
|
* ABORT.
|
216 |
|
|
*/
|
217 |
|
|
if (!sctp_sstate(sk, LISTENING) ||
|
218 |
|
|
(sctp_style(sk, TCP) &&
|
219 |
|
|
(sk->sk_ack_backlog >= sk->sk_max_ack_backlog)))
|
220 |
|
|
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
|
221 |
|
|
|
222 |
|
|
/* Verify the INIT chunk before processing it. */
|
223 |
|
|
err_chunk = NULL;
|
224 |
|
|
if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
|
225 |
|
|
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
|
226 |
|
|
&err_chunk)) {
|
227 |
|
|
/* This chunk contains fatal error. It is to be discarded.
|
228 |
|
|
* Send an ABORT, with causes if there is any.
|
229 |
|
|
*/
|
230 |
|
|
if (err_chunk) {
|
231 |
|
|
packet = sctp_abort_pkt_new(ep, asoc, arg,
|
232 |
|
|
(__u8 *)(err_chunk->chunk_hdr) +
|
233 |
|
|
sizeof(sctp_chunkhdr_t),
|
234 |
|
|
ntohs(err_chunk->chunk_hdr->length) -
|
235 |
|
|
sizeof(sctp_chunkhdr_t));
|
236 |
|
|
|
237 |
|
|
sctp_chunk_free(err_chunk);
|
238 |
|
|
|
239 |
|
|
if (packet) {
|
240 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
241 |
|
|
SCTP_PACKET(packet));
|
242 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
243 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
244 |
|
|
} else {
|
245 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
246 |
|
|
}
|
247 |
|
|
} else {
|
248 |
|
|
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
|
249 |
|
|
commands);
|
250 |
|
|
}
|
251 |
|
|
}
|
252 |
|
|
|
253 |
|
|
/* Grab the INIT header. */
|
254 |
|
|
chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
|
255 |
|
|
|
256 |
|
|
/* Tag the variable length parameters. */
|
257 |
|
|
chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
|
258 |
|
|
|
259 |
|
|
new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
|
260 |
|
|
if (!new_asoc)
|
261 |
|
|
goto nomem;
|
262 |
|
|
|
263 |
|
|
/* The call, sctp_process_init(), can fail on memory allocation. */
|
264 |
|
|
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
|
265 |
|
|
sctp_source(chunk),
|
266 |
|
|
(sctp_init_chunk_t *)chunk->chunk_hdr,
|
267 |
|
|
GFP_ATOMIC))
|
268 |
|
|
goto nomem_init;
|
269 |
|
|
|
270 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
|
271 |
|
|
|
272 |
|
|
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
|
273 |
|
|
|
274 |
|
|
/* If there are errors need to be reported for unknown parameters,
|
275 |
|
|
* make sure to reserve enough room in the INIT ACK for them.
|
276 |
|
|
*/
|
277 |
|
|
len = 0;
|
278 |
|
|
if (err_chunk)
|
279 |
|
|
len = ntohs(err_chunk->chunk_hdr->length) -
|
280 |
|
|
sizeof(sctp_chunkhdr_t);
|
281 |
|
|
|
282 |
|
|
if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
|
283 |
|
|
goto nomem_ack;
|
284 |
|
|
|
285 |
|
|
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
|
286 |
|
|
if (!repl)
|
287 |
|
|
goto nomem_ack;
|
288 |
|
|
|
289 |
|
|
/* If there are errors need to be reported for unknown parameters,
|
290 |
|
|
* include them in the outgoing INIT ACK as "Unrecognized parameter"
|
291 |
|
|
* parameter.
|
292 |
|
|
*/
|
293 |
|
|
if (err_chunk) {
|
294 |
|
|
/* Get the "Unrecognized parameter" parameter(s) out of the
|
295 |
|
|
* ERROR chunk generated by sctp_verify_init(). Since the
|
296 |
|
|
* error cause code for "unknown parameter" and the
|
297 |
|
|
* "Unrecognized parameter" type is the same, we can
|
298 |
|
|
* construct the parameters in INIT ACK by copying the
|
299 |
|
|
* ERROR causes over.
|
300 |
|
|
*/
|
301 |
|
|
unk_param = (sctp_unrecognized_param_t *)
|
302 |
|
|
((__u8 *)(err_chunk->chunk_hdr) +
|
303 |
|
|
sizeof(sctp_chunkhdr_t));
|
304 |
|
|
/* Replace the cause code with the "Unrecognized parameter"
|
305 |
|
|
* parameter type.
|
306 |
|
|
*/
|
307 |
|
|
sctp_addto_chunk(repl, len, unk_param);
|
308 |
|
|
sctp_chunk_free(err_chunk);
|
309 |
|
|
}
|
310 |
|
|
|
311 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
312 |
|
|
|
313 |
|
|
/*
|
314 |
|
|
* Note: After sending out INIT ACK with the State Cookie parameter,
|
315 |
|
|
* "Z" MUST NOT allocate any resources, nor keep any states for the
|
316 |
|
|
* new association. Otherwise, "Z" will be vulnerable to resource
|
317 |
|
|
* attacks.
|
318 |
|
|
*/
|
319 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
320 |
|
|
|
321 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
322 |
|
|
|
323 |
|
|
nomem_ack:
|
324 |
|
|
if (err_chunk)
|
325 |
|
|
sctp_chunk_free(err_chunk);
|
326 |
|
|
nomem_init:
|
327 |
|
|
sctp_association_free(new_asoc);
|
328 |
|
|
nomem:
|
329 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
330 |
|
|
}
|
331 |
|
|
|
332 |
|
|
/*
|
333 |
|
|
* Respond to a normal INIT ACK chunk.
|
334 |
|
|
* We are the side that is initiating the association.
|
335 |
|
|
*
|
336 |
|
|
* Section: 5.1 Normal Establishment of an Association, C
|
337 |
|
|
* C) Upon reception of the INIT ACK from "Z", "A" shall stop the T1-init
|
338 |
|
|
* timer and leave COOKIE-WAIT state. "A" shall then send the State
|
339 |
|
|
* Cookie received in the INIT ACK chunk in a COOKIE ECHO chunk, start
|
340 |
|
|
* the T1-cookie timer, and enter the COOKIE-ECHOED state.
|
341 |
|
|
*
|
342 |
|
|
* Note: The COOKIE ECHO chunk can be bundled with any pending outbound
|
343 |
|
|
* DATA chunks, but it MUST be the first chunk in the packet and
|
344 |
|
|
* until the COOKIE ACK is returned the sender MUST NOT send any
|
345 |
|
|
* other packets to the peer.
|
346 |
|
|
*
|
347 |
|
|
* Verification Tag: 3.3.3
|
348 |
|
|
* If the value of the Initiate Tag in a received INIT ACK chunk is
|
349 |
|
|
* found to be 0, the receiver MUST treat it as an error and close the
|
350 |
|
|
* association by transmitting an ABORT.
|
351 |
|
|
*
|
352 |
|
|
* Inputs
|
353 |
|
|
* (endpoint, asoc, chunk)
|
354 |
|
|
*
|
355 |
|
|
* Outputs
|
356 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
357 |
|
|
*
|
358 |
|
|
* The return value is the disposition of the chunk.
|
359 |
|
|
*/
|
360 |
|
|
sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
|
361 |
|
|
const struct sctp_association *asoc,
|
362 |
|
|
const sctp_subtype_t type,
|
363 |
|
|
void *arg,
|
364 |
|
|
sctp_cmd_seq_t *commands)
|
365 |
|
|
{
|
366 |
|
|
struct sctp_chunk *chunk = arg;
|
367 |
|
|
sctp_init_chunk_t *initchunk;
|
368 |
|
|
__u32 init_tag;
|
369 |
|
|
struct sctp_chunk *err_chunk;
|
370 |
|
|
struct sctp_packet *packet;
|
371 |
|
|
sctp_disposition_t ret;
|
372 |
|
|
|
373 |
|
|
/* 6.10 Bundling
|
374 |
|
|
* An endpoint MUST NOT bundle INIT, INIT ACK or
|
375 |
|
|
* SHUTDOWN COMPLETE with any other chunks.
|
376 |
|
|
*/
|
377 |
|
|
if (!chunk->singleton)
|
378 |
|
|
return SCTP_DISPOSITION_VIOLATION;
|
379 |
|
|
|
380 |
|
|
/* Grab the INIT header. */
|
381 |
|
|
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
|
382 |
|
|
|
383 |
|
|
init_tag = ntohl(chunk->subh.init_hdr->init_tag);
|
384 |
|
|
|
385 |
|
|
/* Verification Tag: 3.3.3
|
386 |
|
|
* If the value of the Initiate Tag in a received INIT ACK
|
387 |
|
|
* chunk is found to be 0, the receiver MUST treat it as an
|
388 |
|
|
* error and close the association by transmitting an ABORT.
|
389 |
|
|
*/
|
390 |
|
|
if (!init_tag) {
|
391 |
|
|
struct sctp_chunk *reply = sctp_make_abort(asoc, chunk, 0);
|
392 |
|
|
if (!reply)
|
393 |
|
|
goto nomem;
|
394 |
|
|
|
395 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
396 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
397 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
398 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
399 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
400 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
401 |
|
|
}
|
402 |
|
|
|
403 |
|
|
/* Verify the INIT chunk before processing it. */
|
404 |
|
|
err_chunk = NULL;
|
405 |
|
|
if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
|
406 |
|
|
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
|
407 |
|
|
&err_chunk)) {
|
408 |
|
|
|
409 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
410 |
|
|
|
411 |
|
|
/* This chunk contains fatal error. It is to be discarded.
|
412 |
|
|
* Send an ABORT, with causes if there is any.
|
413 |
|
|
*/
|
414 |
|
|
if (err_chunk) {
|
415 |
|
|
packet = sctp_abort_pkt_new(ep, asoc, arg,
|
416 |
|
|
(__u8 *)(err_chunk->chunk_hdr) +
|
417 |
|
|
sizeof(sctp_chunkhdr_t),
|
418 |
|
|
ntohs(err_chunk->chunk_hdr->length) -
|
419 |
|
|
sizeof(sctp_chunkhdr_t));
|
420 |
|
|
|
421 |
|
|
sctp_chunk_free(err_chunk);
|
422 |
|
|
|
423 |
|
|
if (packet) {
|
424 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
425 |
|
|
SCTP_PACKET(packet));
|
426 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
427 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
428 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
429 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
|
430 |
|
|
SCTP_NULL());
|
431 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
432 |
|
|
} else {
|
433 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
434 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
435 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
|
436 |
|
|
SCTP_NULL());
|
437 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
438 |
|
|
}
|
439 |
|
|
} else {
|
440 |
|
|
ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
|
441 |
|
|
commands);
|
442 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
443 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
444 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
|
445 |
|
|
SCTP_NULL());
|
446 |
|
|
return ret;
|
447 |
|
|
}
|
448 |
|
|
}
|
449 |
|
|
|
450 |
|
|
/* Tag the variable length parameters. Note that we never
|
451 |
|
|
* convert the parameters in an INIT chunk.
|
452 |
|
|
*/
|
453 |
|
|
chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
|
454 |
|
|
|
455 |
|
|
initchunk = (sctp_init_chunk_t *) chunk->chunk_hdr;
|
456 |
|
|
|
457 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
|
458 |
|
|
SCTP_PEER_INIT(initchunk));
|
459 |
|
|
|
460 |
|
|
/* 5.1 C) "A" shall stop the T1-init timer and leave
|
461 |
|
|
* COOKIE-WAIT state. "A" shall then ... start the T1-cookie
|
462 |
|
|
* timer, and enter the COOKIE-ECHOED state.
|
463 |
|
|
*/
|
464 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
465 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
466 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,
|
467 |
|
|
SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
|
468 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
469 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
|
470 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
471 |
|
|
SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));
|
472 |
|
|
|
473 |
|
|
/* 5.1 C) "A" shall then send the State Cookie received in the
|
474 |
|
|
* INIT ACK chunk in a COOKIE ECHO chunk, ...
|
475 |
|
|
*/
|
476 |
|
|
/* If there is any errors to report, send the ERROR chunk generated
|
477 |
|
|
* for unknown parameters as well.
|
478 |
|
|
*/
|
479 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO,
|
480 |
|
|
SCTP_CHUNK(err_chunk));
|
481 |
|
|
|
482 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
483 |
|
|
|
484 |
|
|
nomem:
|
485 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
486 |
|
|
}
|
487 |
|
|
|
488 |
|
|
/*
|
489 |
|
|
* Respond to a normal COOKIE ECHO chunk.
|
490 |
|
|
* We are the side that is being asked for an association.
|
491 |
|
|
*
|
492 |
|
|
* Section: 5.1 Normal Establishment of an Association, D
|
493 |
|
|
* D) Upon reception of the COOKIE ECHO chunk, Endpoint "Z" will reply
|
494 |
|
|
* with a COOKIE ACK chunk after building a TCB and moving to
|
495 |
|
|
* the ESTABLISHED state. A COOKIE ACK chunk may be bundled with
|
496 |
|
|
* any pending DATA chunks (and/or SACK chunks), but the COOKIE ACK
|
497 |
|
|
* chunk MUST be the first chunk in the packet.
|
498 |
|
|
*
|
499 |
|
|
* IMPLEMENTATION NOTE: An implementation may choose to send the
|
500 |
|
|
* Communication Up notification to the SCTP user upon reception
|
501 |
|
|
* of a valid COOKIE ECHO chunk.
|
502 |
|
|
*
|
503 |
|
|
* Verification Tag: 8.5.1 Exceptions in Verification Tag Rules
|
504 |
|
|
* D) Rules for packet carrying a COOKIE ECHO
|
505 |
|
|
*
|
506 |
|
|
* - When sending a COOKIE ECHO, the endpoint MUST use the value of the
|
507 |
|
|
* Initial Tag received in the INIT ACK.
|
508 |
|
|
*
|
509 |
|
|
* - The receiver of a COOKIE ECHO follows the procedures in Section 5.
|
510 |
|
|
*
|
511 |
|
|
* Inputs
|
512 |
|
|
* (endpoint, asoc, chunk)
|
513 |
|
|
*
|
514 |
|
|
* Outputs
|
515 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
516 |
|
|
*
|
517 |
|
|
* The return value is the disposition of the chunk.
|
518 |
|
|
*/
|
519 |
|
|
sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
|
520 |
|
|
const struct sctp_association *asoc,
|
521 |
|
|
const sctp_subtype_t type, void *arg,
|
522 |
|
|
sctp_cmd_seq_t *commands)
|
523 |
|
|
{
|
524 |
|
|
struct sctp_chunk *chunk = arg;
|
525 |
|
|
struct sctp_association *new_asoc;
|
526 |
|
|
sctp_init_chunk_t *peer_init;
|
527 |
|
|
struct sctp_chunk *repl;
|
528 |
|
|
struct sctp_ulpevent *ev;
|
529 |
|
|
int error = 0;
|
530 |
|
|
struct sctp_chunk *err_chk_p;
|
531 |
|
|
|
532 |
|
|
/* If the packet is an OOTB packet which is temporarily on the
|
533 |
|
|
* control endpoint, respond with an ABORT.
|
534 |
|
|
*/
|
535 |
|
|
if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
|
536 |
|
|
return sctp_sf_ootb(ep, asoc, type, arg, commands);
|
537 |
|
|
|
538 |
|
|
/* "Decode" the chunk. We have no optional parameters so we
|
539 |
|
|
* are in good shape.
|
540 |
|
|
*/
|
541 |
|
|
chunk->subh.cookie_hdr =
|
542 |
|
|
(struct sctp_signed_cookie *)chunk->skb->data;
|
543 |
|
|
skb_pull(chunk->skb,
|
544 |
|
|
ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t));
|
545 |
|
|
|
546 |
|
|
/* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint
|
547 |
|
|
* "Z" will reply with a COOKIE ACK chunk after building a TCB
|
548 |
|
|
* and moving to the ESTABLISHED state.
|
549 |
|
|
*/
|
550 |
|
|
new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
|
551 |
|
|
&err_chk_p);
|
552 |
|
|
|
553 |
|
|
/* FIXME:
|
554 |
|
|
* If the re-build failed, what is the proper error path
|
555 |
|
|
* from here?
|
556 |
|
|
*
|
557 |
|
|
* [We should abort the association. --piggy]
|
558 |
|
|
*/
|
559 |
|
|
if (!new_asoc) {
|
560 |
|
|
/* FIXME: Several errors are possible. A bad cookie should
|
561 |
|
|
* be silently discarded, but think about logging it too.
|
562 |
|
|
*/
|
563 |
|
|
switch (error) {
|
564 |
|
|
case -SCTP_IERROR_NOMEM:
|
565 |
|
|
goto nomem;
|
566 |
|
|
|
567 |
|
|
case -SCTP_IERROR_STALE_COOKIE:
|
568 |
|
|
sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
|
569 |
|
|
err_chk_p);
|
570 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
571 |
|
|
|
572 |
|
|
case -SCTP_IERROR_BAD_SIG:
|
573 |
|
|
default:
|
574 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
575 |
|
|
};
|
576 |
|
|
}
|
577 |
|
|
|
578 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
|
579 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
580 |
|
|
SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
581 |
|
|
SCTP_INC_STATS(SctpCurrEstab);
|
582 |
|
|
SCTP_INC_STATS(SctpPassiveEstabs);
|
583 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
|
584 |
|
|
|
585 |
|
|
if (new_asoc->autoclose)
|
586 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
587 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
|
588 |
|
|
|
589 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
|
590 |
|
|
|
591 |
|
|
/* Re-build the bind address for the association is done in
|
592 |
|
|
* the sctp_unpack_cookie() already.
|
593 |
|
|
*/
|
594 |
|
|
/* This is a brand-new association, so these are not yet side
|
595 |
|
|
* effects--it is safe to run them here.
|
596 |
|
|
*/
|
597 |
|
|
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
|
598 |
|
|
|
599 |
|
|
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
|
600 |
|
|
&chunk->subh.cookie_hdr->c.peer_addr,
|
601 |
|
|
peer_init, GFP_ATOMIC))
|
602 |
|
|
goto nomem_init;
|
603 |
|
|
|
604 |
|
|
repl = sctp_make_cookie_ack(new_asoc, chunk);
|
605 |
|
|
if (!repl)
|
606 |
|
|
goto nomem_repl;
|
607 |
|
|
|
608 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
609 |
|
|
|
610 |
|
|
/* RFC 2960 5.1 Normal Establishment of an Association
|
611 |
|
|
*
|
612 |
|
|
* D) IMPLEMENTATION NOTE: An implementation may choose to
|
613 |
|
|
* send the Communication Up notification to the SCTP user
|
614 |
|
|
* upon reception of a valid COOKIE ECHO chunk.
|
615 |
|
|
*/
|
616 |
|
|
ev = sctp_ulpevent_make_assoc_change(new_asoc, 0, SCTP_COMM_UP, 0,
|
617 |
|
|
new_asoc->c.sinit_num_ostreams,
|
618 |
|
|
new_asoc->c.sinit_max_instreams,
|
619 |
|
|
GFP_ATOMIC);
|
620 |
|
|
if (!ev)
|
621 |
|
|
goto nomem_ev;
|
622 |
|
|
|
623 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
624 |
|
|
|
625 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
626 |
|
|
|
627 |
|
|
nomem_ev:
|
628 |
|
|
sctp_chunk_free(repl);
|
629 |
|
|
nomem_repl:
|
630 |
|
|
nomem_init:
|
631 |
|
|
sctp_association_free(new_asoc);
|
632 |
|
|
nomem:
|
633 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
634 |
|
|
}
|
635 |
|
|
|
636 |
|
|
/*
|
637 |
|
|
* Respond to a normal COOKIE ACK chunk.
|
638 |
|
|
* We are the side that is being asked for an association.
|
639 |
|
|
*
|
640 |
|
|
* RFC 2960 5.1 Normal Establishment of an Association
|
641 |
|
|
*
|
642 |
|
|
* E) Upon reception of the COOKIE ACK, endpoint "A" will move from the
|
643 |
|
|
* COOKIE-ECHOED state to the ESTABLISHED state, stopping the T1-cookie
|
644 |
|
|
* timer. It may also notify its ULP about the successful
|
645 |
|
|
* establishment of the association with a Communication Up
|
646 |
|
|
* notification (see Section 10).
|
647 |
|
|
*
|
648 |
|
|
* Verification Tag:
|
649 |
|
|
* Inputs
|
650 |
|
|
* (endpoint, asoc, chunk)
|
651 |
|
|
*
|
652 |
|
|
* Outputs
|
653 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
654 |
|
|
*
|
655 |
|
|
* The return value is the disposition of the chunk.
|
656 |
|
|
*/
|
657 |
|
|
sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
|
658 |
|
|
const struct sctp_association *asoc,
|
659 |
|
|
const sctp_subtype_t type, void *arg,
|
660 |
|
|
sctp_cmd_seq_t *commands)
|
661 |
|
|
{
|
662 |
|
|
struct sctp_ulpevent *ev;
|
663 |
|
|
|
664 |
|
|
/* RFC 2960 5.1 Normal Establishment of an Association
|
665 |
|
|
*
|
666 |
|
|
* E) Upon reception of the COOKIE ACK, endpoint "A" will move
|
667 |
|
|
* from the COOKIE-ECHOED state to the ESTABLISHED state,
|
668 |
|
|
* stopping the T1-cookie timer.
|
669 |
|
|
*/
|
670 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
671 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
|
672 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
673 |
|
|
SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
674 |
|
|
SCTP_INC_STATS(SctpCurrEstab);
|
675 |
|
|
SCTP_INC_STATS(SctpActiveEstabs);
|
676 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
|
677 |
|
|
if (asoc->autoclose)
|
678 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
679 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
|
680 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
|
681 |
|
|
|
682 |
|
|
/* It may also notify its ULP about the successful
|
683 |
|
|
* establishment of the association with a Communication Up
|
684 |
|
|
* notification (see Section 10).
|
685 |
|
|
*/
|
686 |
|
|
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP,
|
687 |
|
|
0, asoc->c.sinit_num_ostreams,
|
688 |
|
|
asoc->c.sinit_max_instreams,
|
689 |
|
|
GFP_ATOMIC);
|
690 |
|
|
|
691 |
|
|
if (!ev)
|
692 |
|
|
goto nomem;
|
693 |
|
|
|
694 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
695 |
|
|
|
696 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
697 |
|
|
nomem:
|
698 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
699 |
|
|
}
|
700 |
|
|
|
701 |
|
|
/* Generate and sendout a heartbeat packet. */
|
702 |
|
|
sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
|
703 |
|
|
const struct sctp_association *asoc,
|
704 |
|
|
const sctp_subtype_t type,
|
705 |
|
|
void *arg,
|
706 |
|
|
sctp_cmd_seq_t *commands)
|
707 |
|
|
{
|
708 |
|
|
struct sctp_transport *transport = (struct sctp_transport *) arg;
|
709 |
|
|
struct sctp_chunk *reply;
|
710 |
|
|
sctp_sender_hb_info_t hbinfo;
|
711 |
|
|
size_t paylen = 0;
|
712 |
|
|
|
713 |
|
|
hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
|
714 |
|
|
hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
|
715 |
|
|
hbinfo.daddr = transport->ipaddr;
|
716 |
|
|
hbinfo.sent_at = jiffies;
|
717 |
|
|
|
718 |
|
|
/* Send a heartbeat to our peer. */
|
719 |
|
|
paylen = sizeof(sctp_sender_hb_info_t);
|
720 |
|
|
reply = sctp_make_heartbeat(asoc, transport, &hbinfo, paylen);
|
721 |
|
|
if (!reply)
|
722 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
723 |
|
|
|
724 |
|
|
/* Set rto_pending indicating that an RTT measurement
|
725 |
|
|
* is started with this heartbeat chunk.
|
726 |
|
|
*/
|
727 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_RTO_PENDING,
|
728 |
|
|
SCTP_TRANSPORT(transport));
|
729 |
|
|
|
730 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
731 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
732 |
|
|
}
|
733 |
|
|
|
734 |
|
|
/* Generate a HEARTBEAT packet on the given transport. */
|
735 |
|
|
sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
|
736 |
|
|
const struct sctp_association *asoc,
|
737 |
|
|
const sctp_subtype_t type,
|
738 |
|
|
void *arg,
|
739 |
|
|
sctp_cmd_seq_t *commands)
|
740 |
|
|
{
|
741 |
|
|
struct sctp_transport *transport = (struct sctp_transport *) arg;
|
742 |
|
|
|
743 |
|
|
if (asoc->overall_error_count > asoc->max_retrans) {
|
744 |
|
|
/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
|
745 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
746 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
747 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
748 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
749 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
750 |
|
|
}
|
751 |
|
|
|
752 |
|
|
/* Section 3.3.5.
|
753 |
|
|
* The Sender-specific Heartbeat Info field should normally include
|
754 |
|
|
* information about the sender's current time when this HEARTBEAT
|
755 |
|
|
* chunk is sent and the destination transport address to which this
|
756 |
|
|
* HEARTBEAT is sent (see Section 8.3).
|
757 |
|
|
*/
|
758 |
|
|
|
759 |
|
|
if (transport->hb_allowed) {
|
760 |
|
|
if (SCTP_DISPOSITION_NOMEM ==
|
761 |
|
|
sctp_sf_heartbeat(ep, asoc, type, arg,
|
762 |
|
|
commands))
|
763 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
764 |
|
|
/* Set transport error counter and association error counter
|
765 |
|
|
* when sending heartbeat.
|
766 |
|
|
*/
|
767 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
|
768 |
|
|
SCTP_TRANSPORT(transport));
|
769 |
|
|
}
|
770 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
|
771 |
|
|
SCTP_TRANSPORT(transport));
|
772 |
|
|
|
773 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
774 |
|
|
}
|
775 |
|
|
|
776 |
|
|
/*
|
777 |
|
|
* Process an heartbeat request.
|
778 |
|
|
*
|
779 |
|
|
* Section: 8.3 Path Heartbeat
|
780 |
|
|
* The receiver of the HEARTBEAT should immediately respond with a
|
781 |
|
|
* HEARTBEAT ACK that contains the Heartbeat Information field copied
|
782 |
|
|
* from the received HEARTBEAT chunk.
|
783 |
|
|
*
|
784 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
785 |
|
|
* When receiving an SCTP packet, the endpoint MUST ensure that the
|
786 |
|
|
* value in the Verification Tag field of the received SCTP packet
|
787 |
|
|
* matches its own Tag. If the received Verification Tag value does not
|
788 |
|
|
* match the receiver's own tag value, the receiver shall silently
|
789 |
|
|
* discard the packet and shall not process it any further except for
|
790 |
|
|
* those cases listed in Section 8.5.1 below.
|
791 |
|
|
*
|
792 |
|
|
* Inputs
|
793 |
|
|
* (endpoint, asoc, chunk)
|
794 |
|
|
*
|
795 |
|
|
* Outputs
|
796 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
797 |
|
|
*
|
798 |
|
|
* The return value is the disposition of the chunk.
|
799 |
|
|
*/
|
800 |
|
|
sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
|
801 |
|
|
const struct sctp_association *asoc,
|
802 |
|
|
const sctp_subtype_t type,
|
803 |
|
|
void *arg,
|
804 |
|
|
sctp_cmd_seq_t *commands)
|
805 |
|
|
{
|
806 |
|
|
struct sctp_chunk *chunk = arg;
|
807 |
|
|
struct sctp_chunk *reply;
|
808 |
|
|
size_t paylen = 0;
|
809 |
|
|
|
810 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
811 |
|
|
* that the value in the Verification Tag field of the
|
812 |
|
|
* received SCTP packet matches its own Tag. If the received
|
813 |
|
|
* Verification Tag value does not match the receiver's own
|
814 |
|
|
* tag value, the receiver shall silently discard the packet...
|
815 |
|
|
*/
|
816 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
817 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
818 |
|
|
|
819 |
|
|
/* 8.3 The receiver of the HEARTBEAT should immediately
|
820 |
|
|
* respond with a HEARTBEAT ACK that contains the Heartbeat
|
821 |
|
|
* Information field copied from the received HEARTBEAT chunk.
|
822 |
|
|
*/
|
823 |
|
|
chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data;
|
824 |
|
|
paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t);
|
825 |
|
|
skb_pull(chunk->skb, paylen);
|
826 |
|
|
|
827 |
|
|
reply = sctp_make_heartbeat_ack(asoc, chunk,
|
828 |
|
|
chunk->subh.hb_hdr, paylen);
|
829 |
|
|
if (!reply)
|
830 |
|
|
goto nomem;
|
831 |
|
|
|
832 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
833 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
834 |
|
|
|
835 |
|
|
nomem:
|
836 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
837 |
|
|
}
|
838 |
|
|
|
839 |
|
|
/*
|
840 |
|
|
* Process the returning HEARTBEAT ACK.
|
841 |
|
|
*
|
842 |
|
|
* Section: 8.3 Path Heartbeat
|
843 |
|
|
* Upon the receipt of the HEARTBEAT ACK, the sender of the HEARTBEAT
|
844 |
|
|
* should clear the error counter of the destination transport
|
845 |
|
|
* address to which the HEARTBEAT was sent, and mark the destination
|
846 |
|
|
* transport address as active if it is not so marked. The endpoint may
|
847 |
|
|
* optionally report to the upper layer when an inactive destination
|
848 |
|
|
* address is marked as active due to the reception of the latest
|
849 |
|
|
* HEARTBEAT ACK. The receiver of the HEARTBEAT ACK must also
|
850 |
|
|
* clear the association overall error count as well (as defined
|
851 |
|
|
* in section 8.1).
|
852 |
|
|
*
|
853 |
|
|
* The receiver of the HEARTBEAT ACK should also perform an RTT
|
854 |
|
|
* measurement for that destination transport address using the time
|
855 |
|
|
* value carried in the HEARTBEAT ACK chunk.
|
856 |
|
|
*
|
857 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
858 |
|
|
*
|
859 |
|
|
* Inputs
|
860 |
|
|
* (endpoint, asoc, chunk)
|
861 |
|
|
*
|
862 |
|
|
* Outputs
|
863 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
864 |
|
|
*
|
865 |
|
|
* The return value is the disposition of the chunk.
|
866 |
|
|
*/
|
867 |
|
|
sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
|
868 |
|
|
const struct sctp_association *asoc,
|
869 |
|
|
const sctp_subtype_t type,
|
870 |
|
|
void *arg,
|
871 |
|
|
sctp_cmd_seq_t *commands)
|
872 |
|
|
{
|
873 |
|
|
struct sctp_chunk *chunk = arg;
|
874 |
|
|
union sctp_addr from_addr;
|
875 |
|
|
struct sctp_transport *link;
|
876 |
|
|
sctp_sender_hb_info_t *hbinfo;
|
877 |
|
|
unsigned long max_interval;
|
878 |
|
|
|
879 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
880 |
|
|
* that the value in the Verification Tag field of the
|
881 |
|
|
* received SCTP packet matches its own Tag. ...
|
882 |
|
|
*/
|
883 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
884 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
885 |
|
|
|
886 |
|
|
hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
|
887 |
|
|
from_addr = hbinfo->daddr;
|
888 |
|
|
link = sctp_assoc_lookup_paddr(asoc, &from_addr);
|
889 |
|
|
|
890 |
|
|
/* This should never happen, but lets log it if so. */
|
891 |
|
|
if (!link) {
|
892 |
|
|
printk(KERN_WARNING
|
893 |
|
|
"%s: Could not find address %d.%d.%d.%d\n",
|
894 |
|
|
__FUNCTION__, NIPQUAD(from_addr.v4.sin_addr));
|
895 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
896 |
|
|
}
|
897 |
|
|
|
898 |
|
|
max_interval = link->hb_interval + link->rto;
|
899 |
|
|
|
900 |
|
|
/* Check if the timestamp looks valid. */
|
901 |
|
|
if (time_after(hbinfo->sent_at, jiffies) ||
|
902 |
|
|
time_after(jiffies, hbinfo->sent_at + max_interval)) {
|
903 |
|
|
SCTP_DEBUG_PRINTK("%s: HEARTBEAT ACK with invalid timestamp"
|
904 |
|
|
"received for transport: %p\n",
|
905 |
|
|
__FUNCTION__, link);
|
906 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
907 |
|
|
}
|
908 |
|
|
|
909 |
|
|
/* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of
|
910 |
|
|
* the HEARTBEAT should clear the error counter of the
|
911 |
|
|
* destination transport address to which the HEARTBEAT was
|
912 |
|
|
* sent and mark the destination transport address as active if
|
913 |
|
|
* it is not so marked.
|
914 |
|
|
*/
|
915 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_ON, SCTP_TRANSPORT(link));
|
916 |
|
|
|
917 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
918 |
|
|
}
|
919 |
|
|
|
920 |
|
|
/* Helper function to send out an abort for the restart
|
921 |
|
|
* condition.
|
922 |
|
|
*/
|
923 |
|
|
static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
|
924 |
|
|
struct sctp_chunk *init,
|
925 |
|
|
sctp_cmd_seq_t *commands)
|
926 |
|
|
{
|
927 |
|
|
int len;
|
928 |
|
|
struct sctp_packet *pkt;
|
929 |
|
|
union sctp_addr_param *addrparm;
|
930 |
|
|
struct sctp_errhdr *errhdr;
|
931 |
|
|
struct sctp_endpoint *ep;
|
932 |
|
|
char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
|
933 |
|
|
struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
|
934 |
|
|
|
935 |
|
|
/* Build the error on the stack. We are way to malloc crazy
|
936 |
|
|
* throughout the code today.
|
937 |
|
|
*/
|
938 |
|
|
errhdr = (struct sctp_errhdr *)buffer;
|
939 |
|
|
addrparm = (union sctp_addr_param *)errhdr->variable;
|
940 |
|
|
|
941 |
|
|
/* Copy into a parm format. */
|
942 |
|
|
len = af->to_addr_param(ssa, addrparm);
|
943 |
|
|
len += sizeof(sctp_errhdr_t);
|
944 |
|
|
|
945 |
|
|
errhdr->cause = SCTP_ERROR_RESTART;
|
946 |
|
|
errhdr->length = htons(len);
|
947 |
|
|
|
948 |
|
|
/* Assign to the control socket. */
|
949 |
|
|
ep = sctp_sk((sctp_get_ctl_sock()))->ep;
|
950 |
|
|
|
951 |
|
|
/* Association is NULL since this may be a restart attack and we
|
952 |
|
|
* want to send back the attacker's vtag.
|
953 |
|
|
*/
|
954 |
|
|
pkt = sctp_abort_pkt_new(ep, NULL, init, errhdr, len);
|
955 |
|
|
|
956 |
|
|
if (!pkt)
|
957 |
|
|
goto out;
|
958 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(pkt));
|
959 |
|
|
|
960 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
961 |
|
|
|
962 |
|
|
/* Discard the rest of the inbound packet. */
|
963 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
|
964 |
|
|
|
965 |
|
|
out:
|
966 |
|
|
/* Even if there is no memory, treat as a failure so
|
967 |
|
|
* the packet will get dropped.
|
968 |
|
|
*/
|
969 |
|
|
return 0;
|
970 |
|
|
}
|
971 |
|
|
|
972 |
|
|
/* A restart is occurring, check to make sure no new addresses
|
973 |
|
|
* are being added as we may be under a takeover attack.
|
974 |
|
|
*/
|
975 |
|
|
static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
|
976 |
|
|
const struct sctp_association *asoc,
|
977 |
|
|
struct sctp_chunk *init,
|
978 |
|
|
sctp_cmd_seq_t *commands)
|
979 |
|
|
{
|
980 |
|
|
struct sctp_transport *new_addr, *addr;
|
981 |
|
|
struct list_head *pos, *pos2;
|
982 |
|
|
int found;
|
983 |
|
|
|
984 |
|
|
/* Implementor's Guide - Sectin 5.2.2
|
985 |
|
|
* ...
|
986 |
|
|
* Before responding the endpoint MUST check to see if the
|
987 |
|
|
* unexpected INIT adds new addresses to the association. If new
|
988 |
|
|
* addresses are added to the association, the endpoint MUST respond
|
989 |
|
|
* with an ABORT..
|
990 |
|
|
*/
|
991 |
|
|
|
992 |
|
|
/* Search through all current addresses and make sure
|
993 |
|
|
* we aren't adding any new ones.
|
994 |
|
|
*/
|
995 |
|
|
new_addr = 0;
|
996 |
|
|
found = 0;
|
997 |
|
|
|
998 |
|
|
list_for_each(pos, &new_asoc->peer.transport_addr_list) {
|
999 |
|
|
new_addr = list_entry(pos, struct sctp_transport, transports);
|
1000 |
|
|
found = 0;
|
1001 |
|
|
list_for_each(pos2, &asoc->peer.transport_addr_list) {
|
1002 |
|
|
addr = list_entry(pos2, struct sctp_transport,
|
1003 |
|
|
transports);
|
1004 |
|
|
if (sctp_cmp_addr_exact(&new_addr->ipaddr,
|
1005 |
|
|
&addr->ipaddr)) {
|
1006 |
|
|
found = 1;
|
1007 |
|
|
break;
|
1008 |
|
|
}
|
1009 |
|
|
}
|
1010 |
|
|
if (!found)
|
1011 |
|
|
break;
|
1012 |
|
|
}
|
1013 |
|
|
|
1014 |
|
|
/* If a new address was added, ABORT the sender. */
|
1015 |
|
|
if (!found && new_addr) {
|
1016 |
|
|
sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands);
|
1017 |
|
|
}
|
1018 |
|
|
|
1019 |
|
|
/* Return success if all addresses were found. */
|
1020 |
|
|
return found;
|
1021 |
|
|
}
|
1022 |
|
|
|
1023 |
|
|
/* Populate the verification/tie tags based on overlapping INIT
|
1024 |
|
|
* scenario.
|
1025 |
|
|
*
|
1026 |
|
|
* Note: Do not use in CLOSED or SHUTDOWN-ACK-SENT state.
|
1027 |
|
|
*/
|
1028 |
|
|
static void sctp_tietags_populate(struct sctp_association *new_asoc,
|
1029 |
|
|
const struct sctp_association *asoc)
|
1030 |
|
|
{
|
1031 |
|
|
switch (asoc->state) {
|
1032 |
|
|
|
1033 |
|
|
/* 5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State */
|
1034 |
|
|
|
1035 |
|
|
case SCTP_STATE_COOKIE_WAIT:
|
1036 |
|
|
new_asoc->c.my_vtag = asoc->c.my_vtag;
|
1037 |
|
|
new_asoc->c.my_ttag = asoc->c.my_vtag;
|
1038 |
|
|
new_asoc->c.peer_ttag = 0;
|
1039 |
|
|
break;
|
1040 |
|
|
|
1041 |
|
|
case SCTP_STATE_COOKIE_ECHOED:
|
1042 |
|
|
new_asoc->c.my_vtag = asoc->c.my_vtag;
|
1043 |
|
|
new_asoc->c.my_ttag = asoc->c.my_vtag;
|
1044 |
|
|
new_asoc->c.peer_ttag = asoc->c.peer_vtag;
|
1045 |
|
|
break;
|
1046 |
|
|
|
1047 |
|
|
/* 5.2.2 Unexpected INIT in States Other than CLOSED, COOKIE-ECHOED,
|
1048 |
|
|
* COOKIE-WAIT and SHUTDOWN-ACK-SENT
|
1049 |
|
|
*/
|
1050 |
|
|
default:
|
1051 |
|
|
new_asoc->c.my_ttag = asoc->c.my_vtag;
|
1052 |
|
|
new_asoc->c.peer_ttag = asoc->c.peer_vtag;
|
1053 |
|
|
break;
|
1054 |
|
|
};
|
1055 |
|
|
|
1056 |
|
|
/* Other parameters for the endpoint SHOULD be copied from the
|
1057 |
|
|
* existing parameters of the association (e.g. number of
|
1058 |
|
|
* outbound streams) into the INIT ACK and cookie.
|
1059 |
|
|
*/
|
1060 |
|
|
new_asoc->rwnd = asoc->rwnd;
|
1061 |
|
|
new_asoc->c.sinit_num_ostreams = asoc->c.sinit_num_ostreams;
|
1062 |
|
|
new_asoc->c.sinit_max_instreams = asoc->c.sinit_max_instreams;
|
1063 |
|
|
new_asoc->c.initial_tsn = asoc->c.initial_tsn;
|
1064 |
|
|
}
|
1065 |
|
|
|
1066 |
|
|
/*
|
1067 |
|
|
* Compare vtag/tietag values to determine unexpected COOKIE-ECHO
|
1068 |
|
|
* handling action.
|
1069 |
|
|
*
|
1070 |
|
|
* RFC 2960 5.2.4 Handle a COOKIE ECHO when a TCB exists.
|
1071 |
|
|
*
|
1072 |
|
|
* Returns value representing action to be taken. These action values
|
1073 |
|
|
* correspond to Action/Description values in RFC 2960, Table 2.
|
1074 |
|
|
*/
|
1075 |
|
|
static char sctp_tietags_compare(struct sctp_association *new_asoc,
|
1076 |
|
|
const struct sctp_association *asoc)
|
1077 |
|
|
{
|
1078 |
|
|
/* In this case, the peer may have restarted. */
|
1079 |
|
|
if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
|
1080 |
|
|
(asoc->c.peer_vtag != new_asoc->c.peer_vtag) &&
|
1081 |
|
|
(asoc->c.my_vtag == new_asoc->c.my_ttag) &&
|
1082 |
|
|
(asoc->c.peer_vtag == new_asoc->c.peer_ttag))
|
1083 |
|
|
return 'A';
|
1084 |
|
|
|
1085 |
|
|
/* Collision case B. */
|
1086 |
|
|
if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
|
1087 |
|
|
((asoc->c.peer_vtag != new_asoc->c.peer_vtag) ||
|
1088 |
|
|
(0 == asoc->c.peer_vtag))) {
|
1089 |
|
|
return 'B';
|
1090 |
|
|
}
|
1091 |
|
|
|
1092 |
|
|
/* Collision case D. */
|
1093 |
|
|
if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
|
1094 |
|
|
(asoc->c.peer_vtag == new_asoc->c.peer_vtag))
|
1095 |
|
|
return 'D';
|
1096 |
|
|
|
1097 |
|
|
/* Collision case C. */
|
1098 |
|
|
if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
|
1099 |
|
|
(asoc->c.peer_vtag == new_asoc->c.peer_vtag) &&
|
1100 |
|
|
(0 == new_asoc->c.my_ttag) &&
|
1101 |
|
|
(0 == new_asoc->c.peer_ttag))
|
1102 |
|
|
return 'C';
|
1103 |
|
|
|
1104 |
|
|
/* No match to any of the special cases; discard this packet. */
|
1105 |
|
|
return 'E';
|
1106 |
|
|
}
|
1107 |
|
|
|
1108 |
|
|
/* Common helper routine for both duplicate and simulataneous INIT
|
1109 |
|
|
* chunk handling.
|
1110 |
|
|
*/
|
1111 |
|
|
static sctp_disposition_t sctp_sf_do_unexpected_init(
|
1112 |
|
|
const struct sctp_endpoint *ep,
|
1113 |
|
|
const struct sctp_association *asoc,
|
1114 |
|
|
const sctp_subtype_t type,
|
1115 |
|
|
void *arg, sctp_cmd_seq_t *commands)
|
1116 |
|
|
{
|
1117 |
|
|
sctp_disposition_t retval;
|
1118 |
|
|
struct sctp_chunk *chunk = arg;
|
1119 |
|
|
struct sctp_chunk *repl;
|
1120 |
|
|
struct sctp_association *new_asoc;
|
1121 |
|
|
struct sctp_chunk *err_chunk;
|
1122 |
|
|
struct sctp_packet *packet;
|
1123 |
|
|
sctp_unrecognized_param_t *unk_param;
|
1124 |
|
|
int len;
|
1125 |
|
|
|
1126 |
|
|
/* 6.10 Bundling
|
1127 |
|
|
* An endpoint MUST NOT bundle INIT, INIT ACK or
|
1128 |
|
|
* SHUTDOWN COMPLETE with any other chunks.
|
1129 |
|
|
*/
|
1130 |
|
|
if (!chunk->singleton)
|
1131 |
|
|
return SCTP_DISPOSITION_VIOLATION;
|
1132 |
|
|
|
1133 |
|
|
/* Grab the INIT header. */
|
1134 |
|
|
chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
|
1135 |
|
|
|
1136 |
|
|
/* Tag the variable length parameters. */
|
1137 |
|
|
chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
|
1138 |
|
|
|
1139 |
|
|
/* Verify the INIT chunk before processing it. */
|
1140 |
|
|
err_chunk = NULL;
|
1141 |
|
|
if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
|
1142 |
|
|
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
|
1143 |
|
|
&err_chunk)) {
|
1144 |
|
|
/* This chunk contains fatal error. It is to be discarded.
|
1145 |
|
|
* Send an ABORT, with causes if there is any.
|
1146 |
|
|
*/
|
1147 |
|
|
if (err_chunk) {
|
1148 |
|
|
packet = sctp_abort_pkt_new(ep, asoc, arg,
|
1149 |
|
|
(__u8 *)(err_chunk->chunk_hdr) +
|
1150 |
|
|
sizeof(sctp_chunkhdr_t),
|
1151 |
|
|
ntohs(err_chunk->chunk_hdr->length) -
|
1152 |
|
|
sizeof(sctp_chunkhdr_t));
|
1153 |
|
|
|
1154 |
|
|
if (packet) {
|
1155 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
1156 |
|
|
SCTP_PACKET(packet));
|
1157 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
1158 |
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
1159 |
|
|
} else {
|
1160 |
|
|
retval = SCTP_DISPOSITION_NOMEM;
|
1161 |
|
|
}
|
1162 |
|
|
goto cleanup;
|
1163 |
|
|
} else {
|
1164 |
|
|
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
|
1165 |
|
|
commands);
|
1166 |
|
|
}
|
1167 |
|
|
}
|
1168 |
|
|
|
1169 |
|
|
/*
|
1170 |
|
|
* Other parameters for the endpoint SHOULD be copied from the
|
1171 |
|
|
* existing parameters of the association (e.g. number of
|
1172 |
|
|
* outbound streams) into the INIT ACK and cookie.
|
1173 |
|
|
* FIXME: We are copying parameters from the endpoint not the
|
1174 |
|
|
* association.
|
1175 |
|
|
*/
|
1176 |
|
|
new_asoc = sctp_make_temp_asoc(ep, chunk, GFP_ATOMIC);
|
1177 |
|
|
if (!new_asoc)
|
1178 |
|
|
goto nomem;
|
1179 |
|
|
|
1180 |
|
|
/* In the outbound INIT ACK the endpoint MUST copy its current
|
1181 |
|
|
* Verification Tag and Peers Verification tag into a reserved
|
1182 |
|
|
* place (local tie-tag and per tie-tag) within the state cookie.
|
1183 |
|
|
*/
|
1184 |
|
|
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
|
1185 |
|
|
sctp_source(chunk),
|
1186 |
|
|
(sctp_init_chunk_t *)chunk->chunk_hdr,
|
1187 |
|
|
GFP_ATOMIC)) {
|
1188 |
|
|
retval = SCTP_DISPOSITION_NOMEM;
|
1189 |
|
|
goto nomem_init;
|
1190 |
|
|
}
|
1191 |
|
|
|
1192 |
|
|
/* Make sure no new addresses are being added during the
|
1193 |
|
|
* restart. Do not do this check for COOKIE-WAIT state,
|
1194 |
|
|
* since there are no peer addresses to check against.
|
1195 |
|
|
* Upon return an ABORT will have been sent if needed.
|
1196 |
|
|
*/
|
1197 |
|
|
if (!sctp_state(asoc, COOKIE_WAIT)) {
|
1198 |
|
|
if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk,
|
1199 |
|
|
commands)) {
|
1200 |
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
1201 |
|
|
goto cleanup_asoc;
|
1202 |
|
|
}
|
1203 |
|
|
}
|
1204 |
|
|
|
1205 |
|
|
sctp_tietags_populate(new_asoc, asoc);
|
1206 |
|
|
|
1207 |
|
|
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
|
1208 |
|
|
|
1209 |
|
|
/* If there are errors need to be reported for unknown parameters,
|
1210 |
|
|
* make sure to reserve enough room in the INIT ACK for them.
|
1211 |
|
|
*/
|
1212 |
|
|
len = 0;
|
1213 |
|
|
if (err_chunk) {
|
1214 |
|
|
len = ntohs(err_chunk->chunk_hdr->length) -
|
1215 |
|
|
sizeof(sctp_chunkhdr_t);
|
1216 |
|
|
}
|
1217 |
|
|
|
1218 |
|
|
if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
|
1219 |
|
|
goto nomem;
|
1220 |
|
|
|
1221 |
|
|
repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
|
1222 |
|
|
if (!repl)
|
1223 |
|
|
goto nomem;
|
1224 |
|
|
|
1225 |
|
|
/* If there are errors need to be reported for unknown parameters,
|
1226 |
|
|
* include them in the outgoing INIT ACK as "Unrecognized parameter"
|
1227 |
|
|
* parameter.
|
1228 |
|
|
*/
|
1229 |
|
|
if (err_chunk) {
|
1230 |
|
|
/* Get the "Unrecognized parameter" parameter(s) out of the
|
1231 |
|
|
* ERROR chunk generated by sctp_verify_init(). Since the
|
1232 |
|
|
* error cause code for "unknown parameter" and the
|
1233 |
|
|
* "Unrecognized parameter" type is the same, we can
|
1234 |
|
|
* construct the parameters in INIT ACK by copying the
|
1235 |
|
|
* ERROR causes over.
|
1236 |
|
|
*/
|
1237 |
|
|
unk_param = (sctp_unrecognized_param_t *)
|
1238 |
|
|
((__u8 *)(err_chunk->chunk_hdr) +
|
1239 |
|
|
sizeof(sctp_chunkhdr_t));
|
1240 |
|
|
/* Replace the cause code with the "Unrecognized parameter"
|
1241 |
|
|
* parameter type.
|
1242 |
|
|
*/
|
1243 |
|
|
sctp_addto_chunk(repl, len, unk_param);
|
1244 |
|
|
}
|
1245 |
|
|
|
1246 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
|
1247 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
1248 |
|
|
|
1249 |
|
|
/*
|
1250 |
|
|
* Note: After sending out INIT ACK with the State Cookie parameter,
|
1251 |
|
|
* "Z" MUST NOT allocate any resources for this new association.
|
1252 |
|
|
* Otherwise, "Z" will be vulnerable to resource attacks.
|
1253 |
|
|
*/
|
1254 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
1255 |
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
1256 |
|
|
|
1257 |
|
|
cleanup:
|
1258 |
|
|
if (err_chunk)
|
1259 |
|
|
sctp_chunk_free(err_chunk);
|
1260 |
|
|
return retval;
|
1261 |
|
|
nomem:
|
1262 |
|
|
retval = SCTP_DISPOSITION_NOMEM;
|
1263 |
|
|
goto cleanup;
|
1264 |
|
|
nomem_init:
|
1265 |
|
|
cleanup_asoc:
|
1266 |
|
|
sctp_association_free(new_asoc);
|
1267 |
|
|
goto cleanup;
|
1268 |
|
|
}
|
1269 |
|
|
|
1270 |
|
|
/*
|
1271 |
|
|
* Handle simultanous INIT.
|
1272 |
|
|
* This means we started an INIT and then we got an INIT request from
|
1273 |
|
|
* our peer.
|
1274 |
|
|
*
|
1275 |
|
|
* Section: 5.2.1 INIT received in COOKIE-WAIT or COOKIE-ECHOED State (Item B)
|
1276 |
|
|
* This usually indicates an initialization collision, i.e., each
|
1277 |
|
|
* endpoint is attempting, at about the same time, to establish an
|
1278 |
|
|
* association with the other endpoint.
|
1279 |
|
|
*
|
1280 |
|
|
* Upon receipt of an INIT in the COOKIE-WAIT or COOKIE-ECHOED state, an
|
1281 |
|
|
* endpoint MUST respond with an INIT ACK using the same parameters it
|
1282 |
|
|
* sent in its original INIT chunk (including its Verification Tag,
|
1283 |
|
|
* unchanged). These original parameters are combined with those from the
|
1284 |
|
|
* newly received INIT chunk. The endpoint shall also generate a State
|
1285 |
|
|
* Cookie with the INIT ACK. The endpoint uses the parameters sent in its
|
1286 |
|
|
* INIT to calculate the State Cookie.
|
1287 |
|
|
*
|
1288 |
|
|
* After that, the endpoint MUST NOT change its state, the T1-init
|
1289 |
|
|
* timer shall be left running and the corresponding TCB MUST NOT be
|
1290 |
|
|
* destroyed. The normal procedures for handling State Cookies when
|
1291 |
|
|
* a TCB exists will resolve the duplicate INITs to a single association.
|
1292 |
|
|
*
|
1293 |
|
|
* For an endpoint that is in the COOKIE-ECHOED state it MUST populate
|
1294 |
|
|
* its Tie-Tags with the Tag information of itself and its peer (see
|
1295 |
|
|
* section 5.2.2 for a description of the Tie-Tags).
|
1296 |
|
|
*
|
1297 |
|
|
* Verification Tag: Not explicit, but an INIT can not have a valid
|
1298 |
|
|
* verification tag, so we skip the check.
|
1299 |
|
|
*
|
1300 |
|
|
* Inputs
|
1301 |
|
|
* (endpoint, asoc, chunk)
|
1302 |
|
|
*
|
1303 |
|
|
* Outputs
|
1304 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1305 |
|
|
*
|
1306 |
|
|
* The return value is the disposition of the chunk.
|
1307 |
|
|
*/
|
1308 |
|
|
sctp_disposition_t sctp_sf_do_5_2_1_siminit(const struct sctp_endpoint *ep,
|
1309 |
|
|
const struct sctp_association *asoc,
|
1310 |
|
|
const sctp_subtype_t type,
|
1311 |
|
|
void *arg,
|
1312 |
|
|
sctp_cmd_seq_t *commands)
|
1313 |
|
|
{
|
1314 |
|
|
/* Call helper to do the real work for both simulataneous and
|
1315 |
|
|
* duplicate INIT chunk handling.
|
1316 |
|
|
*/
|
1317 |
|
|
return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
|
1318 |
|
|
}
|
1319 |
|
|
|
1320 |
|
|
/*
|
1321 |
|
|
* Handle duplicated INIT messages. These are usually delayed
|
1322 |
|
|
* restransmissions.
|
1323 |
|
|
*
|
1324 |
|
|
* Section: 5.2.2 Unexpected INIT in States Other than CLOSED,
|
1325 |
|
|
* COOKIE-ECHOED and COOKIE-WAIT
|
1326 |
|
|
*
|
1327 |
|
|
* Unless otherwise stated, upon reception of an unexpected INIT for
|
1328 |
|
|
* this association, the endpoint shall generate an INIT ACK with a
|
1329 |
|
|
* State Cookie. In the outbound INIT ACK the endpoint MUST copy its
|
1330 |
|
|
* current Verification Tag and peer's Verification Tag into a reserved
|
1331 |
|
|
* place within the state cookie. We shall refer to these locations as
|
1332 |
|
|
* the Peer's-Tie-Tag and the Local-Tie-Tag. The outbound SCTP packet
|
1333 |
|
|
* containing this INIT ACK MUST carry a Verification Tag value equal to
|
1334 |
|
|
* the Initiation Tag found in the unexpected INIT. And the INIT ACK
|
1335 |
|
|
* MUST contain a new Initiation Tag (randomly generated see Section
|
1336 |
|
|
* 5.3.1). Other parameters for the endpoint SHOULD be copied from the
|
1337 |
|
|
* existing parameters of the association (e.g. number of outbound
|
1338 |
|
|
* streams) into the INIT ACK and cookie.
|
1339 |
|
|
*
|
1340 |
|
|
* After sending out the INIT ACK, the endpoint shall take no further
|
1341 |
|
|
* actions, i.e., the existing association, including its current state,
|
1342 |
|
|
* and the corresponding TCB MUST NOT be changed.
|
1343 |
|
|
*
|
1344 |
|
|
* Note: Only when a TCB exists and the association is not in a COOKIE-
|
1345 |
|
|
* WAIT state are the Tie-Tags populated. For a normal association INIT
|
1346 |
|
|
* (i.e. the endpoint is in a COOKIE-WAIT state), the Tie-Tags MUST be
|
1347 |
|
|
* set to 0 (indicating that no previous TCB existed). The INIT ACK and
|
1348 |
|
|
* State Cookie are populated as specified in section 5.2.1.
|
1349 |
|
|
*
|
1350 |
|
|
* Verification Tag: Not specified, but an INIT has no way of knowing
|
1351 |
|
|
* what the verification tag could be, so we ignore it.
|
1352 |
|
|
*
|
1353 |
|
|
* Inputs
|
1354 |
|
|
* (endpoint, asoc, chunk)
|
1355 |
|
|
*
|
1356 |
|
|
* Outputs
|
1357 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1358 |
|
|
*
|
1359 |
|
|
* The return value is the disposition of the chunk.
|
1360 |
|
|
*/
|
1361 |
|
|
sctp_disposition_t sctp_sf_do_5_2_2_dupinit(const struct sctp_endpoint *ep,
|
1362 |
|
|
const struct sctp_association *asoc,
|
1363 |
|
|
const sctp_subtype_t type,
|
1364 |
|
|
void *arg,
|
1365 |
|
|
sctp_cmd_seq_t *commands)
|
1366 |
|
|
{
|
1367 |
|
|
/* Call helper to do the real work for both simulataneous and
|
1368 |
|
|
* duplicate INIT chunk handling.
|
1369 |
|
|
*/
|
1370 |
|
|
return sctp_sf_do_unexpected_init(ep, asoc, type, arg, commands);
|
1371 |
|
|
}
|
1372 |
|
|
|
1373 |
|
|
|
1374 |
|
|
|
1375 |
|
|
/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
|
1376 |
|
|
*
|
1377 |
|
|
* Section 5.2.4
|
1378 |
|
|
* A) In this case, the peer may have restarted.
|
1379 |
|
|
*/
|
1380 |
|
|
static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
|
1381 |
|
|
const struct sctp_association *asoc,
|
1382 |
|
|
struct sctp_chunk *chunk,
|
1383 |
|
|
sctp_cmd_seq_t *commands,
|
1384 |
|
|
struct sctp_association *new_asoc)
|
1385 |
|
|
{
|
1386 |
|
|
sctp_init_chunk_t *peer_init;
|
1387 |
|
|
struct sctp_ulpevent *ev;
|
1388 |
|
|
struct sctp_chunk *repl;
|
1389 |
|
|
|
1390 |
|
|
/* new_asoc is a brand-new association, so these are not yet
|
1391 |
|
|
* side effects--it is safe to run them here.
|
1392 |
|
|
*/
|
1393 |
|
|
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
|
1394 |
|
|
|
1395 |
|
|
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
|
1396 |
|
|
sctp_source(chunk), peer_init,
|
1397 |
|
|
GFP_ATOMIC))
|
1398 |
|
|
goto nomem;
|
1399 |
|
|
|
1400 |
|
|
/* Make sure no new addresses are being added during the
|
1401 |
|
|
* restart. Though this is a pretty complicated attack
|
1402 |
|
|
* since you'd have to get inside the cookie.
|
1403 |
|
|
*/
|
1404 |
|
|
if (!sctp_sf_check_restart_addrs(new_asoc, asoc, chunk, commands)) {
|
1405 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
1406 |
|
|
}
|
1407 |
|
|
|
1408 |
|
|
/* For now, fail any unsent/unacked data. Consider the optional
|
1409 |
|
|
* choice of resending of this data.
|
1410 |
|
|
*/
|
1411 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL());
|
1412 |
|
|
|
1413 |
|
|
/* Update the content of current association. */
|
1414 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
1415 |
|
|
|
1416 |
|
|
repl = sctp_make_cookie_ack(new_asoc, chunk);
|
1417 |
|
|
if (!repl)
|
1418 |
|
|
goto nomem;
|
1419 |
|
|
|
1420 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
1421 |
|
|
|
1422 |
|
|
/* Report association restart to upper layer. */
|
1423 |
|
|
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_RESTART, 0,
|
1424 |
|
|
new_asoc->c.sinit_num_ostreams,
|
1425 |
|
|
new_asoc->c.sinit_max_instreams,
|
1426 |
|
|
GFP_ATOMIC);
|
1427 |
|
|
if (!ev)
|
1428 |
|
|
goto nomem_ev;
|
1429 |
|
|
|
1430 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
1431 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
1432 |
|
|
|
1433 |
|
|
nomem_ev:
|
1434 |
|
|
sctp_chunk_free(repl);
|
1435 |
|
|
nomem:
|
1436 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
1437 |
|
|
}
|
1438 |
|
|
|
1439 |
|
|
/* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'B')
|
1440 |
|
|
*
|
1441 |
|
|
* Section 5.2.4
|
1442 |
|
|
* B) In this case, both sides may be attempting to start an association
|
1443 |
|
|
* at about the same time but the peer endpoint started its INIT
|
1444 |
|
|
* after responding to the local endpoint's INIT
|
1445 |
|
|
*/
|
1446 |
|
|
/* This case represents an initialization collision. */
|
1447 |
|
|
static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
|
1448 |
|
|
const struct sctp_association *asoc,
|
1449 |
|
|
struct sctp_chunk *chunk,
|
1450 |
|
|
sctp_cmd_seq_t *commands,
|
1451 |
|
|
struct sctp_association *new_asoc)
|
1452 |
|
|
{
|
1453 |
|
|
sctp_init_chunk_t *peer_init;
|
1454 |
|
|
struct sctp_ulpevent *ev;
|
1455 |
|
|
struct sctp_chunk *repl;
|
1456 |
|
|
|
1457 |
|
|
/* new_asoc is a brand-new association, so these are not yet
|
1458 |
|
|
* side effects--it is safe to run them here.
|
1459 |
|
|
*/
|
1460 |
|
|
peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
|
1461 |
|
|
if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
|
1462 |
|
|
sctp_source(chunk), peer_init,
|
1463 |
|
|
GFP_ATOMIC))
|
1464 |
|
|
goto nomem;
|
1465 |
|
|
|
1466 |
|
|
/* Update the content of current association. */
|
1467 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
|
1468 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
1469 |
|
|
SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
1470 |
|
|
SCTP_INC_STATS(SctpCurrEstab);
|
1471 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL());
|
1472 |
|
|
|
1473 |
|
|
repl = sctp_make_cookie_ack(new_asoc, chunk);
|
1474 |
|
|
if (!repl)
|
1475 |
|
|
goto nomem;
|
1476 |
|
|
|
1477 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
1478 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
|
1479 |
|
|
|
1480 |
|
|
/* RFC 2960 5.1 Normal Establishment of an Association
|
1481 |
|
|
*
|
1482 |
|
|
* D) IMPLEMENTATION NOTE: An implementation may choose to
|
1483 |
|
|
* send the Communication Up notification to the SCTP user
|
1484 |
|
|
* upon reception of a valid COOKIE ECHO chunk.
|
1485 |
|
|
*/
|
1486 |
|
|
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_UP, 0,
|
1487 |
|
|
new_asoc->c.sinit_num_ostreams,
|
1488 |
|
|
new_asoc->c.sinit_max_instreams,
|
1489 |
|
|
GFP_ATOMIC);
|
1490 |
|
|
if (!ev)
|
1491 |
|
|
goto nomem_ev;
|
1492 |
|
|
|
1493 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
1494 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
1495 |
|
|
|
1496 |
|
|
nomem_ev:
|
1497 |
|
|
sctp_chunk_free(repl);
|
1498 |
|
|
nomem:
|
1499 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
1500 |
|
|
}
|
1501 |
|
|
|
1502 |
|
|
/* Unexpected COOKIE-ECHO handler for setup collision (Table 2, action 'C')
|
1503 |
|
|
*
|
1504 |
|
|
* Section 5.2.4
|
1505 |
|
|
* C) In this case, the local endpoint's cookie has arrived late.
|
1506 |
|
|
* Before it arrived, the local endpoint sent an INIT and received an
|
1507 |
|
|
* INIT-ACK and finally sent a COOKIE ECHO with the peer's same tag
|
1508 |
|
|
* but a new tag of its own.
|
1509 |
|
|
*/
|
1510 |
|
|
/* This case represents an initialization collision. */
|
1511 |
|
|
static sctp_disposition_t sctp_sf_do_dupcook_c(const struct sctp_endpoint *ep,
|
1512 |
|
|
const struct sctp_association *asoc,
|
1513 |
|
|
struct sctp_chunk *chunk,
|
1514 |
|
|
sctp_cmd_seq_t *commands,
|
1515 |
|
|
struct sctp_association *new_asoc)
|
1516 |
|
|
{
|
1517 |
|
|
/* The cookie should be silently discarded.
|
1518 |
|
|
* The endpoint SHOULD NOT change states and should leave
|
1519 |
|
|
* any timers running.
|
1520 |
|
|
*/
|
1521 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
1522 |
|
|
}
|
1523 |
|
|
|
1524 |
|
|
/* Unexpected COOKIE-ECHO handler lost chunk (Table 2, action 'D')
|
1525 |
|
|
*
|
1526 |
|
|
* Section 5.2.4
|
1527 |
|
|
*
|
1528 |
|
|
* D) When both local and remote tags match the endpoint should always
|
1529 |
|
|
* enter the ESTABLISHED state, if it has not already done so.
|
1530 |
|
|
*/
|
1531 |
|
|
/* This case represents an initialization collision. */
|
1532 |
|
|
static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
|
1533 |
|
|
const struct sctp_association *asoc,
|
1534 |
|
|
struct sctp_chunk *chunk,
|
1535 |
|
|
sctp_cmd_seq_t *commands,
|
1536 |
|
|
struct sctp_association *new_asoc)
|
1537 |
|
|
{
|
1538 |
|
|
struct sctp_ulpevent *ev = NULL;
|
1539 |
|
|
struct sctp_chunk *repl;
|
1540 |
|
|
|
1541 |
|
|
/* Clarification from Implementor's Guide:
|
1542 |
|
|
* D) When both local and remote tags match the endpoint should
|
1543 |
|
|
* enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.
|
1544 |
|
|
* It should stop any cookie timer that may be running and send
|
1545 |
|
|
* a COOKIE ACK.
|
1546 |
|
|
*/
|
1547 |
|
|
|
1548 |
|
|
/* Don't accidentally move back into established state. */
|
1549 |
|
|
if (asoc->state < SCTP_STATE_ESTABLISHED) {
|
1550 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1551 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
|
1552 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
1553 |
|
|
SCTP_STATE(SCTP_STATE_ESTABLISHED));
|
1554 |
|
|
SCTP_INC_STATS(SctpCurrEstab);
|
1555 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
|
1556 |
|
|
SCTP_NULL());
|
1557 |
|
|
|
1558 |
|
|
/* RFC 2960 5.1 Normal Establishment of an Association
|
1559 |
|
|
*
|
1560 |
|
|
* D) IMPLEMENTATION NOTE: An implementation may choose
|
1561 |
|
|
* to send the Communication Up notification to the
|
1562 |
|
|
* SCTP user upon reception of a valid COOKIE
|
1563 |
|
|
* ECHO chunk.
|
1564 |
|
|
*/
|
1565 |
|
|
ev = sctp_ulpevent_make_assoc_change(new_asoc, 0,
|
1566 |
|
|
SCTP_COMM_UP, 0,
|
1567 |
|
|
new_asoc->c.sinit_num_ostreams,
|
1568 |
|
|
new_asoc->c.sinit_max_instreams,
|
1569 |
|
|
GFP_ATOMIC);
|
1570 |
|
|
if (!ev)
|
1571 |
|
|
goto nomem;
|
1572 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
|
1573 |
|
|
SCTP_ULPEVENT(ev));
|
1574 |
|
|
}
|
1575 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
|
1576 |
|
|
|
1577 |
|
|
repl = sctp_make_cookie_ack(new_asoc, chunk);
|
1578 |
|
|
if (!repl)
|
1579 |
|
|
goto nomem;
|
1580 |
|
|
|
1581 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
1582 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
|
1583 |
|
|
|
1584 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
1585 |
|
|
|
1586 |
|
|
nomem:
|
1587 |
|
|
if (ev)
|
1588 |
|
|
sctp_ulpevent_free(ev);
|
1589 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
1590 |
|
|
}
|
1591 |
|
|
|
1592 |
|
|
/*
|
1593 |
|
|
* Handle a duplicate COOKIE-ECHO. This usually means a cookie-carrying
|
1594 |
|
|
* chunk was retransmitted and then delayed in the network.
|
1595 |
|
|
*
|
1596 |
|
|
* Section: 5.2.4 Handle a COOKIE ECHO when a TCB exists
|
1597 |
|
|
*
|
1598 |
|
|
* Verification Tag: None. Do cookie validation.
|
1599 |
|
|
*
|
1600 |
|
|
* Inputs
|
1601 |
|
|
* (endpoint, asoc, chunk)
|
1602 |
|
|
*
|
1603 |
|
|
* Outputs
|
1604 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1605 |
|
|
*
|
1606 |
|
|
* The return value is the disposition of the chunk.
|
1607 |
|
|
*/
|
1608 |
|
|
sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep,
|
1609 |
|
|
const struct sctp_association *asoc,
|
1610 |
|
|
const sctp_subtype_t type,
|
1611 |
|
|
void *arg,
|
1612 |
|
|
sctp_cmd_seq_t *commands)
|
1613 |
|
|
{
|
1614 |
|
|
sctp_disposition_t retval;
|
1615 |
|
|
struct sctp_chunk *chunk = arg;
|
1616 |
|
|
struct sctp_association *new_asoc;
|
1617 |
|
|
int error = 0;
|
1618 |
|
|
char action;
|
1619 |
|
|
struct sctp_chunk *err_chk_p;
|
1620 |
|
|
|
1621 |
|
|
/* "Decode" the chunk. We have no optional parameters so we
|
1622 |
|
|
* are in good shape.
|
1623 |
|
|
*/
|
1624 |
|
|
chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data;
|
1625 |
|
|
skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) -
|
1626 |
|
|
sizeof(sctp_chunkhdr_t));
|
1627 |
|
|
|
1628 |
|
|
/* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie
|
1629 |
|
|
* of a duplicate COOKIE ECHO match the Verification Tags of the
|
1630 |
|
|
* current association, consider the State Cookie valid even if
|
1631 |
|
|
* the lifespan is exceeded.
|
1632 |
|
|
*/
|
1633 |
|
|
new_asoc = sctp_unpack_cookie(ep, asoc, chunk, GFP_ATOMIC, &error,
|
1634 |
|
|
&err_chk_p);
|
1635 |
|
|
|
1636 |
|
|
/* FIXME:
|
1637 |
|
|
* If the re-build failed, what is the proper error path
|
1638 |
|
|
* from here?
|
1639 |
|
|
*
|
1640 |
|
|
* [We should abort the association. --piggy]
|
1641 |
|
|
*/
|
1642 |
|
|
if (!new_asoc) {
|
1643 |
|
|
/* FIXME: Several errors are possible. A bad cookie should
|
1644 |
|
|
* be silently discarded, but think about logging it too.
|
1645 |
|
|
*/
|
1646 |
|
|
switch (error) {
|
1647 |
|
|
case -SCTP_IERROR_NOMEM:
|
1648 |
|
|
goto nomem;
|
1649 |
|
|
|
1650 |
|
|
case -SCTP_IERROR_STALE_COOKIE:
|
1651 |
|
|
sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
|
1652 |
|
|
err_chk_p);
|
1653 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1654 |
|
|
case -SCTP_IERROR_BAD_SIG:
|
1655 |
|
|
default:
|
1656 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1657 |
|
|
};
|
1658 |
|
|
}
|
1659 |
|
|
|
1660 |
|
|
/* Compare the tie_tag in cookie with the verification tag of
|
1661 |
|
|
* current association.
|
1662 |
|
|
*/
|
1663 |
|
|
action = sctp_tietags_compare(new_asoc, asoc);
|
1664 |
|
|
|
1665 |
|
|
switch (action) {
|
1666 |
|
|
case 'A': /* Association restart. */
|
1667 |
|
|
retval = sctp_sf_do_dupcook_a(ep, asoc, chunk, commands,
|
1668 |
|
|
new_asoc);
|
1669 |
|
|
break;
|
1670 |
|
|
|
1671 |
|
|
case 'B': /* Collision case B. */
|
1672 |
|
|
retval = sctp_sf_do_dupcook_b(ep, asoc, chunk, commands,
|
1673 |
|
|
new_asoc);
|
1674 |
|
|
break;
|
1675 |
|
|
|
1676 |
|
|
case 'C': /* Collision case C. */
|
1677 |
|
|
retval = sctp_sf_do_dupcook_c(ep, asoc, chunk, commands,
|
1678 |
|
|
new_asoc);
|
1679 |
|
|
break;
|
1680 |
|
|
|
1681 |
|
|
case 'D': /* Collision case D. */
|
1682 |
|
|
retval = sctp_sf_do_dupcook_d(ep, asoc, chunk, commands,
|
1683 |
|
|
new_asoc);
|
1684 |
|
|
break;
|
1685 |
|
|
|
1686 |
|
|
default: /* Discard packet for all others. */
|
1687 |
|
|
retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1688 |
|
|
break;
|
1689 |
|
|
};
|
1690 |
|
|
|
1691 |
|
|
/* Delete the tempory new association. */
|
1692 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
|
1693 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
1694 |
|
|
|
1695 |
|
|
return retval;
|
1696 |
|
|
|
1697 |
|
|
nomem:
|
1698 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
1699 |
|
|
}
|
1700 |
|
|
|
1701 |
|
|
/*
|
1702 |
|
|
* Process an ABORT. (SHUTDOWN-PENDING state)
|
1703 |
|
|
*
|
1704 |
|
|
* See sctp_sf_do_9_1_abort().
|
1705 |
|
|
*/
|
1706 |
|
|
sctp_disposition_t sctp_sf_shutdown_pending_abort(
|
1707 |
|
|
const struct sctp_endpoint *ep,
|
1708 |
|
|
const struct sctp_association *asoc,
|
1709 |
|
|
const sctp_subtype_t type,
|
1710 |
|
|
void *arg,
|
1711 |
|
|
sctp_cmd_seq_t *commands)
|
1712 |
|
|
{
|
1713 |
|
|
struct sctp_chunk *chunk = arg;
|
1714 |
|
|
|
1715 |
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
1716 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1717 |
|
|
|
1718 |
|
|
/* Stop the T5-shutdown guard timer. */
|
1719 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1720 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
1721 |
|
|
|
1722 |
|
|
return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
1723 |
|
|
}
|
1724 |
|
|
|
1725 |
|
|
/*
|
1726 |
|
|
* Process an ABORT. (SHUTDOWN-SENT state)
|
1727 |
|
|
*
|
1728 |
|
|
* See sctp_sf_do_9_1_abort().
|
1729 |
|
|
*/
|
1730 |
|
|
sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
|
1731 |
|
|
const struct sctp_association *asoc,
|
1732 |
|
|
const sctp_subtype_t type,
|
1733 |
|
|
void *arg,
|
1734 |
|
|
sctp_cmd_seq_t *commands)
|
1735 |
|
|
{
|
1736 |
|
|
struct sctp_chunk *chunk = arg;
|
1737 |
|
|
|
1738 |
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
1739 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1740 |
|
|
|
1741 |
|
|
/* Stop the T2-shutdown timer. */
|
1742 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1743 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
1744 |
|
|
|
1745 |
|
|
/* Stop the T5-shutdown guard timer. */
|
1746 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1747 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
1748 |
|
|
|
1749 |
|
|
return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
|
1750 |
|
|
}
|
1751 |
|
|
|
1752 |
|
|
/*
|
1753 |
|
|
* Process an ABORT. (SHUTDOWN-ACK-SENT state)
|
1754 |
|
|
*
|
1755 |
|
|
* See sctp_sf_do_9_1_abort().
|
1756 |
|
|
*/
|
1757 |
|
|
sctp_disposition_t sctp_sf_shutdown_ack_sent_abort(
|
1758 |
|
|
const struct sctp_endpoint *ep,
|
1759 |
|
|
const struct sctp_association *asoc,
|
1760 |
|
|
const sctp_subtype_t type,
|
1761 |
|
|
void *arg,
|
1762 |
|
|
sctp_cmd_seq_t *commands)
|
1763 |
|
|
{
|
1764 |
|
|
/* The same T2 timer, so we should be able to use
|
1765 |
|
|
* common function with the SHUTDOWN-SENT state.
|
1766 |
|
|
*/
|
1767 |
|
|
return sctp_sf_shutdown_sent_abort(ep, asoc, type, arg, commands);
|
1768 |
|
|
}
|
1769 |
|
|
|
1770 |
|
|
/*
|
1771 |
|
|
* Handle an Error received in COOKIE_ECHOED state.
|
1772 |
|
|
*
|
1773 |
|
|
* Only handle the error type of stale COOKIE Error, the other errors will
|
1774 |
|
|
* be ignored.
|
1775 |
|
|
*
|
1776 |
|
|
* Inputs
|
1777 |
|
|
* (endpoint, asoc, chunk)
|
1778 |
|
|
*
|
1779 |
|
|
* Outputs
|
1780 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1781 |
|
|
*
|
1782 |
|
|
* The return value is the disposition of the chunk.
|
1783 |
|
|
*/
|
1784 |
|
|
sctp_disposition_t sctp_sf_cookie_echoed_err(const struct sctp_endpoint *ep,
|
1785 |
|
|
const struct sctp_association *asoc,
|
1786 |
|
|
const sctp_subtype_t type,
|
1787 |
|
|
void *arg,
|
1788 |
|
|
sctp_cmd_seq_t *commands)
|
1789 |
|
|
{
|
1790 |
|
|
struct sctp_chunk *chunk = arg;
|
1791 |
|
|
sctp_errhdr_t *err;
|
1792 |
|
|
|
1793 |
|
|
/* Process the error here */
|
1794 |
|
|
/* FUTURE FIXME: When PR-SCTP related and other optional
|
1795 |
|
|
* parms are emitted, this will have to change to handle multiple
|
1796 |
|
|
* errors.
|
1797 |
|
|
*/
|
1798 |
|
|
sctp_walk_errors(err, chunk->chunk_hdr) {
|
1799 |
|
|
if (SCTP_ERROR_STALE_COOKIE == err->cause)
|
1800 |
|
|
return sctp_sf_do_5_2_6_stale(ep, asoc, type,
|
1801 |
|
|
arg, commands);
|
1802 |
|
|
}
|
1803 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1804 |
|
|
}
|
1805 |
|
|
|
1806 |
|
|
/*
|
1807 |
|
|
* Handle a Stale COOKIE Error
|
1808 |
|
|
*
|
1809 |
|
|
* Section: 5.2.6 Handle Stale COOKIE Error
|
1810 |
|
|
* If the association is in the COOKIE-ECHOED state, the endpoint may elect
|
1811 |
|
|
* one of the following three alternatives.
|
1812 |
|
|
* ...
|
1813 |
|
|
* 3) Send a new INIT chunk to the endpoint, adding a Cookie
|
1814 |
|
|
* Preservative parameter requesting an extension to the lifetime of
|
1815 |
|
|
* the State Cookie. When calculating the time extension, an
|
1816 |
|
|
* implementation SHOULD use the RTT information measured based on the
|
1817 |
|
|
* previous COOKIE ECHO / ERROR exchange, and should add no more
|
1818 |
|
|
* than 1 second beyond the measured RTT, due to long State Cookie
|
1819 |
|
|
* lifetimes making the endpoint more subject to a replay attack.
|
1820 |
|
|
*
|
1821 |
|
|
* Verification Tag: Not explicit, but safe to ignore.
|
1822 |
|
|
*
|
1823 |
|
|
* Inputs
|
1824 |
|
|
* (endpoint, asoc, chunk)
|
1825 |
|
|
*
|
1826 |
|
|
* Outputs
|
1827 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1828 |
|
|
*
|
1829 |
|
|
* The return value is the disposition of the chunk.
|
1830 |
|
|
*/
|
1831 |
|
|
sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
|
1832 |
|
|
const struct sctp_association *asoc,
|
1833 |
|
|
const sctp_subtype_t type,
|
1834 |
|
|
void *arg,
|
1835 |
|
|
sctp_cmd_seq_t *commands)
|
1836 |
|
|
{
|
1837 |
|
|
struct sctp_chunk *chunk = arg;
|
1838 |
|
|
time_t stale;
|
1839 |
|
|
sctp_cookie_preserve_param_t bht;
|
1840 |
|
|
sctp_errhdr_t *err;
|
1841 |
|
|
struct list_head *pos;
|
1842 |
|
|
struct sctp_transport *t;
|
1843 |
|
|
struct sctp_chunk *reply;
|
1844 |
|
|
struct sctp_bind_addr *bp;
|
1845 |
|
|
int attempts;
|
1846 |
|
|
|
1847 |
|
|
attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
|
1848 |
|
|
|
1849 |
|
|
if (attempts >= asoc->max_init_attempts) {
|
1850 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
|
1851 |
|
|
SCTP_U32(SCTP_ERROR_STALE_COOKIE));
|
1852 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
1853 |
|
|
}
|
1854 |
|
|
|
1855 |
|
|
err = (sctp_errhdr_t *)(chunk->skb->data);
|
1856 |
|
|
|
1857 |
|
|
/* When calculating the time extension, an implementation
|
1858 |
|
|
* SHOULD use the RTT information measured based on the
|
1859 |
|
|
* previous COOKIE ECHO / ERROR exchange, and should add no
|
1860 |
|
|
* more than 1 second beyond the measured RTT, due to long
|
1861 |
|
|
* State Cookie lifetimes making the endpoint more subject to
|
1862 |
|
|
* a replay attack.
|
1863 |
|
|
* Measure of Staleness's unit is usec. (1/1000000 sec)
|
1864 |
|
|
* Suggested Cookie Life-span Increment's unit is msec.
|
1865 |
|
|
* (1/1000 sec)
|
1866 |
|
|
* In general, if you use the suggested cookie life, the value
|
1867 |
|
|
* found in the field of measure of staleness should be doubled
|
1868 |
|
|
* to give ample time to retransmit the new cookie and thus
|
1869 |
|
|
* yield a higher probability of success on the reattempt.
|
1870 |
|
|
*/
|
1871 |
|
|
stale = ntohl(*(suseconds_t *)((u8 *)err + sizeof(sctp_errhdr_t)));
|
1872 |
|
|
stale = (stale * 2) / 1000;
|
1873 |
|
|
|
1874 |
|
|
bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE;
|
1875 |
|
|
bht.param_hdr.length = htons(sizeof(bht));
|
1876 |
|
|
bht.lifespan_increment = htonl(stale);
|
1877 |
|
|
|
1878 |
|
|
/* Build that new INIT chunk. */
|
1879 |
|
|
bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
|
1880 |
|
|
reply = sctp_make_init(asoc, bp, GFP_ATOMIC, sizeof(bht));
|
1881 |
|
|
if (!reply)
|
1882 |
|
|
goto nomem;
|
1883 |
|
|
|
1884 |
|
|
sctp_addto_chunk(reply, sizeof(bht), &bht);
|
1885 |
|
|
|
1886 |
|
|
/* Cast away the const modifier, as we want to just
|
1887 |
|
|
* rerun it through as a sideffect.
|
1888 |
|
|
*/
|
1889 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC,
|
1890 |
|
|
SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
|
1891 |
|
|
|
1892 |
|
|
/* If we've sent any data bundled with COOKIE-ECHO we need to
|
1893 |
|
|
* resend.
|
1894 |
|
|
*/
|
1895 |
|
|
list_for_each(pos, &asoc->peer.transport_addr_list) {
|
1896 |
|
|
t = list_entry(pos, struct sctp_transport, transports);
|
1897 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(t));
|
1898 |
|
|
}
|
1899 |
|
|
|
1900 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1901 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
|
1902 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
1903 |
|
|
SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
|
1904 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
1905 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
1906 |
|
|
|
1907 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
1908 |
|
|
|
1909 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
1910 |
|
|
|
1911 |
|
|
nomem:
|
1912 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
1913 |
|
|
}
|
1914 |
|
|
|
1915 |
|
|
/*
|
1916 |
|
|
* Process an ABORT.
|
1917 |
|
|
*
|
1918 |
|
|
* Section: 9.1
|
1919 |
|
|
* After checking the Verification Tag, the receiving endpoint shall
|
1920 |
|
|
* remove the association from its record, and shall report the
|
1921 |
|
|
* termination to its upper layer.
|
1922 |
|
|
*
|
1923 |
|
|
* Verification Tag: 8.5.1 Exceptions in Verification Tag Rules
|
1924 |
|
|
* B) Rules for packet carrying ABORT:
|
1925 |
|
|
*
|
1926 |
|
|
* - The endpoint shall always fill in the Verification Tag field of the
|
1927 |
|
|
* outbound packet with the destination endpoint's tag value if it
|
1928 |
|
|
* is known.
|
1929 |
|
|
*
|
1930 |
|
|
* - If the ABORT is sent in response to an OOTB packet, the endpoint
|
1931 |
|
|
* MUST follow the procedure described in Section 8.4.
|
1932 |
|
|
*
|
1933 |
|
|
* - The receiver MUST accept the packet if the Verification Tag
|
1934 |
|
|
* matches either its own tag, OR the tag of its peer. Otherwise, the
|
1935 |
|
|
* receiver MUST silently discard the packet and take no further
|
1936 |
|
|
* action.
|
1937 |
|
|
*
|
1938 |
|
|
* Inputs
|
1939 |
|
|
* (endpoint, asoc, chunk)
|
1940 |
|
|
*
|
1941 |
|
|
* Outputs
|
1942 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
1943 |
|
|
*
|
1944 |
|
|
* The return value is the disposition of the chunk.
|
1945 |
|
|
*/
|
1946 |
|
|
sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
|
1947 |
|
|
const struct sctp_association *asoc,
|
1948 |
|
|
const sctp_subtype_t type,
|
1949 |
|
|
void *arg,
|
1950 |
|
|
sctp_cmd_seq_t *commands)
|
1951 |
|
|
{
|
1952 |
|
|
struct sctp_chunk *chunk = arg;
|
1953 |
|
|
unsigned len;
|
1954 |
|
|
__u16 error = SCTP_ERROR_NO_ERROR;
|
1955 |
|
|
|
1956 |
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
1957 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1958 |
|
|
|
1959 |
|
|
/* Check that chunk header looks valid. */
|
1960 |
|
|
len = ntohs(chunk->chunk_hdr->length);
|
1961 |
|
|
if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
|
1962 |
|
|
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
|
1963 |
|
|
|
1964 |
|
|
|
1965 |
|
|
/* ASSOC_FAILED will DELETE_TCB. */
|
1966 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
|
1967 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
1968 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
1969 |
|
|
|
1970 |
|
|
return SCTP_DISPOSITION_ABORT;
|
1971 |
|
|
}
|
1972 |
|
|
|
1973 |
|
|
/*
|
1974 |
|
|
* Process an ABORT. (COOKIE-WAIT state)
|
1975 |
|
|
*
|
1976 |
|
|
* See sctp_sf_do_9_1_abort() above.
|
1977 |
|
|
*/
|
1978 |
|
|
sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
|
1979 |
|
|
const struct sctp_association *asoc,
|
1980 |
|
|
const sctp_subtype_t type,
|
1981 |
|
|
void *arg,
|
1982 |
|
|
sctp_cmd_seq_t *commands)
|
1983 |
|
|
{
|
1984 |
|
|
struct sctp_chunk *chunk = arg;
|
1985 |
|
|
unsigned len;
|
1986 |
|
|
__u16 error = SCTP_ERROR_NO_ERROR;
|
1987 |
|
|
|
1988 |
|
|
if (!sctp_vtag_verify_either(chunk, asoc))
|
1989 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
1990 |
|
|
|
1991 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
1992 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
1993 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
1994 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
1995 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
1996 |
|
|
|
1997 |
|
|
/* Check that chunk header looks valid. */
|
1998 |
|
|
len = ntohs(chunk->chunk_hdr->length);
|
1999 |
|
|
if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
|
2000 |
|
|
error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
|
2001 |
|
|
|
2002 |
|
|
/* CMD_INIT_FAILED will DELETE_TCB. */
|
2003 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(error));
|
2004 |
|
|
|
2005 |
|
|
return SCTP_DISPOSITION_ABORT;
|
2006 |
|
|
}
|
2007 |
|
|
|
2008 |
|
|
/*
|
2009 |
|
|
* Process an ABORT. (COOKIE-ECHOED state)
|
2010 |
|
|
*
|
2011 |
|
|
* See sctp_sf_do_9_1_abort() above.
|
2012 |
|
|
*/
|
2013 |
|
|
sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
|
2014 |
|
|
const struct sctp_association *asoc,
|
2015 |
|
|
const sctp_subtype_t type,
|
2016 |
|
|
void *arg,
|
2017 |
|
|
sctp_cmd_seq_t *commands)
|
2018 |
|
|
{
|
2019 |
|
|
/* There is a single T1 timer, so we should be able to use
|
2020 |
|
|
* common function with the COOKIE-WAIT state.
|
2021 |
|
|
*/
|
2022 |
|
|
return sctp_sf_cookie_wait_abort(ep, asoc, type, arg, commands);
|
2023 |
|
|
}
|
2024 |
|
|
|
2025 |
|
|
/*
|
2026 |
|
|
* sctp_sf_do_9_2_shut
|
2027 |
|
|
*
|
2028 |
|
|
* Section: 9.2
|
2029 |
|
|
* Upon the reception of the SHUTDOWN, the peer endpoint shall
|
2030 |
|
|
* - enter the SHUTDOWN-RECEIVED state,
|
2031 |
|
|
*
|
2032 |
|
|
* - stop accepting new data from its SCTP user
|
2033 |
|
|
*
|
2034 |
|
|
* - verify, by checking the Cumulative TSN Ack field of the chunk,
|
2035 |
|
|
* that all its outstanding DATA chunks have been received by the
|
2036 |
|
|
* SHUTDOWN sender.
|
2037 |
|
|
*
|
2038 |
|
|
* Once an endpoint as reached the SHUTDOWN-RECEIVED state it MUST NOT
|
2039 |
|
|
* send a SHUTDOWN in response to a ULP request. And should discard
|
2040 |
|
|
* subsequent SHUTDOWN chunks.
|
2041 |
|
|
*
|
2042 |
|
|
* If there are still outstanding DATA chunks left, the SHUTDOWN
|
2043 |
|
|
* receiver shall continue to follow normal data transmission
|
2044 |
|
|
* procedures defined in Section 6 until all outstanding DATA chunks
|
2045 |
|
|
* are acknowledged; however, the SHUTDOWN receiver MUST NOT accept
|
2046 |
|
|
* new data from its SCTP user.
|
2047 |
|
|
*
|
2048 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2049 |
|
|
*
|
2050 |
|
|
* Inputs
|
2051 |
|
|
* (endpoint, asoc, chunk)
|
2052 |
|
|
*
|
2053 |
|
|
* Outputs
|
2054 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2055 |
|
|
*
|
2056 |
|
|
* The return value is the disposition of the chunk.
|
2057 |
|
|
*/
|
2058 |
|
|
sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
|
2059 |
|
|
const struct sctp_association *asoc,
|
2060 |
|
|
const sctp_subtype_t type,
|
2061 |
|
|
void *arg,
|
2062 |
|
|
sctp_cmd_seq_t *commands)
|
2063 |
|
|
{
|
2064 |
|
|
struct sctp_chunk *chunk = arg;
|
2065 |
|
|
sctp_shutdownhdr_t *sdh;
|
2066 |
|
|
sctp_disposition_t disposition;
|
2067 |
|
|
struct sctp_ulpevent *ev;
|
2068 |
|
|
|
2069 |
|
|
/* Convert the elaborate header. */
|
2070 |
|
|
sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
|
2071 |
|
|
skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
|
2072 |
|
|
chunk->subh.shutdown_hdr = sdh;
|
2073 |
|
|
|
2074 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
2075 |
|
|
* that the value in the Verification Tag field of the
|
2076 |
|
|
* received SCTP packet matches its own Tag. If the received
|
2077 |
|
|
* Verification Tag value does not match the receiver's own
|
2078 |
|
|
* tag value, the receiver shall silently discard the packet...
|
2079 |
|
|
*/
|
2080 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
2081 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2082 |
|
|
|
2083 |
|
|
/* Upon the reception of the SHUTDOWN, the peer endpoint shall
|
2084 |
|
|
* - enter the SHUTDOWN-RECEIVED state,
|
2085 |
|
|
* - stop accepting new data from its SCTP user
|
2086 |
|
|
*
|
2087 |
|
|
* [This is implicit in the new state.]
|
2088 |
|
|
*/
|
2089 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
2090 |
|
|
SCTP_STATE(SCTP_STATE_SHUTDOWN_RECEIVED));
|
2091 |
|
|
disposition = SCTP_DISPOSITION_CONSUME;
|
2092 |
|
|
|
2093 |
|
|
if (sctp_outq_is_empty(&asoc->outqueue)) {
|
2094 |
|
|
disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
|
2095 |
|
|
arg, commands);
|
2096 |
|
|
}
|
2097 |
|
|
|
2098 |
|
|
if (SCTP_DISPOSITION_NOMEM == disposition)
|
2099 |
|
|
goto out;
|
2100 |
|
|
|
2101 |
|
|
/* - verify, by checking the Cumulative TSN Ack field of the
|
2102 |
|
|
* chunk, that all its outstanding DATA chunks have been
|
2103 |
|
|
* received by the SHUTDOWN sender.
|
2104 |
|
|
*/
|
2105 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
|
2106 |
|
|
SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack));
|
2107 |
|
|
|
2108 |
|
|
/* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
|
2109 |
|
|
* When a peer sends a SHUTDOWN, SCTP delivers this notification to
|
2110 |
|
|
* inform the application that it should cease sending data.
|
2111 |
|
|
*/
|
2112 |
|
|
ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);
|
2113 |
|
|
if (!ev) {
|
2114 |
|
|
disposition = SCTP_DISPOSITION_NOMEM;
|
2115 |
|
|
goto out;
|
2116 |
|
|
}
|
2117 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
2118 |
|
|
|
2119 |
|
|
out:
|
2120 |
|
|
return disposition;
|
2121 |
|
|
}
|
2122 |
|
|
|
2123 |
|
|
/* RFC 2960 9.2
|
2124 |
|
|
* If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
|
2125 |
|
|
* (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
|
2126 |
|
|
* transport addresses (either in the IP addresses or in the INIT chunk)
|
2127 |
|
|
* that belong to this association, it should discard the INIT chunk and
|
2128 |
|
|
* retransmit the SHUTDOWN ACK chunk.
|
2129 |
|
|
*/
|
2130 |
|
|
sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
|
2131 |
|
|
const struct sctp_association *asoc,
|
2132 |
|
|
const sctp_subtype_t type,
|
2133 |
|
|
void *arg,
|
2134 |
|
|
sctp_cmd_seq_t *commands)
|
2135 |
|
|
{
|
2136 |
|
|
struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
|
2137 |
|
|
struct sctp_chunk *reply;
|
2138 |
|
|
|
2139 |
|
|
reply = sctp_make_shutdown_ack(asoc, chunk);
|
2140 |
|
|
if (NULL == reply)
|
2141 |
|
|
goto nomem;
|
2142 |
|
|
|
2143 |
|
|
/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
|
2144 |
|
|
* the T2-SHUTDOWN timer.
|
2145 |
|
|
*/
|
2146 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
|
2147 |
|
|
|
2148 |
|
|
/* and restart the T2-shutdown timer. */
|
2149 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
2150 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
2151 |
|
|
|
2152 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
2153 |
|
|
|
2154 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2155 |
|
|
nomem:
|
2156 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
2157 |
|
|
}
|
2158 |
|
|
|
2159 |
|
|
/*
|
2160 |
|
|
* sctp_sf_do_ecn_cwr
|
2161 |
|
|
*
|
2162 |
|
|
* Section: Appendix A: Explicit Congestion Notification
|
2163 |
|
|
*
|
2164 |
|
|
* CWR:
|
2165 |
|
|
*
|
2166 |
|
|
* RFC 2481 details a specific bit for a sender to send in the header of
|
2167 |
|
|
* its next outbound TCP segment to indicate to its peer that it has
|
2168 |
|
|
* reduced its congestion window. This is termed the CWR bit. For
|
2169 |
|
|
* SCTP the same indication is made by including the CWR chunk.
|
2170 |
|
|
* This chunk contains one data element, i.e. the TSN number that
|
2171 |
|
|
* was sent in the ECNE chunk. This element represents the lowest
|
2172 |
|
|
* TSN number in the datagram that was originally marked with the
|
2173 |
|
|
* CE bit.
|
2174 |
|
|
*
|
2175 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2176 |
|
|
* Inputs
|
2177 |
|
|
* (endpoint, asoc, chunk)
|
2178 |
|
|
*
|
2179 |
|
|
* Outputs
|
2180 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2181 |
|
|
*
|
2182 |
|
|
* The return value is the disposition of the chunk.
|
2183 |
|
|
*/
|
2184 |
|
|
sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
|
2185 |
|
|
const struct sctp_association *asoc,
|
2186 |
|
|
const sctp_subtype_t type,
|
2187 |
|
|
void *arg,
|
2188 |
|
|
sctp_cmd_seq_t *commands)
|
2189 |
|
|
{
|
2190 |
|
|
sctp_cwrhdr_t *cwr;
|
2191 |
|
|
struct sctp_chunk *chunk = arg;
|
2192 |
|
|
|
2193 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
2194 |
|
|
* that the value in the Verification Tag field of the
|
2195 |
|
|
* received SCTP packet matches its own Tag. If the received
|
2196 |
|
|
* Verification Tag value does not match the receiver's own
|
2197 |
|
|
* tag value, the receiver shall silently discard the packet...
|
2198 |
|
|
*/
|
2199 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
2200 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2201 |
|
|
|
2202 |
|
|
cwr = (sctp_cwrhdr_t *) chunk->skb->data;
|
2203 |
|
|
skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
|
2204 |
|
|
|
2205 |
|
|
cwr->lowest_tsn = ntohl(cwr->lowest_tsn);
|
2206 |
|
|
|
2207 |
|
|
/* Does this CWR ack the last sent congestion notification? */
|
2208 |
|
|
if (TSN_lte(asoc->last_ecne_tsn, cwr->lowest_tsn)) {
|
2209 |
|
|
/* Stop sending ECNE. */
|
2210 |
|
|
sctp_add_cmd_sf(commands,
|
2211 |
|
|
SCTP_CMD_ECN_CWR,
|
2212 |
|
|
SCTP_U32(cwr->lowest_tsn));
|
2213 |
|
|
}
|
2214 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2215 |
|
|
}
|
2216 |
|
|
|
2217 |
|
|
/*
|
2218 |
|
|
* sctp_sf_do_ecne
|
2219 |
|
|
*
|
2220 |
|
|
* Section: Appendix A: Explicit Congestion Notification
|
2221 |
|
|
*
|
2222 |
|
|
* ECN-Echo
|
2223 |
|
|
*
|
2224 |
|
|
* RFC 2481 details a specific bit for a receiver to send back in its
|
2225 |
|
|
* TCP acknowledgements to notify the sender of the Congestion
|
2226 |
|
|
* Experienced (CE) bit having arrived from the network. For SCTP this
|
2227 |
|
|
* same indication is made by including the ECNE chunk. This chunk
|
2228 |
|
|
* contains one data element, i.e. the lowest TSN associated with the IP
|
2229 |
|
|
* datagram marked with the CE bit.....
|
2230 |
|
|
*
|
2231 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2232 |
|
|
* Inputs
|
2233 |
|
|
* (endpoint, asoc, chunk)
|
2234 |
|
|
*
|
2235 |
|
|
* Outputs
|
2236 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2237 |
|
|
*
|
2238 |
|
|
* The return value is the disposition of the chunk.
|
2239 |
|
|
*/
|
2240 |
|
|
sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
|
2241 |
|
|
const struct sctp_association *asoc,
|
2242 |
|
|
const sctp_subtype_t type,
|
2243 |
|
|
void *arg,
|
2244 |
|
|
sctp_cmd_seq_t *commands)
|
2245 |
|
|
{
|
2246 |
|
|
sctp_ecnehdr_t *ecne;
|
2247 |
|
|
struct sctp_chunk *chunk = arg;
|
2248 |
|
|
|
2249 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
2250 |
|
|
* that the value in the Verification Tag field of the
|
2251 |
|
|
* received SCTP packet matches its own Tag. If the received
|
2252 |
|
|
* Verification Tag value does not match the receiver's own
|
2253 |
|
|
* tag value, the receiver shall silently discard the packet...
|
2254 |
|
|
*/
|
2255 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
2256 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2257 |
|
|
|
2258 |
|
|
ecne = (sctp_ecnehdr_t *) chunk->skb->data;
|
2259 |
|
|
skb_pull(chunk->skb, sizeof(sctp_ecnehdr_t));
|
2260 |
|
|
|
2261 |
|
|
/* If this is a newer ECNE than the last CWR packet we sent out */
|
2262 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ECN_ECNE,
|
2263 |
|
|
SCTP_U32(ntohl(ecne->lowest_tsn)));
|
2264 |
|
|
|
2265 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2266 |
|
|
}
|
2267 |
|
|
|
2268 |
|
|
/*
|
2269 |
|
|
* Section: 6.2 Acknowledgement on Reception of DATA Chunks
|
2270 |
|
|
*
|
2271 |
|
|
* The SCTP endpoint MUST always acknowledge the reception of each valid
|
2272 |
|
|
* DATA chunk.
|
2273 |
|
|
*
|
2274 |
|
|
* The guidelines on delayed acknowledgement algorithm specified in
|
2275 |
|
|
* Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an
|
2276 |
|
|
* acknowledgement SHOULD be generated for at least every second packet
|
2277 |
|
|
* (not every second DATA chunk) received, and SHOULD be generated within
|
2278 |
|
|
* 200 ms of the arrival of any unacknowledged DATA chunk. In some
|
2279 |
|
|
* situations it may be beneficial for an SCTP transmitter to be more
|
2280 |
|
|
* conservative than the algorithms detailed in this document allow.
|
2281 |
|
|
* However, an SCTP transmitter MUST NOT be more aggressive than the
|
2282 |
|
|
* following algorithms allow.
|
2283 |
|
|
*
|
2284 |
|
|
* A SCTP receiver MUST NOT generate more than one SACK for every
|
2285 |
|
|
* incoming packet, other than to update the offered window as the
|
2286 |
|
|
* receiving application consumes new data.
|
2287 |
|
|
*
|
2288 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2289 |
|
|
*
|
2290 |
|
|
* Inputs
|
2291 |
|
|
* (endpoint, asoc, chunk)
|
2292 |
|
|
*
|
2293 |
|
|
* Outputs
|
2294 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2295 |
|
|
*
|
2296 |
|
|
* The return value is the disposition of the chunk.
|
2297 |
|
|
*/
|
2298 |
|
|
sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
|
2299 |
|
|
const struct sctp_association *asoc,
|
2300 |
|
|
const sctp_subtype_t type,
|
2301 |
|
|
void *arg,
|
2302 |
|
|
sctp_cmd_seq_t *commands)
|
2303 |
|
|
{
|
2304 |
|
|
struct sctp_chunk *chunk = arg;
|
2305 |
|
|
sctp_datahdr_t *data_hdr;
|
2306 |
|
|
struct sctp_chunk *err;
|
2307 |
|
|
size_t datalen;
|
2308 |
|
|
sctp_verb_t deliver;
|
2309 |
|
|
int tmp;
|
2310 |
|
|
__u32 tsn;
|
2311 |
|
|
|
2312 |
|
|
/* RFC 2960 8.5 Verification Tag
|
2313 |
|
|
*
|
2314 |
|
|
* When receiving an SCTP packet, the endpoint MUST ensure
|
2315 |
|
|
* that the value in the Verification Tag field of the
|
2316 |
|
|
* received SCTP packet matches its own Tag.
|
2317 |
|
|
*/
|
2318 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
|
2319 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
|
2320 |
|
|
SCTP_NULL());
|
2321 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2322 |
|
|
}
|
2323 |
|
|
|
2324 |
|
|
data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
|
2325 |
|
|
skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
|
2326 |
|
|
|
2327 |
|
|
tsn = ntohl(data_hdr->tsn);
|
2328 |
|
|
SCTP_DEBUG_PRINTK("eat_data: TSN 0x%x.\n", tsn);
|
2329 |
|
|
|
2330 |
|
|
/* ASSERT: Now skb->data is really the user data. */
|
2331 |
|
|
|
2332 |
|
|
/* Process ECN based congestion.
|
2333 |
|
|
*
|
2334 |
|
|
* Since the chunk structure is reused for all chunks within
|
2335 |
|
|
* a packet, we use ecn_ce_done to track if we've already
|
2336 |
|
|
* done CE processing for this packet.
|
2337 |
|
|
*
|
2338 |
|
|
* We need to do ECN processing even if we plan to discard the
|
2339 |
|
|
* chunk later.
|
2340 |
|
|
*/
|
2341 |
|
|
|
2342 |
|
|
if (!chunk->ecn_ce_done) {
|
2343 |
|
|
struct sctp_af *af;
|
2344 |
|
|
chunk->ecn_ce_done = 1;
|
2345 |
|
|
|
2346 |
|
|
af = sctp_get_af_specific(
|
2347 |
|
|
ipver2af(chunk->skb->nh.iph->version));
|
2348 |
|
|
|
2349 |
|
|
if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
|
2350 |
|
|
/* Do real work as sideffect. */
|
2351 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
|
2352 |
|
|
SCTP_U32(tsn));
|
2353 |
|
|
}
|
2354 |
|
|
}
|
2355 |
|
|
|
2356 |
|
|
tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
|
2357 |
|
|
if (tmp < 0) {
|
2358 |
|
|
/* The TSN is too high--silently discard the chunk and
|
2359 |
|
|
* count on it getting retransmitted later.
|
2360 |
|
|
*/
|
2361 |
|
|
goto discard_noforce;
|
2362 |
|
|
} else if (tmp > 0) {
|
2363 |
|
|
/* This is a duplicate. Record it. */
|
2364 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
|
2365 |
|
|
goto discard_force;
|
2366 |
|
|
}
|
2367 |
|
|
|
2368 |
|
|
/* This is a new TSN. */
|
2369 |
|
|
|
2370 |
|
|
/* Discard if there is no room in the receive window.
|
2371 |
|
|
* Actually, allow a little bit of overflow (up to a MTU).
|
2372 |
|
|
*/
|
2373 |
|
|
datalen = ntohs(chunk->chunk_hdr->length);
|
2374 |
|
|
datalen -= sizeof(sctp_data_chunk_t);
|
2375 |
|
|
|
2376 |
|
|
deliver = SCTP_CMD_CHUNK_ULP;
|
2377 |
|
|
|
2378 |
|
|
/* Think about partial delivery. */
|
2379 |
|
|
if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) {
|
2380 |
|
|
|
2381 |
|
|
/* Even if we don't accept this chunk there is
|
2382 |
|
|
* memory pressure.
|
2383 |
|
|
*/
|
2384 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PART_DELIVER, SCTP_NULL());
|
2385 |
|
|
}
|
2386 |
|
|
|
2387 |
|
|
/* Spill over rwnd a little bit. Note: While allowed, this spill over
|
2388 |
|
|
* seems a bit troublesome in that frag_point varies based on
|
2389 |
|
|
* PMTU. In cases, such as loopback, this might be a rather
|
2390 |
|
|
* large spill over.
|
2391 |
|
|
*/
|
2392 |
|
|
if (!asoc->rwnd || asoc->rwnd_over ||
|
2393 |
|
|
(datalen > asoc->rwnd + asoc->frag_point)) {
|
2394 |
|
|
|
2395 |
|
|
/* If this is the next TSN, consider reneging to make
|
2396 |
|
|
* room. Note: Playing nice with a confused sender. A
|
2397 |
|
|
* malicious sender can still eat up all our buffer
|
2398 |
|
|
* space and in the future we may want to detect and
|
2399 |
|
|
* do more drastic reneging.
|
2400 |
|
|
*/
|
2401 |
|
|
if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) &&
|
2402 |
|
|
(sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) {
|
2403 |
|
|
SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn);
|
2404 |
|
|
deliver = SCTP_CMD_RENEGE;
|
2405 |
|
|
} else {
|
2406 |
|
|
SCTP_DEBUG_PRINTK("Discard tsn: %u len: %Zd, "
|
2407 |
|
|
"rwnd: %d\n", tsn, datalen,
|
2408 |
|
|
asoc->rwnd);
|
2409 |
|
|
goto discard_force;
|
2410 |
|
|
}
|
2411 |
|
|
}
|
2412 |
|
|
|
2413 |
|
|
/*
|
2414 |
|
|
* Section 3.3.10.9 No User Data (9)
|
2415 |
|
|
*
|
2416 |
|
|
* Cause of error
|
2417 |
|
|
* ---------------
|
2418 |
|
|
* No User Data: This error cause is returned to the originator of a
|
2419 |
|
|
* DATA chunk if a received DATA chunk has no user data.
|
2420 |
|
|
*/
|
2421 |
|
|
if (unlikely(0 == datalen)) {
|
2422 |
|
|
err = sctp_make_abort_no_data(asoc, chunk, tsn);
|
2423 |
|
|
if (err) {
|
2424 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
2425 |
|
|
SCTP_CHUNK(err));
|
2426 |
|
|
}
|
2427 |
|
|
/* We are going to ABORT, so we might as well stop
|
2428 |
|
|
* processing the rest of the chunks in the packet.
|
2429 |
|
|
*/
|
2430 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
|
2431 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
2432 |
|
|
SCTP_U32(SCTP_ERROR_NO_DATA));
|
2433 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
2434 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
2435 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2436 |
|
|
}
|
2437 |
|
|
|
2438 |
|
|
/* If definately accepting the DATA chunk, record its TSN, otherwise
|
2439 |
|
|
* wait for renege processing.
|
2440 |
|
|
*/
|
2441 |
|
|
if (SCTP_CMD_CHUNK_ULP == deliver)
|
2442 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
|
2443 |
|
|
|
2444 |
|
|
/* Note: Some chunks may get overcounted (if we drop) or overcounted
|
2445 |
|
|
* if we renege and the chunk arrives again.
|
2446 |
|
|
*/
|
2447 |
|
|
if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
|
2448 |
|
|
SCTP_INC_STATS(SctpInUnorderChunks);
|
2449 |
|
|
else
|
2450 |
|
|
SCTP_INC_STATS(SctpInOrderChunks);
|
2451 |
|
|
|
2452 |
|
|
/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
|
2453 |
|
|
*
|
2454 |
|
|
* If an endpoint receive a DATA chunk with an invalid stream
|
2455 |
|
|
* identifier, it shall acknowledge the reception of the DATA chunk
|
2456 |
|
|
* following the normal procedure, immediately send an ERROR chunk
|
2457 |
|
|
* with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
|
2458 |
|
|
* and discard the DATA chunk.
|
2459 |
|
|
*/
|
2460 |
|
|
if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
|
2461 |
|
|
err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
|
2462 |
|
|
&data_hdr->stream,
|
2463 |
|
|
sizeof(data_hdr->stream));
|
2464 |
|
|
if (err)
|
2465 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
2466 |
|
|
SCTP_CHUNK(err));
|
2467 |
|
|
goto discard_noforce;
|
2468 |
|
|
}
|
2469 |
|
|
|
2470 |
|
|
/* Send the data up to the user. Note: Schedule the
|
2471 |
|
|
* SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
|
2472 |
|
|
* chunk needs the updated rwnd.
|
2473 |
|
|
*/
|
2474 |
|
|
sctp_add_cmd_sf(commands, deliver, SCTP_CHUNK(chunk));
|
2475 |
|
|
|
2476 |
|
|
if (asoc->autoclose) {
|
2477 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
2478 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
|
2479 |
|
|
}
|
2480 |
|
|
|
2481 |
|
|
/* If this is the last chunk in a packet, we need to count it
|
2482 |
|
|
* toward sack generation. Note that we need to SACK every
|
2483 |
|
|
* OTHER packet containing data chunks, EVEN IF WE DISCARD
|
2484 |
|
|
* THEM. We elect to NOT generate SACK's if the chunk fails
|
2485 |
|
|
* the verification tag test.
|
2486 |
|
|
*
|
2487 |
|
|
* RFC 2960 6.2 Acknowledgement on Reception of DATA Chunks
|
2488 |
|
|
*
|
2489 |
|
|
* The SCTP endpoint MUST always acknowledge the reception of
|
2490 |
|
|
* each valid DATA chunk.
|
2491 |
|
|
*
|
2492 |
|
|
* The guidelines on delayed acknowledgement algorithm
|
2493 |
|
|
* specified in Section 4.2 of [RFC2581] SHOULD be followed.
|
2494 |
|
|
* Specifically, an acknowledgement SHOULD be generated for at
|
2495 |
|
|
* least every second packet (not every second DATA chunk)
|
2496 |
|
|
* received, and SHOULD be generated within 200 ms of the
|
2497 |
|
|
* arrival of any unacknowledged DATA chunk. In some
|
2498 |
|
|
* situations it may be beneficial for an SCTP transmitter to
|
2499 |
|
|
* be more conservative than the algorithms detailed in this
|
2500 |
|
|
* document allow. However, an SCTP transmitter MUST NOT be
|
2501 |
|
|
* more aggressive than the following algorithms allow.
|
2502 |
|
|
*/
|
2503 |
|
|
if (chunk->end_of_packet) {
|
2504 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
|
2505 |
|
|
|
2506 |
|
|
/* Start the SACK timer. */
|
2507 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
2508 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
|
2509 |
|
|
}
|
2510 |
|
|
|
2511 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2512 |
|
|
|
2513 |
|
|
discard_force:
|
2514 |
|
|
/* RFC 2960 6.2 Acknowledgement on Reception of DATA Chunks
|
2515 |
|
|
*
|
2516 |
|
|
* When a packet arrives with duplicate DATA chunk(s) and with
|
2517 |
|
|
* no new DATA chunk(s), the endpoint MUST immediately send a
|
2518 |
|
|
* SACK with no delay. If a packet arrives with duplicate
|
2519 |
|
|
* DATA chunk(s) bundled with new DATA chunks, the endpoint
|
2520 |
|
|
* MAY immediately send a SACK. Normally receipt of duplicate
|
2521 |
|
|
* DATA chunks will occur when the original SACK chunk was lost
|
2522 |
|
|
* and the peer's RTO has expired. The duplicate TSN number(s)
|
2523 |
|
|
* SHOULD be reported in the SACK as duplicate.
|
2524 |
|
|
*/
|
2525 |
|
|
/* In our case, we split the MAY SACK advice up whether or not
|
2526 |
|
|
* the last chunk is a duplicate.'
|
2527 |
|
|
*/
|
2528 |
|
|
if (chunk->end_of_packet)
|
2529 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
|
2530 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
2531 |
|
|
|
2532 |
|
|
discard_noforce:
|
2533 |
|
|
if (chunk->end_of_packet) {
|
2534 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
|
2535 |
|
|
|
2536 |
|
|
/* Start the SACK timer. */
|
2537 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
2538 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
|
2539 |
|
|
}
|
2540 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
2541 |
|
|
}
|
2542 |
|
|
|
2543 |
|
|
/*
|
2544 |
|
|
* sctp_sf_eat_data_fast_4_4
|
2545 |
|
|
*
|
2546 |
|
|
* Section: 4 (4)
|
2547 |
|
|
* (4) In SHUTDOWN-SENT state the endpoint MUST acknowledge any received
|
2548 |
|
|
* DATA chunks without delay.
|
2549 |
|
|
*
|
2550 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2551 |
|
|
* Inputs
|
2552 |
|
|
* (endpoint, asoc, chunk)
|
2553 |
|
|
*
|
2554 |
|
|
* Outputs
|
2555 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2556 |
|
|
*
|
2557 |
|
|
* The return value is the disposition of the chunk.
|
2558 |
|
|
*/
|
2559 |
|
|
sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
|
2560 |
|
|
const struct sctp_association *asoc,
|
2561 |
|
|
const sctp_subtype_t type,
|
2562 |
|
|
void *arg,
|
2563 |
|
|
sctp_cmd_seq_t *commands)
|
2564 |
|
|
{
|
2565 |
|
|
struct sctp_chunk *chunk = arg;
|
2566 |
|
|
sctp_datahdr_t *data_hdr;
|
2567 |
|
|
struct sctp_chunk *err;
|
2568 |
|
|
size_t datalen;
|
2569 |
|
|
int tmp;
|
2570 |
|
|
__u32 tsn;
|
2571 |
|
|
|
2572 |
|
|
/* RFC 2960 8.5 Verification Tag
|
2573 |
|
|
*
|
2574 |
|
|
* When receiving an SCTP packet, the endpoint MUST ensure
|
2575 |
|
|
* that the value in the Verification Tag field of the
|
2576 |
|
|
* received SCTP packet matches its own Tag.
|
2577 |
|
|
*/
|
2578 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) {
|
2579 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
|
2580 |
|
|
SCTP_NULL());
|
2581 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2582 |
|
|
}
|
2583 |
|
|
|
2584 |
|
|
data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *) chunk->skb->data;
|
2585 |
|
|
skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
|
2586 |
|
|
|
2587 |
|
|
tsn = ntohl(data_hdr->tsn);
|
2588 |
|
|
|
2589 |
|
|
SCTP_DEBUG_PRINTK("eat_data: TSN 0x%x.\n", tsn);
|
2590 |
|
|
|
2591 |
|
|
/* ASSERT: Now skb->data is really the user data. */
|
2592 |
|
|
|
2593 |
|
|
/* Process ECN based congestion.
|
2594 |
|
|
*
|
2595 |
|
|
* Since the chunk structure is reused for all chunks within
|
2596 |
|
|
* a packet, we use ecn_ce_done to track if we've already
|
2597 |
|
|
* done CE processing for this packet.
|
2598 |
|
|
*
|
2599 |
|
|
* We need to do ECN processing even if we plan to discard the
|
2600 |
|
|
* chunk later.
|
2601 |
|
|
*/
|
2602 |
|
|
if (!chunk->ecn_ce_done) {
|
2603 |
|
|
struct sctp_af *af;
|
2604 |
|
|
chunk->ecn_ce_done = 1;
|
2605 |
|
|
|
2606 |
|
|
af = sctp_get_af_specific(
|
2607 |
|
|
ipver2af(chunk->skb->nh.iph->version));
|
2608 |
|
|
|
2609 |
|
|
if (af && af->is_ce(chunk->skb) && asoc->peer.ecn_capable) {
|
2610 |
|
|
/* Do real work as sideffect. */
|
2611 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,
|
2612 |
|
|
SCTP_U32(tsn));
|
2613 |
|
|
}
|
2614 |
|
|
}
|
2615 |
|
|
|
2616 |
|
|
tmp = sctp_tsnmap_check(&asoc->peer.tsn_map, tsn);
|
2617 |
|
|
if (tmp < 0) {
|
2618 |
|
|
/* The TSN is too high--silently discard the chunk and
|
2619 |
|
|
* count on it getting retransmitted later.
|
2620 |
|
|
*/
|
2621 |
|
|
goto gen_shutdown;
|
2622 |
|
|
} else if (tmp > 0) {
|
2623 |
|
|
/* This is a duplicate. Record it. */
|
2624 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_DUP, SCTP_U32(tsn));
|
2625 |
|
|
goto gen_shutdown;
|
2626 |
|
|
}
|
2627 |
|
|
|
2628 |
|
|
/* This is a new TSN. */
|
2629 |
|
|
|
2630 |
|
|
datalen = ntohs(chunk->chunk_hdr->length);
|
2631 |
|
|
datalen -= sizeof(sctp_data_chunk_t);
|
2632 |
|
|
|
2633 |
|
|
/*
|
2634 |
|
|
* Section 3.3.10.9 No User Data (9)
|
2635 |
|
|
*
|
2636 |
|
|
* Cause of error
|
2637 |
|
|
* ---------------
|
2638 |
|
|
* No User Data: This error cause is returned to the originator of a
|
2639 |
|
|
* DATA chunk if a received DATA chunk has no user data.
|
2640 |
|
|
*/
|
2641 |
|
|
if (unlikely(0 == datalen)) {
|
2642 |
|
|
err = sctp_make_abort_no_data(asoc, chunk, tsn);
|
2643 |
|
|
if (err) {
|
2644 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
2645 |
|
|
SCTP_CHUNK(err));
|
2646 |
|
|
}
|
2647 |
|
|
/* We are going to ABORT, so we might as well stop
|
2648 |
|
|
* processing the rest of the chunks in the packet.
|
2649 |
|
|
*/
|
2650 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
|
2651 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
2652 |
|
|
SCTP_U32(SCTP_ERROR_NO_DATA));
|
2653 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
2654 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
2655 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2656 |
|
|
}
|
2657 |
|
|
|
2658 |
|
|
/* We are accepting this DATA chunk. */
|
2659 |
|
|
|
2660 |
|
|
/* Record the fact that we have received this TSN. */
|
2661 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
|
2662 |
|
|
|
2663 |
|
|
if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
|
2664 |
|
|
SCTP_INC_STATS(SctpInUnorderChunks);
|
2665 |
|
|
else
|
2666 |
|
|
SCTP_INC_STATS(SctpInOrderChunks);
|
2667 |
|
|
|
2668 |
|
|
/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
|
2669 |
|
|
*
|
2670 |
|
|
* If an endpoint receive a DATA chunk with an invalid stream
|
2671 |
|
|
* identifier, it shall acknowledge the reception of the DATA chunk
|
2672 |
|
|
* following the normal procedure, immediately send an ERROR chunk
|
2673 |
|
|
* with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
|
2674 |
|
|
* and discard the DATA chunk.
|
2675 |
|
|
*/
|
2676 |
|
|
if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
|
2677 |
|
|
err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM,
|
2678 |
|
|
&data_hdr->stream,
|
2679 |
|
|
sizeof(data_hdr->stream));
|
2680 |
|
|
if (err) {
|
2681 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
2682 |
|
|
SCTP_CHUNK(err));
|
2683 |
|
|
}
|
2684 |
|
|
}
|
2685 |
|
|
|
2686 |
|
|
/* Go a head and force a SACK, since we are shutting down. */
|
2687 |
|
|
gen_shutdown:
|
2688 |
|
|
/* Implementor's Guide.
|
2689 |
|
|
*
|
2690 |
|
|
* While in SHUTDOWN-SENT state, the SHUTDOWN sender MUST immediately
|
2691 |
|
|
* respond to each received packet containing one or more DATA chunk(s)
|
2692 |
|
|
* with a SACK, a SHUTDOWN chunk, and restart the T2-shutdown timer
|
2693 |
|
|
*/
|
2694 |
|
|
if (chunk->end_of_packet) {
|
2695 |
|
|
/* We must delay the chunk creation since the cumulative
|
2696 |
|
|
* TSN has not been updated yet.
|
2697 |
|
|
*/
|
2698 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SHUTDOWN, SCTP_NULL());
|
2699 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
|
2700 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
2701 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
2702 |
|
|
}
|
2703 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2704 |
|
|
}
|
2705 |
|
|
|
2706 |
|
|
/*
|
2707 |
|
|
* Section: 6.2 Processing a Received SACK
|
2708 |
|
|
* D) Any time a SACK arrives, the endpoint performs the following:
|
2709 |
|
|
*
|
2710 |
|
|
* i) If Cumulative TSN Ack is less than the Cumulative TSN Ack Point,
|
2711 |
|
|
* then drop the SACK. Since Cumulative TSN Ack is monotonically
|
2712 |
|
|
* increasing, a SACK whose Cumulative TSN Ack is less than the
|
2713 |
|
|
* Cumulative TSN Ack Point indicates an out-of-order SACK.
|
2714 |
|
|
*
|
2715 |
|
|
* ii) Set rwnd equal to the newly received a_rwnd minus the number
|
2716 |
|
|
* of bytes still outstanding after processing the Cumulative TSN Ack
|
2717 |
|
|
* and the Gap Ack Blocks.
|
2718 |
|
|
*
|
2719 |
|
|
* iii) If the SACK is missing a TSN that was previously
|
2720 |
|
|
* acknowledged via a Gap Ack Block (e.g., the data receiver
|
2721 |
|
|
* reneged on the data), then mark the corresponding DATA chunk
|
2722 |
|
|
* as available for retransmit: Mark it as missing for fast
|
2723 |
|
|
* retransmit as described in Section 7.2.4 and if no retransmit
|
2724 |
|
|
* timer is running for the destination address to which the DATA
|
2725 |
|
|
* chunk was originally transmitted, then T3-rtx is started for
|
2726 |
|
|
* that destination address.
|
2727 |
|
|
*
|
2728 |
|
|
* Verification Tag: 8.5 Verification Tag [Normal verification]
|
2729 |
|
|
*
|
2730 |
|
|
* Inputs
|
2731 |
|
|
* (endpoint, asoc, chunk)
|
2732 |
|
|
*
|
2733 |
|
|
* Outputs
|
2734 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
2735 |
|
|
*
|
2736 |
|
|
* The return value is the disposition of the chunk.
|
2737 |
|
|
*/
|
2738 |
|
|
sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
|
2739 |
|
|
const struct sctp_association *asoc,
|
2740 |
|
|
const sctp_subtype_t type,
|
2741 |
|
|
void *arg,
|
2742 |
|
|
sctp_cmd_seq_t *commands)
|
2743 |
|
|
{
|
2744 |
|
|
struct sctp_chunk *chunk = arg;
|
2745 |
|
|
sctp_sackhdr_t *sackh;
|
2746 |
|
|
__u32 ctsn;
|
2747 |
|
|
|
2748 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
2749 |
|
|
* that the value in the Verification Tag field of the
|
2750 |
|
|
* received SCTP packet matches its own Tag. ...
|
2751 |
|
|
*/
|
2752 |
|
|
if (ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
2753 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2754 |
|
|
|
2755 |
|
|
/* Pull the SACK chunk from the data buffer */
|
2756 |
|
|
sackh = sctp_sm_pull_sack(chunk);
|
2757 |
|
|
/* Was this a bogus SACK? */
|
2758 |
|
|
if (!sackh)
|
2759 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2760 |
|
|
chunk->subh.sack_hdr = sackh;
|
2761 |
|
|
ctsn = ntohl(sackh->cum_tsn_ack);
|
2762 |
|
|
|
2763 |
|
|
/* i) If Cumulative TSN Ack is less than the Cumulative TSN
|
2764 |
|
|
* Ack Point, then drop the SACK. Since Cumulative TSN
|
2765 |
|
|
* Ack is monotonically increasing, a SACK whose
|
2766 |
|
|
* Cumulative TSN Ack is less than the Cumulative TSN Ack
|
2767 |
|
|
* Point indicates an out-of-order SACK.
|
2768 |
|
|
*/
|
2769 |
|
|
if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
|
2770 |
|
|
SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
|
2771 |
|
|
SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
|
2772 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
2773 |
|
|
}
|
2774 |
|
|
|
2775 |
|
|
/* Return this SACK for further processing. */
|
2776 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh));
|
2777 |
|
|
|
2778 |
|
|
/* Note: We do the rest of the work on the PROCESS_SACK
|
2779 |
|
|
* sideeffect.
|
2780 |
|
|
*/
|
2781 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2782 |
|
|
}
|
2783 |
|
|
|
2784 |
|
|
/*
|
2785 |
|
|
* Generate an ABORT in response to a packet.
|
2786 |
|
|
*
|
2787 |
|
|
* Section: 8.4 Handle "Out of the blue" Packets
|
2788 |
|
|
*
|
2789 |
|
|
* 8) The receiver should respond to the sender of the OOTB packet
|
2790 |
|
|
* with an ABORT. When sending the ABORT, the receiver of the
|
2791 |
|
|
* OOTB packet MUST fill in the Verification Tag field of the
|
2792 |
|
|
* outbound packet with the value found in the Verification Tag
|
2793 |
|
|
* field of the OOTB packet and set the T-bit in the Chunk Flags
|
2794 |
|
|
* to indicate that no TCB was found. After sending this ABORT,
|
2795 |
|
|
* the receiver of the OOTB packet shall discard the OOTB packet
|
2796 |
|
|
* and take no further action.
|
2797 |
|
|
*
|
2798 |
|
|
* Verification Tag:
|
2799 |
|
|
*
|
2800 |
|
|
* The return value is the disposition of the chunk.
|
2801 |
|
|
*/
|
2802 |
|
|
sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
|
2803 |
|
|
const struct sctp_association *asoc,
|
2804 |
|
|
const sctp_subtype_t type,
|
2805 |
|
|
void *arg,
|
2806 |
|
|
sctp_cmd_seq_t *commands)
|
2807 |
|
|
{
|
2808 |
|
|
struct sctp_packet *packet = NULL;
|
2809 |
|
|
struct sctp_chunk *chunk = arg;
|
2810 |
|
|
struct sctp_chunk *abort;
|
2811 |
|
|
|
2812 |
|
|
packet = sctp_ootb_pkt_new(asoc, chunk);
|
2813 |
|
|
|
2814 |
|
|
if (packet) {
|
2815 |
|
|
/* Make an ABORT. The T bit will be set if the asoc
|
2816 |
|
|
* is NULL.
|
2817 |
|
|
*/
|
2818 |
|
|
abort = sctp_make_abort(asoc, chunk, 0);
|
2819 |
|
|
if (!abort) {
|
2820 |
|
|
sctp_ootb_pkt_free(packet);
|
2821 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
2822 |
|
|
}
|
2823 |
|
|
|
2824 |
|
|
/* Set the skb to the belonging sock for accounting. */
|
2825 |
|
|
abort->skb->sk = ep->base.sk;
|
2826 |
|
|
|
2827 |
|
|
sctp_packet_append_chunk(packet, abort);
|
2828 |
|
|
|
2829 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
2830 |
|
|
SCTP_PACKET(packet));
|
2831 |
|
|
|
2832 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
2833 |
|
|
|
2834 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2835 |
|
|
}
|
2836 |
|
|
|
2837 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
2838 |
|
|
}
|
2839 |
|
|
|
2840 |
|
|
/*
|
2841 |
|
|
* Received an ERROR chunk from peer. Generate SCTP_REMOTE_ERROR
|
2842 |
|
|
* event as ULP notification for each cause included in the chunk.
|
2843 |
|
|
*
|
2844 |
|
|
* API 5.3.1.3 - SCTP_REMOTE_ERROR
|
2845 |
|
|
*
|
2846 |
|
|
* The return value is the disposition of the chunk.
|
2847 |
|
|
*/
|
2848 |
|
|
sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
|
2849 |
|
|
const struct sctp_association *asoc,
|
2850 |
|
|
const sctp_subtype_t type,
|
2851 |
|
|
void *arg,
|
2852 |
|
|
sctp_cmd_seq_t *commands)
|
2853 |
|
|
{
|
2854 |
|
|
struct sctp_chunk *chunk = arg;
|
2855 |
|
|
struct sctp_ulpevent *ev;
|
2856 |
|
|
|
2857 |
|
|
while (chunk->chunk_end > chunk->skb->data) {
|
2858 |
|
|
ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
|
2859 |
|
|
GFP_ATOMIC);
|
2860 |
|
|
if (!ev)
|
2861 |
|
|
goto nomem;
|
2862 |
|
|
|
2863 |
|
|
if (!sctp_add_cmd(commands, SCTP_CMD_EVENT_ULP,
|
2864 |
|
|
SCTP_ULPEVENT(ev))) {
|
2865 |
|
|
sctp_ulpevent_free(ev);
|
2866 |
|
|
goto nomem;
|
2867 |
|
|
}
|
2868 |
|
|
|
2869 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
|
2870 |
|
|
SCTP_CHUNK(chunk));
|
2871 |
|
|
}
|
2872 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
2873 |
|
|
|
2874 |
|
|
nomem:
|
2875 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
2876 |
|
|
}
|
2877 |
|
|
|
2878 |
|
|
/*
|
2879 |
|
|
* Process an inbound SHUTDOWN ACK.
|
2880 |
|
|
*
|
2881 |
|
|
* From Section 9.2:
|
2882 |
|
|
* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall
|
2883 |
|
|
* stop the T2-shutdown timer, send a SHUTDOWN COMPLETE chunk to its
|
2884 |
|
|
* peer, and remove all record of the association.
|
2885 |
|
|
*
|
2886 |
|
|
* The return value is the disposition.
|
2887 |
|
|
*/
|
2888 |
|
|
sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
|
2889 |
|
|
const struct sctp_association *asoc,
|
2890 |
|
|
const sctp_subtype_t type,
|
2891 |
|
|
void *arg,
|
2892 |
|
|
sctp_cmd_seq_t *commands)
|
2893 |
|
|
{
|
2894 |
|
|
struct sctp_chunk *chunk = arg;
|
2895 |
|
|
struct sctp_chunk *reply;
|
2896 |
|
|
struct sctp_ulpevent *ev;
|
2897 |
|
|
|
2898 |
|
|
/* 10.2 H) SHUTDOWN COMPLETE notification
|
2899 |
|
|
*
|
2900 |
|
|
* When SCTP completes the shutdown procedures (section 9.2) this
|
2901 |
|
|
* notification is passed to the upper layer.
|
2902 |
|
|
*/
|
2903 |
|
|
ev = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_SHUTDOWN_COMP,
|
2904 |
|
|
0, 0, 0, GFP_ATOMIC);
|
2905 |
|
|
if (!ev)
|
2906 |
|
|
goto nomem;
|
2907 |
|
|
|
2908 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
|
2909 |
|
|
|
2910 |
|
|
/* Upon the receipt of the SHUTDOWN ACK, the SHUTDOWN sender shall
|
2911 |
|
|
* stop the T2-shutdown timer,
|
2912 |
|
|
*/
|
2913 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
2914 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
2915 |
|
|
|
2916 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
2917 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
2918 |
|
|
|
2919 |
|
|
/* ...send a SHUTDOWN COMPLETE chunk to its peer, */
|
2920 |
|
|
reply = sctp_make_shutdown_complete(asoc, chunk);
|
2921 |
|
|
if (!reply)
|
2922 |
|
|
goto nomem;
|
2923 |
|
|
|
2924 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
2925 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
2926 |
|
|
SCTP_INC_STATS(SctpShutdowns);
|
2927 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
2928 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
2929 |
|
|
|
2930 |
|
|
/* ...and remove all record of the association. */
|
2931 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
2932 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
2933 |
|
|
|
2934 |
|
|
nomem:
|
2935 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
2936 |
|
|
}
|
2937 |
|
|
|
2938 |
|
|
/*
|
2939 |
|
|
* RFC 2960, 8.4 - Handle "Out of the blue" Packets
|
2940 |
|
|
* 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
|
2941 |
|
|
* respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
|
2942 |
|
|
* When sending the SHUTDOWN COMPLETE, the receiver of the OOTB
|
2943 |
|
|
* packet must fill in the Verification Tag field of the outbound
|
2944 |
|
|
* packet with the Verification Tag received in the SHUTDOWN ACK and
|
2945 |
|
|
* set the T-bit in the Chunk Flags to indicate that no TCB was
|
2946 |
|
|
* found. Otherwise,
|
2947 |
|
|
*
|
2948 |
|
|
* 8) The receiver should respond to the sender of the OOTB packet with
|
2949 |
|
|
* an ABORT. When sending the ABORT, the receiver of the OOTB packet
|
2950 |
|
|
* MUST fill in the Verification Tag field of the outbound packet
|
2951 |
|
|
* with the value found in the Verification Tag field of the OOTB
|
2952 |
|
|
* packet and set the T-bit in the Chunk Flags to indicate that no
|
2953 |
|
|
* TCB was found. After sending this ABORT, the receiver of the OOTB
|
2954 |
|
|
* packet shall discard the OOTB packet and take no further action.
|
2955 |
|
|
*/
|
2956 |
|
|
sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
|
2957 |
|
|
const struct sctp_association *asoc,
|
2958 |
|
|
const sctp_subtype_t type,
|
2959 |
|
|
void *arg,
|
2960 |
|
|
sctp_cmd_seq_t *commands)
|
2961 |
|
|
{
|
2962 |
|
|
struct sctp_chunk *chunk = arg;
|
2963 |
|
|
struct sk_buff *skb = chunk->skb;
|
2964 |
|
|
sctp_chunkhdr_t *ch;
|
2965 |
|
|
__u8 *ch_end;
|
2966 |
|
|
int ootb_shut_ack = 0;
|
2967 |
|
|
|
2968 |
|
|
SCTP_INC_STATS(SctpOutOfBlues);
|
2969 |
|
|
|
2970 |
|
|
ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
|
2971 |
|
|
do {
|
2972 |
|
|
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
|
2973 |
|
|
|
2974 |
|
|
if (SCTP_CID_SHUTDOWN_ACK == ch->type)
|
2975 |
|
|
ootb_shut_ack = 1;
|
2976 |
|
|
|
2977 |
|
|
ch = (sctp_chunkhdr_t *) ch_end;
|
2978 |
|
|
} while (ch_end < skb->tail);
|
2979 |
|
|
|
2980 |
|
|
if (ootb_shut_ack)
|
2981 |
|
|
sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
|
2982 |
|
|
else
|
2983 |
|
|
sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
|
2984 |
|
|
|
2985 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
2986 |
|
|
}
|
2987 |
|
|
|
2988 |
|
|
/*
|
2989 |
|
|
* Handle an "Out of the blue" SHUTDOWN ACK.
|
2990 |
|
|
*
|
2991 |
|
|
* Section: 8.4 5)
|
2992 |
|
|
* 5) If the packet contains a SHUTDOWN ACK chunk, the receiver should
|
2993 |
|
|
* respond to the sender of the OOTB packet with a SHUTDOWN COMPLETE.
|
2994 |
|
|
* When sending the SHUTDOWN COMPLETE, the receiver of the OOTB packet
|
2995 |
|
|
* must fill in the Verification Tag field of the outbound packet with
|
2996 |
|
|
* the Verification Tag received in the SHUTDOWN ACK and set the
|
2997 |
|
|
* T-bit in the Chunk Flags to indicate that no TCB was found.
|
2998 |
|
|
*
|
2999 |
|
|
* Inputs
|
3000 |
|
|
* (endpoint, asoc, type, arg, commands)
|
3001 |
|
|
*
|
3002 |
|
|
* Outputs
|
3003 |
|
|
* (sctp_disposition_t)
|
3004 |
|
|
*
|
3005 |
|
|
* The return value is the disposition of the chunk.
|
3006 |
|
|
*/
|
3007 |
|
|
sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
|
3008 |
|
|
const struct sctp_association *asoc,
|
3009 |
|
|
const sctp_subtype_t type,
|
3010 |
|
|
void *arg,
|
3011 |
|
|
sctp_cmd_seq_t *commands)
|
3012 |
|
|
{
|
3013 |
|
|
struct sctp_packet *packet = NULL;
|
3014 |
|
|
struct sctp_chunk *chunk = arg;
|
3015 |
|
|
struct sctp_chunk *shut;
|
3016 |
|
|
|
3017 |
|
|
packet = sctp_ootb_pkt_new(asoc, chunk);
|
3018 |
|
|
|
3019 |
|
|
if (packet) {
|
3020 |
|
|
/* Make an SHUTDOWN_COMPLETE.
|
3021 |
|
|
* The T bit will be set if the asoc is NULL.
|
3022 |
|
|
*/
|
3023 |
|
|
shut = sctp_make_shutdown_complete(asoc, chunk);
|
3024 |
|
|
if (!shut) {
|
3025 |
|
|
sctp_ootb_pkt_free(packet);
|
3026 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
3027 |
|
|
}
|
3028 |
|
|
|
3029 |
|
|
/* Set the skb to the belonging sock for accounting. */
|
3030 |
|
|
shut->skb->sk = ep->base.sk;
|
3031 |
|
|
|
3032 |
|
|
sctp_packet_append_chunk(packet, shut);
|
3033 |
|
|
|
3034 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
3035 |
|
|
SCTP_PACKET(packet));
|
3036 |
|
|
|
3037 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
3038 |
|
|
|
3039 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3040 |
|
|
}
|
3041 |
|
|
|
3042 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
3043 |
|
|
}
|
3044 |
|
|
|
3045 |
|
|
/*
|
3046 |
|
|
* Handle SHUTDOWN ACK in COOKIE_ECHOED or COOKIE_WAIT state.
|
3047 |
|
|
*
|
3048 |
|
|
* Verification Tag: 8.5.1 E) Rules for packet carrying a SHUTDOWN ACK
|
3049 |
|
|
* If the receiver is in COOKIE-ECHOED or COOKIE-WAIT state the
|
3050 |
|
|
* procedures in section 8.4 SHOULD be followed, in other words it
|
3051 |
|
|
* should be treated as an Out Of The Blue packet.
|
3052 |
|
|
* [This means that we do NOT check the Verification Tag on these
|
3053 |
|
|
* chunks. --piggy ]
|
3054 |
|
|
*
|
3055 |
|
|
*/
|
3056 |
|
|
sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
|
3057 |
|
|
const struct sctp_association *asoc,
|
3058 |
|
|
const sctp_subtype_t type,
|
3059 |
|
|
void *arg,
|
3060 |
|
|
sctp_cmd_seq_t *commands)
|
3061 |
|
|
{
|
3062 |
|
|
/* Although we do have an association in this case, it corresponds
|
3063 |
|
|
* to a restarted association. So the packet is treated as an OOTB
|
3064 |
|
|
* packet and the state function that handles OOTB SHUTDOWN_ACK is
|
3065 |
|
|
* called with a NULL association.
|
3066 |
|
|
*/
|
3067 |
|
|
return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands);
|
3068 |
|
|
}
|
3069 |
|
|
|
3070 |
|
|
/* ADDIP Section 4.2 Upon reception of an ASCONF Chunk. */
|
3071 |
|
|
sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
|
3072 |
|
|
const struct sctp_association *asoc,
|
3073 |
|
|
const sctp_subtype_t type, void *arg,
|
3074 |
|
|
sctp_cmd_seq_t *commands)
|
3075 |
|
|
{
|
3076 |
|
|
struct sctp_chunk *chunk = arg;
|
3077 |
|
|
struct sctp_chunk *asconf_ack = NULL;
|
3078 |
|
|
sctp_addiphdr_t *hdr;
|
3079 |
|
|
__u32 serial;
|
3080 |
|
|
|
3081 |
|
|
hdr = (sctp_addiphdr_t *)chunk->skb->data;
|
3082 |
|
|
serial = ntohl(hdr->serial);
|
3083 |
|
|
|
3084 |
|
|
/* ADDIP 4.2 C1) Compare the value of the serial number to the value
|
3085 |
|
|
* the endpoint stored in a new association variable
|
3086 |
|
|
* 'Peer-Serial-Number'.
|
3087 |
|
|
*/
|
3088 |
|
|
if (serial == asoc->peer.addip_serial + 1) {
|
3089 |
|
|
/* ADDIP 4.2 C2) If the value found in the serial number is
|
3090 |
|
|
* equal to the ('Peer-Serial-Number' + 1), the endpoint MUST
|
3091 |
|
|
* do V1-V5.
|
3092 |
|
|
*/
|
3093 |
|
|
asconf_ack = sctp_process_asconf((struct sctp_association *)
|
3094 |
|
|
asoc, chunk);
|
3095 |
|
|
if (!asconf_ack)
|
3096 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
3097 |
|
|
} else if (serial == asoc->peer.addip_serial) {
|
3098 |
|
|
/* ADDIP 4.2 C3) If the value found in the serial number is
|
3099 |
|
|
* equal to the value stored in the 'Peer-Serial-Number'
|
3100 |
|
|
* IMPLEMENTATION NOTE: As an optimization a receiver may wish
|
3101 |
|
|
* to save the last ASCONF-ACK for some predetermined period of * time and instead of re-processing the ASCONF (with the same
|
3102 |
|
|
* serial number) it may just re-transmit the ASCONF-ACK.
|
3103 |
|
|
*/
|
3104 |
|
|
if (asoc->addip_last_asconf_ack)
|
3105 |
|
|
asconf_ack = asoc->addip_last_asconf_ack;
|
3106 |
|
|
else
|
3107 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3108 |
|
|
} else {
|
3109 |
|
|
/* ADDIP 4.2 C4) Otherwise, the ASCONF Chunk is discarded since
|
3110 |
|
|
* it must be either a stale packet or from an attacker.
|
3111 |
|
|
*/
|
3112 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3113 |
|
|
}
|
3114 |
|
|
|
3115 |
|
|
/* ADDIP 4.2 C5) In both cases C2 and C3 the ASCONF-ACK MUST be sent
|
3116 |
|
|
* back to the source address contained in the IP header of the ASCONF
|
3117 |
|
|
* being responded to.
|
3118 |
|
|
*/
|
3119 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
|
3120 |
|
|
|
3121 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3122 |
|
|
}
|
3123 |
|
|
|
3124 |
|
|
/*
|
3125 |
|
|
* ADDIP Section 4.3 General rules for address manipulation
|
3126 |
|
|
* When building TLV parameters for the ASCONF Chunk that will add or
|
3127 |
|
|
* delete IP addresses the D0 to D13 rules should be applied:
|
3128 |
|
|
*/
|
3129 |
|
|
sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
|
3130 |
|
|
const struct sctp_association *asoc,
|
3131 |
|
|
const sctp_subtype_t type, void *arg,
|
3132 |
|
|
sctp_cmd_seq_t *commands)
|
3133 |
|
|
{
|
3134 |
|
|
struct sctp_chunk *asconf_ack = arg;
|
3135 |
|
|
struct sctp_chunk *last_asconf = asoc->addip_last_asconf;
|
3136 |
|
|
struct sctp_chunk *abort;
|
3137 |
|
|
sctp_addiphdr_t *addip_hdr;
|
3138 |
|
|
__u32 sent_serial, rcvd_serial;
|
3139 |
|
|
|
3140 |
|
|
addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
|
3141 |
|
|
rcvd_serial = ntohl(addip_hdr->serial);
|
3142 |
|
|
|
3143 |
|
|
if (last_asconf) {
|
3144 |
|
|
addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
|
3145 |
|
|
sent_serial = ntohl(addip_hdr->serial);
|
3146 |
|
|
} else {
|
3147 |
|
|
sent_serial = asoc->addip_serial - 1;
|
3148 |
|
|
}
|
3149 |
|
|
|
3150 |
|
|
/* D0) If an endpoint receives an ASCONF-ACK that is greater than or
|
3151 |
|
|
* equal to the next serial number to be used but no ASCONF chunk is
|
3152 |
|
|
* outstanding the endpoint MUST ABORT the association. Note that a
|
3153 |
|
|
* sequence number is greater than if it is no more than 2^^31-1
|
3154 |
|
|
* larger than the current sequence number (using serial arithmetic).
|
3155 |
|
|
*/
|
3156 |
|
|
if (ADDIP_SERIAL_gte(rcvd_serial, sent_serial + 1) &&
|
3157 |
|
|
!(asoc->addip_last_asconf)) {
|
3158 |
|
|
abort = sctp_make_abort(asoc, asconf_ack,
|
3159 |
|
|
sizeof(sctp_errhdr_t));
|
3160 |
|
|
if (abort) {
|
3161 |
|
|
sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, NULL, 0);
|
3162 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
3163 |
|
|
SCTP_CHUNK(abort));
|
3164 |
|
|
}
|
3165 |
|
|
/* We are going to ABORT, so we might as well stop
|
3166 |
|
|
* processing the rest of the chunks in the packet.
|
3167 |
|
|
*/
|
3168 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3169 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
|
3170 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
|
3171 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
3172 |
|
|
SCTP_U32(SCTP_ERROR_ASCONF_ACK));
|
3173 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
3174 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
3175 |
|
|
return SCTP_DISPOSITION_ABORT;
|
3176 |
|
|
}
|
3177 |
|
|
|
3178 |
|
|
if ((rcvd_serial == sent_serial) && asoc->addip_last_asconf) {
|
3179 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3180 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
|
3181 |
|
|
|
3182 |
|
|
if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
|
3183 |
|
|
asconf_ack))
|
3184 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3185 |
|
|
|
3186 |
|
|
abort = sctp_make_abort(asoc, asconf_ack,
|
3187 |
|
|
sizeof(sctp_errhdr_t));
|
3188 |
|
|
if (abort) {
|
3189 |
|
|
sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, NULL, 0);
|
3190 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
3191 |
|
|
SCTP_CHUNK(abort));
|
3192 |
|
|
}
|
3193 |
|
|
/* We are going to ABORT, so we might as well stop
|
3194 |
|
|
* processing the rest of the chunks in the packet.
|
3195 |
|
|
*/
|
3196 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
|
3197 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
3198 |
|
|
SCTP_U32(SCTP_ERROR_ASCONF_ACK));
|
3199 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
3200 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
3201 |
|
|
return SCTP_DISPOSITION_ABORT;
|
3202 |
|
|
}
|
3203 |
|
|
|
3204 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3205 |
|
|
}
|
3206 |
|
|
|
3207 |
|
|
/*
|
3208 |
|
|
* Process an unknown chunk.
|
3209 |
|
|
*
|
3210 |
|
|
* Section: 3.2. Also, 2.1 in the implementor's guide.
|
3211 |
|
|
*
|
3212 |
|
|
* Chunk Types are encoded such that the highest-order two bits specify
|
3213 |
|
|
* the action that must be taken if the processing endpoint does not
|
3214 |
|
|
* recognize the Chunk Type.
|
3215 |
|
|
*
|
3216 |
|
|
* 00 - Stop processing this SCTP packet and discard it, do not process
|
3217 |
|
|
* any further chunks within it.
|
3218 |
|
|
*
|
3219 |
|
|
* 01 - Stop processing this SCTP packet and discard it, do not process
|
3220 |
|
|
* any further chunks within it, and report the unrecognized
|
3221 |
|
|
* chunk in an 'Unrecognized Chunk Type'.
|
3222 |
|
|
*
|
3223 |
|
|
* 10 - Skip this chunk and continue processing.
|
3224 |
|
|
*
|
3225 |
|
|
* 11 - Skip this chunk and continue processing, but report in an ERROR
|
3226 |
|
|
* Chunk using the 'Unrecognized Chunk Type' cause of error.
|
3227 |
|
|
*
|
3228 |
|
|
* The return value is the disposition of the chunk.
|
3229 |
|
|
*/
|
3230 |
|
|
sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
|
3231 |
|
|
const struct sctp_association *asoc,
|
3232 |
|
|
const sctp_subtype_t type,
|
3233 |
|
|
void *arg,
|
3234 |
|
|
sctp_cmd_seq_t *commands)
|
3235 |
|
|
{
|
3236 |
|
|
struct sctp_chunk *unk_chunk = arg;
|
3237 |
|
|
struct sctp_chunk *err_chunk;
|
3238 |
|
|
sctp_chunkhdr_t *hdr;
|
3239 |
|
|
|
3240 |
|
|
SCTP_DEBUG_PRINTK("Processing the unknown chunk id %d.\n", type.chunk);
|
3241 |
|
|
|
3242 |
|
|
/* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
|
3243 |
|
|
* that the value in the Verification Tag field of the
|
3244 |
|
|
* received SCTP packet matches its own Tag. If the received
|
3245 |
|
|
* Verification Tag value does not match the receiver's own
|
3246 |
|
|
* tag value, the receiver shall silently discard the packet.
|
3247 |
|
|
*/
|
3248 |
|
|
if (ntohl(unk_chunk->sctp_hdr->vtag) != asoc->c.my_vtag)
|
3249 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
3250 |
|
|
|
3251 |
|
|
switch (type.chunk & SCTP_CID_ACTION_MASK) {
|
3252 |
|
|
case SCTP_CID_ACTION_DISCARD:
|
3253 |
|
|
/* Discard the packet. */
|
3254 |
|
|
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
3255 |
|
|
break;
|
3256 |
|
|
case SCTP_CID_ACTION_DISCARD_ERR:
|
3257 |
|
|
/* Discard the packet. */
|
3258 |
|
|
sctp_sf_pdiscard(ep, asoc, type, arg, commands);
|
3259 |
|
|
|
3260 |
|
|
/* Generate an ERROR chunk as response. */
|
3261 |
|
|
hdr = unk_chunk->chunk_hdr;
|
3262 |
|
|
err_chunk = sctp_make_op_error(asoc, unk_chunk,
|
3263 |
|
|
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
|
3264 |
|
|
WORD_ROUND(ntohs(hdr->length)));
|
3265 |
|
|
if (err_chunk) {
|
3266 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
3267 |
|
|
SCTP_CHUNK(err_chunk));
|
3268 |
|
|
}
|
3269 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3270 |
|
|
break;
|
3271 |
|
|
case SCTP_CID_ACTION_SKIP:
|
3272 |
|
|
/* Skip the chunk. */
|
3273 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3274 |
|
|
break;
|
3275 |
|
|
case SCTP_CID_ACTION_SKIP_ERR:
|
3276 |
|
|
/* Generate an ERROR chunk as response. */
|
3277 |
|
|
hdr = unk_chunk->chunk_hdr;
|
3278 |
|
|
err_chunk = sctp_make_op_error(asoc, unk_chunk,
|
3279 |
|
|
SCTP_ERROR_UNKNOWN_CHUNK, hdr,
|
3280 |
|
|
WORD_ROUND(ntohs(hdr->length)));
|
3281 |
|
|
if (err_chunk) {
|
3282 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
3283 |
|
|
SCTP_CHUNK(err_chunk));
|
3284 |
|
|
}
|
3285 |
|
|
/* Skip the chunk. */
|
3286 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3287 |
|
|
break;
|
3288 |
|
|
default:
|
3289 |
|
|
break;
|
3290 |
|
|
}
|
3291 |
|
|
|
3292 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3293 |
|
|
}
|
3294 |
|
|
|
3295 |
|
|
/*
|
3296 |
|
|
* Discard the chunk.
|
3297 |
|
|
*
|
3298 |
|
|
* Section: 0.2, 5.2.3, 5.2.5, 5.2.6, 6.0, 8.4.6, 8.5.1c, 9.2
|
3299 |
|
|
* [Too numerous to mention...]
|
3300 |
|
|
* Verification Tag: No verification needed.
|
3301 |
|
|
* Inputs
|
3302 |
|
|
* (endpoint, asoc, chunk)
|
3303 |
|
|
*
|
3304 |
|
|
* Outputs
|
3305 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
3306 |
|
|
*
|
3307 |
|
|
* The return value is the disposition of the chunk.
|
3308 |
|
|
*/
|
3309 |
|
|
sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
|
3310 |
|
|
const struct sctp_association *asoc,
|
3311 |
|
|
const sctp_subtype_t type,
|
3312 |
|
|
void *arg,
|
3313 |
|
|
sctp_cmd_seq_t *commands)
|
3314 |
|
|
{
|
3315 |
|
|
SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
|
3316 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3317 |
|
|
}
|
3318 |
|
|
|
3319 |
|
|
/*
|
3320 |
|
|
* Discard the whole packet.
|
3321 |
|
|
*
|
3322 |
|
|
* Section: 8.4 2)
|
3323 |
|
|
*
|
3324 |
|
|
* 2) If the OOTB packet contains an ABORT chunk, the receiver MUST
|
3325 |
|
|
* silently discard the OOTB packet and take no further action.
|
3326 |
|
|
* Otherwise,
|
3327 |
|
|
*
|
3328 |
|
|
* Verification Tag: No verification necessary
|
3329 |
|
|
*
|
3330 |
|
|
* Inputs
|
3331 |
|
|
* (endpoint, asoc, chunk)
|
3332 |
|
|
*
|
3333 |
|
|
* Outputs
|
3334 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
3335 |
|
|
*
|
3336 |
|
|
* The return value is the disposition of the chunk.
|
3337 |
|
|
*/
|
3338 |
|
|
sctp_disposition_t sctp_sf_pdiscard(const struct sctp_endpoint *ep,
|
3339 |
|
|
const struct sctp_association *asoc,
|
3340 |
|
|
const sctp_subtype_t type,
|
3341 |
|
|
void *arg,
|
3342 |
|
|
sctp_cmd_seq_t *commands)
|
3343 |
|
|
{
|
3344 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
|
3345 |
|
|
|
3346 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3347 |
|
|
}
|
3348 |
|
|
|
3349 |
|
|
|
3350 |
|
|
/*
|
3351 |
|
|
* The other end is violating protocol.
|
3352 |
|
|
*
|
3353 |
|
|
* Section: Not specified
|
3354 |
|
|
* Verification Tag: Not specified
|
3355 |
|
|
* Inputs
|
3356 |
|
|
* (endpoint, asoc, chunk)
|
3357 |
|
|
*
|
3358 |
|
|
* Outputs
|
3359 |
|
|
* (asoc, reply_msg, msg_up, timers, counters)
|
3360 |
|
|
*
|
3361 |
|
|
* We simply tag the chunk as a violation. The state machine will log
|
3362 |
|
|
* the violation and continue.
|
3363 |
|
|
*/
|
3364 |
|
|
sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
|
3365 |
|
|
const struct sctp_association *asoc,
|
3366 |
|
|
const sctp_subtype_t type,
|
3367 |
|
|
void *arg,
|
3368 |
|
|
sctp_cmd_seq_t *commands)
|
3369 |
|
|
{
|
3370 |
|
|
return SCTP_DISPOSITION_VIOLATION;
|
3371 |
|
|
}
|
3372 |
|
|
|
3373 |
|
|
/***************************************************************************
|
3374 |
|
|
* These are the state functions for handling primitive (Section 10) events.
|
3375 |
|
|
***************************************************************************/
|
3376 |
|
|
/*
|
3377 |
|
|
* sctp_sf_do_prm_asoc
|
3378 |
|
|
*
|
3379 |
|
|
* Section: 10.1 ULP-to-SCTP
|
3380 |
|
|
* B) Associate
|
3381 |
|
|
*
|
3382 |
|
|
* Format: ASSOCIATE(local SCTP instance name, destination transport addr,
|
3383 |
|
|
* outbound stream count)
|
3384 |
|
|
* -> association id [,destination transport addr list] [,outbound stream
|
3385 |
|
|
* count]
|
3386 |
|
|
*
|
3387 |
|
|
* This primitive allows the upper layer to initiate an association to a
|
3388 |
|
|
* specific peer endpoint.
|
3389 |
|
|
*
|
3390 |
|
|
* The peer endpoint shall be specified by one of the transport addresses
|
3391 |
|
|
* which defines the endpoint (see Section 1.4). If the local SCTP
|
3392 |
|
|
* instance has not been initialized, the ASSOCIATE is considered an
|
3393 |
|
|
* error.
|
3394 |
|
|
* [This is not relevant for the kernel implementation since we do all
|
3395 |
|
|
* initialization at boot time. It we hadn't initialized we wouldn't
|
3396 |
|
|
* get anywhere near this code.]
|
3397 |
|
|
*
|
3398 |
|
|
* An association id, which is a local handle to the SCTP association,
|
3399 |
|
|
* will be returned on successful establishment of the association. If
|
3400 |
|
|
* SCTP is not able to open an SCTP association with the peer endpoint,
|
3401 |
|
|
* an error is returned.
|
3402 |
|
|
* [In the kernel implementation, the struct sctp_association needs to
|
3403 |
|
|
* be created BEFORE causing this primitive to run.]
|
3404 |
|
|
*
|
3405 |
|
|
* Other association parameters may be returned, including the
|
3406 |
|
|
* complete destination transport addresses of the peer as well as the
|
3407 |
|
|
* outbound stream count of the local endpoint. One of the transport
|
3408 |
|
|
* address from the returned destination addresses will be selected by
|
3409 |
|
|
* the local endpoint as default primary path for sending SCTP packets
|
3410 |
|
|
* to this peer. The returned "destination transport addr list" can
|
3411 |
|
|
* be used by the ULP to change the default primary path or to force
|
3412 |
|
|
* sending a packet to a specific transport address. [All of this
|
3413 |
|
|
* stuff happens when the INIT ACK arrives. This is a NON-BLOCKING
|
3414 |
|
|
* function.]
|
3415 |
|
|
*
|
3416 |
|
|
* Mandatory attributes:
|
3417 |
|
|
*
|
3418 |
|
|
* o local SCTP instance name - obtained from the INITIALIZE operation.
|
3419 |
|
|
* [This is the argument asoc.]
|
3420 |
|
|
* o destination transport addr - specified as one of the transport
|
3421 |
|
|
* addresses of the peer endpoint with which the association is to be
|
3422 |
|
|
* established.
|
3423 |
|
|
* [This is asoc->peer.active_path.]
|
3424 |
|
|
* o outbound stream count - the number of outbound streams the ULP
|
3425 |
|
|
* would like to open towards this peer endpoint.
|
3426 |
|
|
* [BUG: This is not currently implemented.]
|
3427 |
|
|
* Optional attributes:
|
3428 |
|
|
*
|
3429 |
|
|
* None.
|
3430 |
|
|
*
|
3431 |
|
|
* The return value is a disposition.
|
3432 |
|
|
*/
|
3433 |
|
|
sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
|
3434 |
|
|
const struct sctp_association *asoc,
|
3435 |
|
|
const sctp_subtype_t type,
|
3436 |
|
|
void *arg,
|
3437 |
|
|
sctp_cmd_seq_t *commands)
|
3438 |
|
|
{
|
3439 |
|
|
struct sctp_chunk *repl;
|
3440 |
|
|
|
3441 |
|
|
/* The comment below says that we enter COOKIE-WAIT AFTER
|
3442 |
|
|
* sending the INIT, but that doesn't actually work in our
|
3443 |
|
|
* implementation...
|
3444 |
|
|
*/
|
3445 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
3446 |
|
|
SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
|
3447 |
|
|
|
3448 |
|
|
/* RFC 2960 5.1 Normal Establishment of an Association
|
3449 |
|
|
*
|
3450 |
|
|
* A) "A" first sends an INIT chunk to "Z". In the INIT, "A"
|
3451 |
|
|
* must provide its Verification Tag (Tag_A) in the Initiate
|
3452 |
|
|
* Tag field. Tag_A SHOULD be a random number in the range of
|
3453 |
|
|
* 1 to 4294967295 (see 5.3.1 for Tag value selection). ...
|
3454 |
|
|
*/
|
3455 |
|
|
|
3456 |
|
|
repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
|
3457 |
|
|
if (!repl)
|
3458 |
|
|
goto nomem;
|
3459 |
|
|
|
3460 |
|
|
/* Cast away the const modifier, as we want to just
|
3461 |
|
|
* rerun it through as a sideffect.
|
3462 |
|
|
*/
|
3463 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC,
|
3464 |
|
|
SCTP_ASOC((struct sctp_association *) asoc));
|
3465 |
|
|
|
3466 |
|
|
/* After sending the INIT, "A" starts the T1-init timer and
|
3467 |
|
|
* enters the COOKIE-WAIT state.
|
3468 |
|
|
*/
|
3469 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
3470 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
3471 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
3472 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3473 |
|
|
|
3474 |
|
|
nomem:
|
3475 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
3476 |
|
|
}
|
3477 |
|
|
|
3478 |
|
|
/*
|
3479 |
|
|
* Process the SEND primitive.
|
3480 |
|
|
*
|
3481 |
|
|
* Section: 10.1 ULP-to-SCTP
|
3482 |
|
|
* E) Send
|
3483 |
|
|
*
|
3484 |
|
|
* Format: SEND(association id, buffer address, byte count [,context]
|
3485 |
|
|
* [,stream id] [,life time] [,destination transport address]
|
3486 |
|
|
* [,unorder flag] [,no-bundle flag] [,payload protocol-id] )
|
3487 |
|
|
* -> result
|
3488 |
|
|
*
|
3489 |
|
|
* This is the main method to send user data via SCTP.
|
3490 |
|
|
*
|
3491 |
|
|
* Mandatory attributes:
|
3492 |
|
|
*
|
3493 |
|
|
* o association id - local handle to the SCTP association
|
3494 |
|
|
*
|
3495 |
|
|
* o buffer address - the location where the user message to be
|
3496 |
|
|
* transmitted is stored;
|
3497 |
|
|
*
|
3498 |
|
|
* o byte count - The size of the user data in number of bytes;
|
3499 |
|
|
*
|
3500 |
|
|
* Optional attributes:
|
3501 |
|
|
*
|
3502 |
|
|
* o context - an optional 32 bit integer that will be carried in the
|
3503 |
|
|
* sending failure notification to the ULP if the transportation of
|
3504 |
|
|
* this User Message fails.
|
3505 |
|
|
*
|
3506 |
|
|
* o stream id - to indicate which stream to send the data on. If not
|
3507 |
|
|
* specified, stream 0 will be used.
|
3508 |
|
|
*
|
3509 |
|
|
* o life time - specifies the life time of the user data. The user data
|
3510 |
|
|
* will not be sent by SCTP after the life time expires. This
|
3511 |
|
|
* parameter can be used to avoid efforts to transmit stale
|
3512 |
|
|
* user messages. SCTP notifies the ULP if the data cannot be
|
3513 |
|
|
* initiated to transport (i.e. sent to the destination via SCTP's
|
3514 |
|
|
* send primitive) within the life time variable. However, the
|
3515 |
|
|
* user data will be transmitted if SCTP has attempted to transmit a
|
3516 |
|
|
* chunk before the life time expired.
|
3517 |
|
|
*
|
3518 |
|
|
* o destination transport address - specified as one of the destination
|
3519 |
|
|
* transport addresses of the peer endpoint to which this packet
|
3520 |
|
|
* should be sent. Whenever possible, SCTP should use this destination
|
3521 |
|
|
* transport address for sending the packets, instead of the current
|
3522 |
|
|
* primary path.
|
3523 |
|
|
*
|
3524 |
|
|
* o unorder flag - this flag, if present, indicates that the user
|
3525 |
|
|
* would like the data delivered in an unordered fashion to the peer
|
3526 |
|
|
* (i.e., the U flag is set to 1 on all DATA chunks carrying this
|
3527 |
|
|
* message).
|
3528 |
|
|
*
|
3529 |
|
|
* o no-bundle flag - instructs SCTP not to bundle this user data with
|
3530 |
|
|
* other outbound DATA chunks. SCTP MAY still bundle even when
|
3531 |
|
|
* this flag is present, when faced with network congestion.
|
3532 |
|
|
*
|
3533 |
|
|
* o payload protocol-id - A 32 bit unsigned integer that is to be
|
3534 |
|
|
* passed to the peer indicating the type of payload protocol data
|
3535 |
|
|
* being transmitted. This value is passed as opaque data by SCTP.
|
3536 |
|
|
*
|
3537 |
|
|
* The return value is the disposition.
|
3538 |
|
|
*/
|
3539 |
|
|
sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
|
3540 |
|
|
const struct sctp_association *asoc,
|
3541 |
|
|
const sctp_subtype_t type,
|
3542 |
|
|
void *arg,
|
3543 |
|
|
sctp_cmd_seq_t *commands)
|
3544 |
|
|
{
|
3545 |
|
|
struct sctp_chunk *chunk = arg;
|
3546 |
|
|
|
3547 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
|
3548 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3549 |
|
|
}
|
3550 |
|
|
|
3551 |
|
|
/*
|
3552 |
|
|
* Process the SHUTDOWN primitive.
|
3553 |
|
|
*
|
3554 |
|
|
* Section: 10.1:
|
3555 |
|
|
* C) Shutdown
|
3556 |
|
|
*
|
3557 |
|
|
* Format: SHUTDOWN(association id)
|
3558 |
|
|
* -> result
|
3559 |
|
|
*
|
3560 |
|
|
* Gracefully closes an association. Any locally queued user data
|
3561 |
|
|
* will be delivered to the peer. The association will be terminated only
|
3562 |
|
|
* after the peer acknowledges all the SCTP packets sent. A success code
|
3563 |
|
|
* will be returned on successful termination of the association. If
|
3564 |
|
|
* attempting to terminate the association results in a failure, an error
|
3565 |
|
|
* code shall be returned.
|
3566 |
|
|
*
|
3567 |
|
|
* Mandatory attributes:
|
3568 |
|
|
*
|
3569 |
|
|
* o association id - local handle to the SCTP association
|
3570 |
|
|
*
|
3571 |
|
|
* Optional attributes:
|
3572 |
|
|
*
|
3573 |
|
|
* None.
|
3574 |
|
|
*
|
3575 |
|
|
* The return value is the disposition.
|
3576 |
|
|
*/
|
3577 |
|
|
sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
|
3578 |
|
|
const struct sctp_endpoint *ep,
|
3579 |
|
|
const struct sctp_association *asoc,
|
3580 |
|
|
const sctp_subtype_t type,
|
3581 |
|
|
void *arg,
|
3582 |
|
|
sctp_cmd_seq_t *commands)
|
3583 |
|
|
{
|
3584 |
|
|
int disposition;
|
3585 |
|
|
|
3586 |
|
|
/* From 9.2 Shutdown of an Association
|
3587 |
|
|
* Upon receipt of the SHUTDOWN primitive from its upper
|
3588 |
|
|
* layer, the endpoint enters SHUTDOWN-PENDING state and
|
3589 |
|
|
* remains there until all outstanding data has been
|
3590 |
|
|
* acknowledged by its peer. The endpoint accepts no new data
|
3591 |
|
|
* from its upper layer, but retransmits data to the far end
|
3592 |
|
|
* if necessary to fill gaps.
|
3593 |
|
|
*/
|
3594 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
3595 |
|
|
SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
|
3596 |
|
|
|
3597 |
|
|
/* sctpimpguide-05 Section 2.12.2
|
3598 |
|
|
* The sender of the SHUTDOWN MAY also start an overall guard timer
|
3599 |
|
|
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
|
3600 |
|
|
*/
|
3601 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
3602 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
3603 |
|
|
|
3604 |
|
|
disposition = SCTP_DISPOSITION_CONSUME;
|
3605 |
|
|
if (sctp_outq_is_empty(&asoc->outqueue)) {
|
3606 |
|
|
disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
|
3607 |
|
|
arg, commands);
|
3608 |
|
|
}
|
3609 |
|
|
return disposition;
|
3610 |
|
|
}
|
3611 |
|
|
|
3612 |
|
|
/*
|
3613 |
|
|
* Process the ABORT primitive.
|
3614 |
|
|
*
|
3615 |
|
|
* Section: 10.1:
|
3616 |
|
|
* C) Abort
|
3617 |
|
|
*
|
3618 |
|
|
* Format: Abort(association id [, cause code])
|
3619 |
|
|
* -> result
|
3620 |
|
|
*
|
3621 |
|
|
* Ungracefully closes an association. Any locally queued user data
|
3622 |
|
|
* will be discarded and an ABORT chunk is sent to the peer. A success code
|
3623 |
|
|
* will be returned on successful abortion of the association. If
|
3624 |
|
|
* attempting to abort the association results in a failure, an error
|
3625 |
|
|
* code shall be returned.
|
3626 |
|
|
*
|
3627 |
|
|
* Mandatory attributes:
|
3628 |
|
|
*
|
3629 |
|
|
* o association id - local handle to the SCTP association
|
3630 |
|
|
*
|
3631 |
|
|
* Optional attributes:
|
3632 |
|
|
*
|
3633 |
|
|
* o cause code - reason of the abort to be passed to the peer
|
3634 |
|
|
*
|
3635 |
|
|
* None.
|
3636 |
|
|
*
|
3637 |
|
|
* The return value is the disposition.
|
3638 |
|
|
*/
|
3639 |
|
|
sctp_disposition_t sctp_sf_do_9_1_prm_abort(
|
3640 |
|
|
const struct sctp_endpoint *ep,
|
3641 |
|
|
const struct sctp_association *asoc,
|
3642 |
|
|
const sctp_subtype_t type,
|
3643 |
|
|
void *arg,
|
3644 |
|
|
sctp_cmd_seq_t *commands)
|
3645 |
|
|
{
|
3646 |
|
|
/* From 9.1 Abort of an Association
|
3647 |
|
|
* Upon receipt of the ABORT primitive from its upper
|
3648 |
|
|
* layer, the endpoint enters CLOSED state and
|
3649 |
|
|
* discard all outstanding data has been
|
3650 |
|
|
* acknowledged by its peer. The endpoint accepts no new data
|
3651 |
|
|
* from its upper layer, but retransmits data to the far end
|
3652 |
|
|
* if necessary to fill gaps.
|
3653 |
|
|
*/
|
3654 |
|
|
struct msghdr *msg = arg;
|
3655 |
|
|
struct sctp_chunk *abort;
|
3656 |
|
|
sctp_disposition_t retval;
|
3657 |
|
|
|
3658 |
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
3659 |
|
|
|
3660 |
|
|
/* Generate ABORT chunk to send the peer. */
|
3661 |
|
|
abort = sctp_make_abort_user(asoc, NULL, msg);
|
3662 |
|
|
if (!abort)
|
3663 |
|
|
retval = SCTP_DISPOSITION_NOMEM;
|
3664 |
|
|
else
|
3665 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
3666 |
|
|
|
3667 |
|
|
/* Even if we can't send the ABORT due to low memory delete the
|
3668 |
|
|
* TCB. This is a departure from our typical NOMEM handling.
|
3669 |
|
|
*/
|
3670 |
|
|
|
3671 |
|
|
/* Delete the established association. */
|
3672 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
3673 |
|
|
SCTP_U32(SCTP_ERROR_USER_ABORT));
|
3674 |
|
|
|
3675 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
3676 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
3677 |
|
|
|
3678 |
|
|
return retval;
|
3679 |
|
|
}
|
3680 |
|
|
|
3681 |
|
|
/* We tried an illegal operation on an association which is closed. */
|
3682 |
|
|
sctp_disposition_t sctp_sf_error_closed(const struct sctp_endpoint *ep,
|
3683 |
|
|
const struct sctp_association *asoc,
|
3684 |
|
|
const sctp_subtype_t type,
|
3685 |
|
|
void *arg,
|
3686 |
|
|
sctp_cmd_seq_t *commands)
|
3687 |
|
|
{
|
3688 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR, SCTP_ERROR(-EINVAL));
|
3689 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3690 |
|
|
}
|
3691 |
|
|
|
3692 |
|
|
/* We tried an illegal operation on an association which is shutting
|
3693 |
|
|
* down.
|
3694 |
|
|
*/
|
3695 |
|
|
sctp_disposition_t sctp_sf_error_shutdown(const struct sctp_endpoint *ep,
|
3696 |
|
|
const struct sctp_association *asoc,
|
3697 |
|
|
const sctp_subtype_t type,
|
3698 |
|
|
void *arg,
|
3699 |
|
|
sctp_cmd_seq_t *commands)
|
3700 |
|
|
{
|
3701 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_ERROR,
|
3702 |
|
|
SCTP_ERROR(-ESHUTDOWN));
|
3703 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3704 |
|
|
}
|
3705 |
|
|
|
3706 |
|
|
/*
|
3707 |
|
|
* sctp_cookie_wait_prm_shutdown
|
3708 |
|
|
*
|
3709 |
|
|
* Section: 4 Note: 2
|
3710 |
|
|
* Verification Tag:
|
3711 |
|
|
* Inputs
|
3712 |
|
|
* (endpoint, asoc)
|
3713 |
|
|
*
|
3714 |
|
|
* The RFC does not explicitly address this issue, but is the route through the
|
3715 |
|
|
* state table when someone issues a shutdown while in COOKIE_WAIT state.
|
3716 |
|
|
*
|
3717 |
|
|
* Outputs
|
3718 |
|
|
* (timers)
|
3719 |
|
|
*/
|
3720 |
|
|
sctp_disposition_t sctp_sf_cookie_wait_prm_shutdown(
|
3721 |
|
|
const struct sctp_endpoint *ep,
|
3722 |
|
|
const struct sctp_association *asoc,
|
3723 |
|
|
const sctp_subtype_t type,
|
3724 |
|
|
void *arg,
|
3725 |
|
|
sctp_cmd_seq_t *commands)
|
3726 |
|
|
{
|
3727 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3728 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
3729 |
|
|
|
3730 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
3731 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
3732 |
|
|
|
3733 |
|
|
SCTP_INC_STATS(SctpShutdowns);
|
3734 |
|
|
|
3735 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
|
3736 |
|
|
|
3737 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
3738 |
|
|
}
|
3739 |
|
|
|
3740 |
|
|
/*
|
3741 |
|
|
* sctp_cookie_echoed_prm_shutdown
|
3742 |
|
|
*
|
3743 |
|
|
* Section: 4 Note: 2
|
3744 |
|
|
* Verification Tag:
|
3745 |
|
|
* Inputs
|
3746 |
|
|
* (endpoint, asoc)
|
3747 |
|
|
*
|
3748 |
|
|
* The RFC does not explcitly address this issue, but is the route through the
|
3749 |
|
|
* state table when someone issues a shutdown while in COOKIE_ECHOED state.
|
3750 |
|
|
*
|
3751 |
|
|
* Outputs
|
3752 |
|
|
* (timers)
|
3753 |
|
|
*/
|
3754 |
|
|
sctp_disposition_t sctp_sf_cookie_echoed_prm_shutdown(
|
3755 |
|
|
const struct sctp_endpoint *ep,
|
3756 |
|
|
const struct sctp_association *asoc,
|
3757 |
|
|
const sctp_subtype_t type,
|
3758 |
|
|
void *arg, sctp_cmd_seq_t *commands)
|
3759 |
|
|
{
|
3760 |
|
|
/* There is a single T1 timer, so we should be able to use
|
3761 |
|
|
* common function with the COOKIE-WAIT state.
|
3762 |
|
|
*/
|
3763 |
|
|
return sctp_sf_cookie_wait_prm_shutdown(ep, asoc, type, arg, commands);
|
3764 |
|
|
}
|
3765 |
|
|
|
3766 |
|
|
/*
|
3767 |
|
|
* sctp_sf_cookie_wait_prm_abort
|
3768 |
|
|
*
|
3769 |
|
|
* Section: 4 Note: 2
|
3770 |
|
|
* Verification Tag:
|
3771 |
|
|
* Inputs
|
3772 |
|
|
* (endpoint, asoc)
|
3773 |
|
|
*
|
3774 |
|
|
* The RFC does not explicitly address this issue, but is the route through the
|
3775 |
|
|
* state table when someone issues an abort while in COOKIE_WAIT state.
|
3776 |
|
|
*
|
3777 |
|
|
* Outputs
|
3778 |
|
|
* (timers)
|
3779 |
|
|
*/
|
3780 |
|
|
sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
|
3781 |
|
|
const struct sctp_endpoint *ep,
|
3782 |
|
|
const struct sctp_association *asoc,
|
3783 |
|
|
const sctp_subtype_t type,
|
3784 |
|
|
void *arg,
|
3785 |
|
|
sctp_cmd_seq_t *commands)
|
3786 |
|
|
{
|
3787 |
|
|
struct msghdr *msg = arg;
|
3788 |
|
|
struct sctp_chunk *abort;
|
3789 |
|
|
sctp_disposition_t retval;
|
3790 |
|
|
|
3791 |
|
|
/* Stop T1-init timer */
|
3792 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3793 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
|
3794 |
|
|
retval = SCTP_DISPOSITION_CONSUME;
|
3795 |
|
|
|
3796 |
|
|
/* Generate ABORT chunk to send the peer */
|
3797 |
|
|
abort = sctp_make_abort_user(asoc, NULL, msg);
|
3798 |
|
|
if (!abort)
|
3799 |
|
|
retval = SCTP_DISPOSITION_NOMEM;
|
3800 |
|
|
else
|
3801 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
|
3802 |
|
|
|
3803 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
3804 |
|
|
SCTP_STATE(SCTP_STATE_CLOSED));
|
3805 |
|
|
|
3806 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
3807 |
|
|
|
3808 |
|
|
/* Even if we can't send the ABORT due to low memory delete the
|
3809 |
|
|
* TCB. This is a departure from our typical NOMEM handling.
|
3810 |
|
|
*/
|
3811 |
|
|
|
3812 |
|
|
/* Delete the established association. */
|
3813 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
|
3814 |
|
|
SCTP_U32(SCTP_ERROR_USER_ABORT));
|
3815 |
|
|
|
3816 |
|
|
return retval;
|
3817 |
|
|
}
|
3818 |
|
|
|
3819 |
|
|
/*
|
3820 |
|
|
* sctp_sf_cookie_echoed_prm_abort
|
3821 |
|
|
*
|
3822 |
|
|
* Section: 4 Note: 3
|
3823 |
|
|
* Verification Tag:
|
3824 |
|
|
* Inputs
|
3825 |
|
|
* (endpoint, asoc)
|
3826 |
|
|
*
|
3827 |
|
|
* The RFC does not explcitly address this issue, but is the route through the
|
3828 |
|
|
* state table when someone issues an abort while in COOKIE_ECHOED state.
|
3829 |
|
|
*
|
3830 |
|
|
* Outputs
|
3831 |
|
|
* (timers)
|
3832 |
|
|
*/
|
3833 |
|
|
sctp_disposition_t sctp_sf_cookie_echoed_prm_abort(
|
3834 |
|
|
const struct sctp_endpoint *ep,
|
3835 |
|
|
const struct sctp_association *asoc,
|
3836 |
|
|
const sctp_subtype_t type,
|
3837 |
|
|
void *arg,
|
3838 |
|
|
sctp_cmd_seq_t *commands)
|
3839 |
|
|
{
|
3840 |
|
|
/* There is a single T1 timer, so we should be able to use
|
3841 |
|
|
* common function with the COOKIE-WAIT state.
|
3842 |
|
|
*/
|
3843 |
|
|
return sctp_sf_cookie_wait_prm_abort(ep, asoc, type, arg, commands);
|
3844 |
|
|
}
|
3845 |
|
|
|
3846 |
|
|
/*
|
3847 |
|
|
* sctp_sf_shutdown_pending_prm_abort
|
3848 |
|
|
*
|
3849 |
|
|
* Inputs
|
3850 |
|
|
* (endpoint, asoc)
|
3851 |
|
|
*
|
3852 |
|
|
* The RFC does not explicitly address this issue, but is the route through the
|
3853 |
|
|
* state table when someone issues an abort while in SHUTDOWN-PENDING state.
|
3854 |
|
|
*
|
3855 |
|
|
* Outputs
|
3856 |
|
|
* (timers)
|
3857 |
|
|
*/
|
3858 |
|
|
sctp_disposition_t sctp_sf_shutdown_pending_prm_abort(
|
3859 |
|
|
const struct sctp_endpoint *ep,
|
3860 |
|
|
const struct sctp_association *asoc,
|
3861 |
|
|
const sctp_subtype_t type,
|
3862 |
|
|
void *arg,
|
3863 |
|
|
sctp_cmd_seq_t *commands)
|
3864 |
|
|
{
|
3865 |
|
|
/* Stop the T5-shutdown guard timer. */
|
3866 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3867 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
3868 |
|
|
|
3869 |
|
|
return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
|
3870 |
|
|
}
|
3871 |
|
|
|
3872 |
|
|
/*
|
3873 |
|
|
* sctp_sf_shutdown_sent_prm_abort
|
3874 |
|
|
*
|
3875 |
|
|
* Inputs
|
3876 |
|
|
* (endpoint, asoc)
|
3877 |
|
|
*
|
3878 |
|
|
* The RFC does not explicitly address this issue, but is the route through the
|
3879 |
|
|
* state table when someone issues an abort while in SHUTDOWN-SENT state.
|
3880 |
|
|
*
|
3881 |
|
|
* Outputs
|
3882 |
|
|
* (timers)
|
3883 |
|
|
*/
|
3884 |
|
|
sctp_disposition_t sctp_sf_shutdown_sent_prm_abort(
|
3885 |
|
|
const struct sctp_endpoint *ep,
|
3886 |
|
|
const struct sctp_association *asoc,
|
3887 |
|
|
const sctp_subtype_t type,
|
3888 |
|
|
void *arg,
|
3889 |
|
|
sctp_cmd_seq_t *commands)
|
3890 |
|
|
{
|
3891 |
|
|
/* Stop the T2-shutdown timer. */
|
3892 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3893 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
3894 |
|
|
|
3895 |
|
|
/* Stop the T5-shutdown guard timer. */
|
3896 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
3897 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
3898 |
|
|
|
3899 |
|
|
return sctp_sf_do_9_1_prm_abort(ep, asoc, type, arg, commands);
|
3900 |
|
|
}
|
3901 |
|
|
|
3902 |
|
|
/*
|
3903 |
|
|
* sctp_sf_cookie_echoed_prm_abort
|
3904 |
|
|
*
|
3905 |
|
|
* Inputs
|
3906 |
|
|
* (endpoint, asoc)
|
3907 |
|
|
*
|
3908 |
|
|
* The RFC does not explcitly address this issue, but is the route through the
|
3909 |
|
|
* state table when someone issues an abort while in COOKIE_ECHOED state.
|
3910 |
|
|
*
|
3911 |
|
|
* Outputs
|
3912 |
|
|
* (timers)
|
3913 |
|
|
*/
|
3914 |
|
|
sctp_disposition_t sctp_sf_shutdown_ack_sent_prm_abort(
|
3915 |
|
|
const struct sctp_endpoint *ep,
|
3916 |
|
|
const struct sctp_association *asoc,
|
3917 |
|
|
const sctp_subtype_t type,
|
3918 |
|
|
void *arg,
|
3919 |
|
|
sctp_cmd_seq_t *commands)
|
3920 |
|
|
{
|
3921 |
|
|
/* The same T2 timer, so we should be able to use
|
3922 |
|
|
* common function with the SHUTDOWN-SENT state.
|
3923 |
|
|
*/
|
3924 |
|
|
return sctp_sf_shutdown_sent_prm_abort(ep, asoc, type, arg, commands);
|
3925 |
|
|
}
|
3926 |
|
|
|
3927 |
|
|
/*
|
3928 |
|
|
* Process the REQUESTHEARTBEAT primitive
|
3929 |
|
|
*
|
3930 |
|
|
* 10.1 ULP-to-SCTP
|
3931 |
|
|
* J) Request Heartbeat
|
3932 |
|
|
*
|
3933 |
|
|
* Format: REQUESTHEARTBEAT(association id, destination transport address)
|
3934 |
|
|
*
|
3935 |
|
|
* -> result
|
3936 |
|
|
*
|
3937 |
|
|
* Instructs the local endpoint to perform a HeartBeat on the specified
|
3938 |
|
|
* destination transport address of the given association. The returned
|
3939 |
|
|
* result should indicate whether the transmission of the HEARTBEAT
|
3940 |
|
|
* chunk to the destination address is successful.
|
3941 |
|
|
*
|
3942 |
|
|
* Mandatory attributes:
|
3943 |
|
|
*
|
3944 |
|
|
* o association id - local handle to the SCTP association
|
3945 |
|
|
*
|
3946 |
|
|
* o destination transport address - the transport address of the
|
3947 |
|
|
* association on which a heartbeat should be issued.
|
3948 |
|
|
*/
|
3949 |
|
|
sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
|
3950 |
|
|
const struct sctp_endpoint *ep,
|
3951 |
|
|
const struct sctp_association *asoc,
|
3952 |
|
|
const sctp_subtype_t type,
|
3953 |
|
|
void *arg,
|
3954 |
|
|
sctp_cmd_seq_t *commands)
|
3955 |
|
|
{
|
3956 |
|
|
return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg,
|
3957 |
|
|
commands);
|
3958 |
|
|
}
|
3959 |
|
|
|
3960 |
|
|
/*
|
3961 |
|
|
* ADDIP Section 4.1 ASCONF Chunk Procedures
|
3962 |
|
|
* When an endpoint has an ASCONF signaled change to be sent to the
|
3963 |
|
|
* remote endpoint it should do A1 to A9
|
3964 |
|
|
*/
|
3965 |
|
|
sctp_disposition_t sctp_sf_do_prm_asconf(const struct sctp_endpoint *ep,
|
3966 |
|
|
const struct sctp_association *asoc,
|
3967 |
|
|
const sctp_subtype_t type,
|
3968 |
|
|
void *arg,
|
3969 |
|
|
sctp_cmd_seq_t *commands)
|
3970 |
|
|
{
|
3971 |
|
|
struct sctp_chunk *chunk = arg;
|
3972 |
|
|
|
3973 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
|
3974 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
3975 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
|
3976 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
|
3977 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
3978 |
|
|
}
|
3979 |
|
|
|
3980 |
|
|
/*
|
3981 |
|
|
* Ignore the primitive event
|
3982 |
|
|
*
|
3983 |
|
|
* The return value is the disposition of the primitive.
|
3984 |
|
|
*/
|
3985 |
|
|
sctp_disposition_t sctp_sf_ignore_primitive(
|
3986 |
|
|
const struct sctp_endpoint *ep,
|
3987 |
|
|
const struct sctp_association *asoc,
|
3988 |
|
|
const sctp_subtype_t type,
|
3989 |
|
|
void *arg,
|
3990 |
|
|
sctp_cmd_seq_t *commands)
|
3991 |
|
|
{
|
3992 |
|
|
SCTP_DEBUG_PRINTK("Primitive type %d is ignored.\n", type.primitive);
|
3993 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
3994 |
|
|
}
|
3995 |
|
|
|
3996 |
|
|
/***************************************************************************
|
3997 |
|
|
* These are the state functions for the OTHER events.
|
3998 |
|
|
***************************************************************************/
|
3999 |
|
|
|
4000 |
|
|
/*
|
4001 |
|
|
* Start the shutdown negotiation.
|
4002 |
|
|
*
|
4003 |
|
|
* From Section 9.2:
|
4004 |
|
|
* Once all its outstanding data has been acknowledged, the endpoint
|
4005 |
|
|
* shall send a SHUTDOWN chunk to its peer including in the Cumulative
|
4006 |
|
|
* TSN Ack field the last sequential TSN it has received from the peer.
|
4007 |
|
|
* It shall then start the T2-shutdown timer and enter the SHUTDOWN-SENT
|
4008 |
|
|
* state. If the timer expires, the endpoint must re-send the SHUTDOWN
|
4009 |
|
|
* with the updated last sequential TSN received from its peer.
|
4010 |
|
|
*
|
4011 |
|
|
* The return value is the disposition.
|
4012 |
|
|
*/
|
4013 |
|
|
sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
|
4014 |
|
|
const struct sctp_endpoint *ep,
|
4015 |
|
|
const struct sctp_association *asoc,
|
4016 |
|
|
const sctp_subtype_t type,
|
4017 |
|
|
void *arg,
|
4018 |
|
|
sctp_cmd_seq_t *commands)
|
4019 |
|
|
{
|
4020 |
|
|
struct sctp_chunk *reply;
|
4021 |
|
|
|
4022 |
|
|
/* Once all its outstanding data has been acknowledged, the
|
4023 |
|
|
* endpoint shall send a SHUTDOWN chunk to its peer including
|
4024 |
|
|
* in the Cumulative TSN Ack field the last sequential TSN it
|
4025 |
|
|
* has received from the peer.
|
4026 |
|
|
*/
|
4027 |
|
|
reply = sctp_make_shutdown(asoc, NULL);
|
4028 |
|
|
if (!reply)
|
4029 |
|
|
goto nomem;
|
4030 |
|
|
|
4031 |
|
|
/* Set the transport for the SHUTDOWN chunk and the timeout for the
|
4032 |
|
|
* T2-shutdown timer.
|
4033 |
|
|
*/
|
4034 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
|
4035 |
|
|
|
4036 |
|
|
/* It shall then start the T2-shutdown timer */
|
4037 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
4038 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
4039 |
|
|
|
4040 |
|
|
if (asoc->autoclose)
|
4041 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
4042 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
|
4043 |
|
|
|
4044 |
|
|
/* and enter the SHUTDOWN-SENT state. */
|
4045 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
4046 |
|
|
SCTP_STATE(SCTP_STATE_SHUTDOWN_SENT));
|
4047 |
|
|
|
4048 |
|
|
/* sctp-implguide 2.10 Issues with Heartbeating and failover
|
4049 |
|
|
*
|
4050 |
|
|
* HEARTBEAT ... is discontinued after sending either SHUTDOWN
|
4051 |
|
|
* or SHUTDOWN-ACK.
|
4052 |
|
|
*/
|
4053 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
|
4054 |
|
|
|
4055 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
4056 |
|
|
|
4057 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4058 |
|
|
|
4059 |
|
|
nomem:
|
4060 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
4061 |
|
|
}
|
4062 |
|
|
|
4063 |
|
|
/*
|
4064 |
|
|
* Generate a SHUTDOWN ACK now that everything is SACK'd.
|
4065 |
|
|
*
|
4066 |
|
|
* From Section 9.2:
|
4067 |
|
|
*
|
4068 |
|
|
* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
|
4069 |
|
|
* shall send a SHUTDOWN ACK and start a T2-shutdown timer of its own,
|
4070 |
|
|
* entering the SHUTDOWN-ACK-SENT state. If the timer expires, the
|
4071 |
|
|
* endpoint must re-send the SHUTDOWN ACK.
|
4072 |
|
|
*
|
4073 |
|
|
* The return value is the disposition.
|
4074 |
|
|
*/
|
4075 |
|
|
sctp_disposition_t sctp_sf_do_9_2_shutdown_ack(
|
4076 |
|
|
const struct sctp_endpoint *ep,
|
4077 |
|
|
const struct sctp_association *asoc,
|
4078 |
|
|
const sctp_subtype_t type,
|
4079 |
|
|
void *arg,
|
4080 |
|
|
sctp_cmd_seq_t *commands)
|
4081 |
|
|
{
|
4082 |
|
|
struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
|
4083 |
|
|
struct sctp_chunk *reply;
|
4084 |
|
|
|
4085 |
|
|
/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
|
4086 |
|
|
* shall send a SHUTDOWN ACK ...
|
4087 |
|
|
*/
|
4088 |
|
|
reply = sctp_make_shutdown_ack(asoc, chunk);
|
4089 |
|
|
if (!reply)
|
4090 |
|
|
goto nomem;
|
4091 |
|
|
|
4092 |
|
|
/* Set the transport for the SHUTDOWN ACK chunk and the timeout for
|
4093 |
|
|
* the T2-shutdown timer.
|
4094 |
|
|
*/
|
4095 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
|
4096 |
|
|
|
4097 |
|
|
/* and start/restart a T2-shutdown timer of its own, */
|
4098 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
4099 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
4100 |
|
|
|
4101 |
|
|
if (asoc->autoclose)
|
4102 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
4103 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
|
4104 |
|
|
|
4105 |
|
|
/* Enter the SHUTDOWN-ACK-SENT state. */
|
4106 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
4107 |
|
|
SCTP_STATE(SCTP_STATE_SHUTDOWN_ACK_SENT));
|
4108 |
|
|
|
4109 |
|
|
/* sctp-implguide 2.10 Issues with Heartbeating and failover
|
4110 |
|
|
*
|
4111 |
|
|
* HEARTBEAT ... is discontinued after sending either SHUTDOWN
|
4112 |
|
|
* or SHUTDOWN-ACK.
|
4113 |
|
|
*/
|
4114 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
|
4115 |
|
|
|
4116 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
4117 |
|
|
|
4118 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4119 |
|
|
|
4120 |
|
|
nomem:
|
4121 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
4122 |
|
|
}
|
4123 |
|
|
|
4124 |
|
|
/*
|
4125 |
|
|
* Ignore the event defined as other
|
4126 |
|
|
*
|
4127 |
|
|
* The return value is the disposition of the event.
|
4128 |
|
|
*/
|
4129 |
|
|
sctp_disposition_t sctp_sf_ignore_other(const struct sctp_endpoint *ep,
|
4130 |
|
|
const struct sctp_association *asoc,
|
4131 |
|
|
const sctp_subtype_t type,
|
4132 |
|
|
void *arg,
|
4133 |
|
|
sctp_cmd_seq_t *commands)
|
4134 |
|
|
{
|
4135 |
|
|
SCTP_DEBUG_PRINTK("The event other type %d is ignored\n", type.other);
|
4136 |
|
|
return SCTP_DISPOSITION_DISCARD;
|
4137 |
|
|
}
|
4138 |
|
|
|
4139 |
|
|
/************************************************************
|
4140 |
|
|
* These are the state functions for handling timeout events.
|
4141 |
|
|
************************************************************/
|
4142 |
|
|
|
4143 |
|
|
/*
|
4144 |
|
|
* RTX Timeout
|
4145 |
|
|
*
|
4146 |
|
|
* Section: 6.3.3 Handle T3-rtx Expiration
|
4147 |
|
|
*
|
4148 |
|
|
* Whenever the retransmission timer T3-rtx expires for a destination
|
4149 |
|
|
* address, do the following:
|
4150 |
|
|
* [See below]
|
4151 |
|
|
*
|
4152 |
|
|
* The return value is the disposition of the chunk.
|
4153 |
|
|
*/
|
4154 |
|
|
sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
|
4155 |
|
|
const struct sctp_association *asoc,
|
4156 |
|
|
const sctp_subtype_t type,
|
4157 |
|
|
void *arg,
|
4158 |
|
|
sctp_cmd_seq_t *commands)
|
4159 |
|
|
{
|
4160 |
|
|
struct sctp_transport *transport = arg;
|
4161 |
|
|
|
4162 |
|
|
if (asoc->overall_error_count >= asoc->max_retrans) {
|
4163 |
|
|
/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
|
4164 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
4165 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
4166 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
4167 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
4168 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
4169 |
|
|
}
|
4170 |
|
|
|
4171 |
|
|
/* E1) For the destination address for which the timer
|
4172 |
|
|
* expires, adjust its ssthresh with rules defined in Section
|
4173 |
|
|
* 7.2.3 and set the cwnd <- MTU.
|
4174 |
|
|
*/
|
4175 |
|
|
|
4176 |
|
|
/* E2) For the destination address for which the timer
|
4177 |
|
|
* expires, set RTO <- RTO * 2 ("back off the timer"). The
|
4178 |
|
|
* maximum value discussed in rule C7 above (RTO.max) may be
|
4179 |
|
|
* used to provide an upper bound to this doubling operation.
|
4180 |
|
|
*/
|
4181 |
|
|
|
4182 |
|
|
/* E3) Determine how many of the earliest (i.e., lowest TSN)
|
4183 |
|
|
* outstanding DATA chunks for the address for which the
|
4184 |
|
|
* T3-rtx has expired will fit into a single packet, subject
|
4185 |
|
|
* to the MTU constraint for the path corresponding to the
|
4186 |
|
|
* destination transport address to which the retransmission
|
4187 |
|
|
* is being sent (this may be different from the address for
|
4188 |
|
|
* which the timer expires [see Section 6.4]). Call this
|
4189 |
|
|
* value K. Bundle and retransmit those K DATA chunks in a
|
4190 |
|
|
* single packet to the destination endpoint.
|
4191 |
|
|
*
|
4192 |
|
|
* Note: Any DATA chunks that were sent to the address for
|
4193 |
|
|
* which the T3-rtx timer expired but did not fit in one MTU
|
4194 |
|
|
* (rule E3 above), should be marked for retransmission and
|
4195 |
|
|
* sent as soon as cwnd allows (normally when a SACK arrives).
|
4196 |
|
|
*/
|
4197 |
|
|
|
4198 |
|
|
/* NB: Rules E4 and F1 are implicit in R1. */
|
4199 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(transport));
|
4200 |
|
|
|
4201 |
|
|
/* Do some failure management (Section 8.2). */
|
4202 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
|
4203 |
|
|
|
4204 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4205 |
|
|
}
|
4206 |
|
|
|
4207 |
|
|
/*
|
4208 |
|
|
* Generate delayed SACK on timeout
|
4209 |
|
|
*
|
4210 |
|
|
* Section: 6.2 Acknowledgement on Reception of DATA Chunks
|
4211 |
|
|
*
|
4212 |
|
|
* The guidelines on delayed acknowledgement algorithm specified in
|
4213 |
|
|
* Section 4.2 of [RFC2581] SHOULD be followed. Specifically, an
|
4214 |
|
|
* acknowledgement SHOULD be generated for at least every second packet
|
4215 |
|
|
* (not every second DATA chunk) received, and SHOULD be generated
|
4216 |
|
|
* within 200 ms of the arrival of any unacknowledged DATA chunk. In
|
4217 |
|
|
* some situations it may be beneficial for an SCTP transmitter to be
|
4218 |
|
|
* more conservative than the algorithms detailed in this document
|
4219 |
|
|
* allow. However, an SCTP transmitter MUST NOT be more aggressive than
|
4220 |
|
|
* the following algorithms allow.
|
4221 |
|
|
*/
|
4222 |
|
|
sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
|
4223 |
|
|
const struct sctp_association *asoc,
|
4224 |
|
|
const sctp_subtype_t type,
|
4225 |
|
|
void *arg,
|
4226 |
|
|
sctp_cmd_seq_t *commands)
|
4227 |
|
|
{
|
4228 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_FORCE());
|
4229 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4230 |
|
|
}
|
4231 |
|
|
|
4232 |
|
|
/*
|
4233 |
|
|
* sctp_sf_t1_timer_expire
|
4234 |
|
|
*
|
4235 |
|
|
* Section: 4 Note: 2
|
4236 |
|
|
* Verification Tag:
|
4237 |
|
|
* Inputs
|
4238 |
|
|
* (endpoint, asoc)
|
4239 |
|
|
*
|
4240 |
|
|
* RFC 2960 Section 4 Notes
|
4241 |
|
|
* 2) If the T1-init timer expires, the endpoint MUST retransmit INIT
|
4242 |
|
|
* and re-start the T1-init timer without changing state. This MUST
|
4243 |
|
|
* be repeated up to 'Max.Init.Retransmits' times. After that, the
|
4244 |
|
|
* endpoint MUST abort the initialization process and report the
|
4245 |
|
|
* error to SCTP user.
|
4246 |
|
|
*
|
4247 |
|
|
* 3) If the T1-cookie timer expires, the endpoint MUST retransmit
|
4248 |
|
|
* COOKIE ECHO and re-start the T1-cookie timer without changing
|
4249 |
|
|
* state. This MUST be repeated up to 'Max.Init.Retransmits' times.
|
4250 |
|
|
* After that, the endpoint MUST abort the initialization process and
|
4251 |
|
|
* report the error to SCTP user.
|
4252 |
|
|
*
|
4253 |
|
|
* Outputs
|
4254 |
|
|
* (timers, events)
|
4255 |
|
|
*
|
4256 |
|
|
*/
|
4257 |
|
|
sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
|
4258 |
|
|
const struct sctp_association *asoc,
|
4259 |
|
|
const sctp_subtype_t type,
|
4260 |
|
|
void *arg,
|
4261 |
|
|
sctp_cmd_seq_t *commands)
|
4262 |
|
|
{
|
4263 |
|
|
struct sctp_chunk *repl;
|
4264 |
|
|
struct sctp_bind_addr *bp;
|
4265 |
|
|
sctp_event_timeout_t timer = (sctp_event_timeout_t) arg;
|
4266 |
|
|
int timeout;
|
4267 |
|
|
int attempts;
|
4268 |
|
|
|
4269 |
|
|
timeout = asoc->timeouts[timer];
|
4270 |
|
|
attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
|
4271 |
|
|
repl = NULL;
|
4272 |
|
|
|
4273 |
|
|
SCTP_DEBUG_PRINTK("Timer T1 expired.\n");
|
4274 |
|
|
|
4275 |
|
|
if (attempts < asoc->max_init_attempts) {
|
4276 |
|
|
switch (timer) {
|
4277 |
|
|
case SCTP_EVENT_TIMEOUT_T1_INIT:
|
4278 |
|
|
bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
|
4279 |
|
|
repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
|
4280 |
|
|
break;
|
4281 |
|
|
|
4282 |
|
|
case SCTP_EVENT_TIMEOUT_T1_COOKIE:
|
4283 |
|
|
repl = sctp_make_cookie_echo(asoc, NULL);
|
4284 |
|
|
break;
|
4285 |
|
|
|
4286 |
|
|
default:
|
4287 |
|
|
BUG();
|
4288 |
|
|
break;
|
4289 |
|
|
};
|
4290 |
|
|
|
4291 |
|
|
if (!repl)
|
4292 |
|
|
goto nomem;
|
4293 |
|
|
|
4294 |
|
|
/* Issue a sideeffect to do the needed accounting. */
|
4295 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
|
4296 |
|
|
SCTP_TO(timer));
|
4297 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
|
4298 |
|
|
} else {
|
4299 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
|
4300 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
4301 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
4302 |
|
|
}
|
4303 |
|
|
|
4304 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4305 |
|
|
|
4306 |
|
|
nomem:
|
4307 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
4308 |
|
|
}
|
4309 |
|
|
|
4310 |
|
|
/* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
|
4311 |
|
|
* with the updated last sequential TSN received from its peer.
|
4312 |
|
|
*
|
4313 |
|
|
* An endpoint should limit the number of retransmissions of the
|
4314 |
|
|
* SHUTDOWN chunk to the protocol parameter 'Association.Max.Retrans'.
|
4315 |
|
|
* If this threshold is exceeded the endpoint should destroy the TCB and
|
4316 |
|
|
* MUST report the peer endpoint unreachable to the upper layer (and
|
4317 |
|
|
* thus the association enters the CLOSED state). The reception of any
|
4318 |
|
|
* packet from its peer (i.e. as the peer sends all of its queued DATA
|
4319 |
|
|
* chunks) should clear the endpoint's retransmission count and restart
|
4320 |
|
|
* the T2-Shutdown timer, giving its peer ample opportunity to transmit
|
4321 |
|
|
* all of its queued DATA chunks that have not yet been sent.
|
4322 |
|
|
*/
|
4323 |
|
|
sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
|
4324 |
|
|
const struct sctp_association *asoc,
|
4325 |
|
|
const sctp_subtype_t type,
|
4326 |
|
|
void *arg,
|
4327 |
|
|
sctp_cmd_seq_t *commands)
|
4328 |
|
|
{
|
4329 |
|
|
struct sctp_chunk *reply = NULL;
|
4330 |
|
|
|
4331 |
|
|
SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
|
4332 |
|
|
if (asoc->overall_error_count >= asoc->max_retrans) {
|
4333 |
|
|
/* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
|
4334 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
4335 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
4336 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
4337 |
|
|
SCTP_DEC_STATS(SctpCurrEstab);
|
4338 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
4339 |
|
|
}
|
4340 |
|
|
|
4341 |
|
|
switch (asoc->state) {
|
4342 |
|
|
case SCTP_STATE_SHUTDOWN_SENT:
|
4343 |
|
|
reply = sctp_make_shutdown(asoc, NULL);
|
4344 |
|
|
break;
|
4345 |
|
|
|
4346 |
|
|
case SCTP_STATE_SHUTDOWN_ACK_SENT:
|
4347 |
|
|
reply = sctp_make_shutdown_ack(asoc, NULL);
|
4348 |
|
|
break;
|
4349 |
|
|
|
4350 |
|
|
default:
|
4351 |
|
|
BUG();
|
4352 |
|
|
break;
|
4353 |
|
|
};
|
4354 |
|
|
|
4355 |
|
|
if (!reply)
|
4356 |
|
|
goto nomem;
|
4357 |
|
|
|
4358 |
|
|
/* Do some failure management (Section 8.2). */
|
4359 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
|
4360 |
|
|
SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
|
4361 |
|
|
|
4362 |
|
|
/* Set the transport for the SHUTDOWN/ACK chunk and the timeout for
|
4363 |
|
|
* the T2-shutdown timer.
|
4364 |
|
|
*/
|
4365 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T2, SCTP_CHUNK(reply));
|
4366 |
|
|
|
4367 |
|
|
/* Restart the T2-shutdown timer. */
|
4368 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
4369 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
|
4370 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
4371 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4372 |
|
|
|
4373 |
|
|
nomem:
|
4374 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
4375 |
|
|
}
|
4376 |
|
|
|
4377 |
|
|
/*
|
4378 |
|
|
* ADDIP Section 4.1 ASCONF CHunk Procedures
|
4379 |
|
|
* If the T4 RTO timer expires the endpoint should do B1 to B5
|
4380 |
|
|
*/
|
4381 |
|
|
sctp_disposition_t sctp_sf_t4_timer_expire(
|
4382 |
|
|
const struct sctp_endpoint *ep,
|
4383 |
|
|
const struct sctp_association *asoc,
|
4384 |
|
|
const sctp_subtype_t type,
|
4385 |
|
|
void *arg,
|
4386 |
|
|
sctp_cmd_seq_t *commands)
|
4387 |
|
|
{
|
4388 |
|
|
struct sctp_chunk *chunk = asoc->addip_last_asconf;
|
4389 |
|
|
struct sctp_transport *transport = chunk->transport;
|
4390 |
|
|
|
4391 |
|
|
/* ADDIP 4.1 B1) Increment the error counters and perform path failure
|
4392 |
|
|
* detection on the appropriate destination address as defined in
|
4393 |
|
|
* RFC2960 [5] section 8.1 and 8.2.
|
4394 |
|
|
*/
|
4395 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
|
4396 |
|
|
|
4397 |
|
|
/* Reconfig T4 timer and transport. */
|
4398 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
|
4399 |
|
|
|
4400 |
|
|
/* ADDIP 4.1 B2) Increment the association error counters and perform
|
4401 |
|
|
* endpoint failure detection on the association as defined in
|
4402 |
|
|
* RFC2960 [5] section 8.1 and 8.2.
|
4403 |
|
|
* association error counter is incremented in SCTP_CMD_STRIKE.
|
4404 |
|
|
*/
|
4405 |
|
|
if (asoc->overall_error_count >= asoc->max_retrans) {
|
4406 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
|
4407 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
|
4408 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
4409 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
4410 |
|
|
SCTP_INC_STATS(SctpAborteds);
|
4411 |
|
|
SCTP_INC_STATS(SctpCurrEstab);
|
4412 |
|
|
return SCTP_DISPOSITION_ABORT;
|
4413 |
|
|
}
|
4414 |
|
|
|
4415 |
|
|
/* ADDIP 4.1 B3) Back-off the destination address RTO value to which
|
4416 |
|
|
* the ASCONF chunk was sent by doubling the RTO timer value.
|
4417 |
|
|
* This is done in SCTP_CMD_STRIKE.
|
4418 |
|
|
*/
|
4419 |
|
|
|
4420 |
|
|
/* ADDIP 4.1 B4) Re-transmit the ASCONF Chunk last sent and if possible
|
4421 |
|
|
* choose an alternate destination address (please refer to RFC2960
|
4422 |
|
|
* [5] section 6.4.1). An endpoint MUST NOT add new parameters to this
|
4423 |
|
|
* chunk, it MUST be the same (including its serial number) as the last
|
4424 |
|
|
* ASCONF sent.
|
4425 |
|
|
*/
|
4426 |
|
|
sctp_chunk_hold(asoc->addip_last_asconf);
|
4427 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
|
4428 |
|
|
SCTP_CHUNK(asoc->addip_last_asconf));
|
4429 |
|
|
|
4430 |
|
|
/* ADDIP 4.1 B5) Restart the T-4 RTO timer. Note that if a different
|
4431 |
|
|
* destination is selected, then the RTO used will be that of the new
|
4432 |
|
|
* destination address.
|
4433 |
|
|
*/
|
4434 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
|
4435 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
|
4436 |
|
|
|
4437 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4438 |
|
|
}
|
4439 |
|
|
|
4440 |
|
|
/* sctpimpguide-05 Section 2.12.2
|
4441 |
|
|
* The sender of the SHUTDOWN MAY also start an overall guard timer
|
4442 |
|
|
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
|
4443 |
|
|
* At the expiration of this timer the sender SHOULD abort the association
|
4444 |
|
|
* by sending an ABORT chunk.
|
4445 |
|
|
*/
|
4446 |
|
|
sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
|
4447 |
|
|
const struct sctp_association *asoc,
|
4448 |
|
|
const sctp_subtype_t type,
|
4449 |
|
|
void *arg,
|
4450 |
|
|
sctp_cmd_seq_t *commands)
|
4451 |
|
|
{
|
4452 |
|
|
struct sctp_chunk *reply = NULL;
|
4453 |
|
|
|
4454 |
|
|
SCTP_DEBUG_PRINTK("Timer T5 expired.\n");
|
4455 |
|
|
|
4456 |
|
|
reply = sctp_make_abort(asoc, NULL, 0);
|
4457 |
|
|
if (!reply)
|
4458 |
|
|
goto nomem;
|
4459 |
|
|
|
4460 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
|
4461 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
|
4462 |
|
|
SCTP_U32(SCTP_ERROR_NO_ERROR));
|
4463 |
|
|
|
4464 |
|
|
return SCTP_DISPOSITION_DELETE_TCB;
|
4465 |
|
|
nomem:
|
4466 |
|
|
return SCTP_DISPOSITION_NOMEM;
|
4467 |
|
|
}
|
4468 |
|
|
|
4469 |
|
|
/* Handle expiration of AUTOCLOSE timer. When the autoclose timer expires,
|
4470 |
|
|
* the association is automatically closed by starting the shutdown process.
|
4471 |
|
|
* The work that needs to be done is same as when SHUTDOWN is initiated by
|
4472 |
|
|
* the user. So this routine looks same as sctp_sf_do_9_2_prm_shutdown().
|
4473 |
|
|
*/
|
4474 |
|
|
sctp_disposition_t sctp_sf_autoclose_timer_expire(
|
4475 |
|
|
const struct sctp_endpoint *ep,
|
4476 |
|
|
const struct sctp_association *asoc,
|
4477 |
|
|
const sctp_subtype_t type,
|
4478 |
|
|
void *arg,
|
4479 |
|
|
sctp_cmd_seq_t *commands)
|
4480 |
|
|
{
|
4481 |
|
|
int disposition;
|
4482 |
|
|
|
4483 |
|
|
/* From 9.2 Shutdown of an Association
|
4484 |
|
|
* Upon receipt of the SHUTDOWN primitive from its upper
|
4485 |
|
|
* layer, the endpoint enters SHUTDOWN-PENDING state and
|
4486 |
|
|
* remains there until all outstanding data has been
|
4487 |
|
|
* acknowledged by its peer. The endpoint accepts no new data
|
4488 |
|
|
* from its upper layer, but retransmits data to the far end
|
4489 |
|
|
* if necessary to fill gaps.
|
4490 |
|
|
*/
|
4491 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
|
4492 |
|
|
SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
|
4493 |
|
|
|
4494 |
|
|
/* sctpimpguide-05 Section 2.12.2
|
4495 |
|
|
* The sender of the SHUTDOWN MAY also start an overall guard timer
|
4496 |
|
|
* 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
|
4497 |
|
|
*/
|
4498 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
|
4499 |
|
|
SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
|
4500 |
|
|
disposition = SCTP_DISPOSITION_CONSUME;
|
4501 |
|
|
if (sctp_outq_is_empty(&asoc->outqueue)) {
|
4502 |
|
|
disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
|
4503 |
|
|
arg, commands);
|
4504 |
|
|
}
|
4505 |
|
|
return disposition;
|
4506 |
|
|
}
|
4507 |
|
|
|
4508 |
|
|
/*****************************************************************************
|
4509 |
|
|
* These are sa state functions which could apply to all types of events.
|
4510 |
|
|
****************************************************************************/
|
4511 |
|
|
|
4512 |
|
|
/*
|
4513 |
|
|
* This table entry is not implemented.
|
4514 |
|
|
*
|
4515 |
|
|
* Inputs
|
4516 |
|
|
* (endpoint, asoc, chunk)
|
4517 |
|
|
*
|
4518 |
|
|
* The return value is the disposition of the chunk.
|
4519 |
|
|
*/
|
4520 |
|
|
sctp_disposition_t sctp_sf_not_impl(const struct sctp_endpoint *ep,
|
4521 |
|
|
const struct sctp_association *asoc,
|
4522 |
|
|
const sctp_subtype_t type,
|
4523 |
|
|
void *arg,
|
4524 |
|
|
sctp_cmd_seq_t *commands)
|
4525 |
|
|
{
|
4526 |
|
|
return SCTP_DISPOSITION_NOT_IMPL;
|
4527 |
|
|
}
|
4528 |
|
|
|
4529 |
|
|
/*
|
4530 |
|
|
* This table entry represents a bug.
|
4531 |
|
|
*
|
4532 |
|
|
* Inputs
|
4533 |
|
|
* (endpoint, asoc, chunk)
|
4534 |
|
|
*
|
4535 |
|
|
* The return value is the disposition of the chunk.
|
4536 |
|
|
*/
|
4537 |
|
|
sctp_disposition_t sctp_sf_bug(const struct sctp_endpoint *ep,
|
4538 |
|
|
const struct sctp_association *asoc,
|
4539 |
|
|
const sctp_subtype_t type,
|
4540 |
|
|
void *arg,
|
4541 |
|
|
sctp_cmd_seq_t *commands)
|
4542 |
|
|
{
|
4543 |
|
|
return SCTP_DISPOSITION_BUG;
|
4544 |
|
|
}
|
4545 |
|
|
|
4546 |
|
|
/*
|
4547 |
|
|
* This table entry represents the firing of a timer in the wrong state.
|
4548 |
|
|
* Since timer deletion cannot be guaranteed a timer 'may' end up firing
|
4549 |
|
|
* when the association is in the wrong state. This event should
|
4550 |
|
|
* be ignored, so as to prevent any rearming of the timer.
|
4551 |
|
|
*
|
4552 |
|
|
* Inputs
|
4553 |
|
|
* (endpoint, asoc, chunk)
|
4554 |
|
|
*
|
4555 |
|
|
* The return value is the disposition of the chunk.
|
4556 |
|
|
*/
|
4557 |
|
|
sctp_disposition_t sctp_sf_timer_ignore(const struct sctp_endpoint *ep,
|
4558 |
|
|
const struct sctp_association *asoc,
|
4559 |
|
|
const sctp_subtype_t type,
|
4560 |
|
|
void *arg,
|
4561 |
|
|
sctp_cmd_seq_t *commands)
|
4562 |
|
|
{
|
4563 |
|
|
SCTP_DEBUG_PRINTK("Timer %d ignored.\n", type.chunk);
|
4564 |
|
|
return SCTP_DISPOSITION_CONSUME;
|
4565 |
|
|
}
|
4566 |
|
|
|
4567 |
|
|
/********************************************************************
|
4568 |
|
|
* 2nd Level Abstractions
|
4569 |
|
|
********************************************************************/
|
4570 |
|
|
|
4571 |
|
|
/* Pull the SACK chunk based on the SACK header. */
|
4572 |
|
|
struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
|
4573 |
|
|
{
|
4574 |
|
|
struct sctp_sackhdr *sack;
|
4575 |
|
|
unsigned int len;
|
4576 |
|
|
__u16 num_blocks;
|
4577 |
|
|
__u16 num_dup_tsns;
|
4578 |
|
|
|
4579 |
|
|
/* Protect ourselves from reading too far into
|
4580 |
|
|
* the skb from a bogus sender.
|
4581 |
|
|
*/
|
4582 |
|
|
sack = (struct sctp_sackhdr *) chunk->skb->data;
|
4583 |
|
|
|
4584 |
|
|
num_blocks = ntohs(sack->num_gap_ack_blocks);
|
4585 |
|
|
num_dup_tsns = ntohs(sack->num_dup_tsns);
|
4586 |
|
|
len = sizeof(struct sctp_sackhdr);
|
4587 |
|
|
len = (num_blocks + num_dup_tsns) * sizeof(__u32);
|
4588 |
|
|
if (len > chunk->skb->len)
|
4589 |
|
|
return NULL;
|
4590 |
|
|
|
4591 |
|
|
skb_pull(chunk->skb, len);
|
4592 |
|
|
|
4593 |
|
|
return sack;
|
4594 |
|
|
}
|
4595 |
|
|
|
4596 |
|
|
/* Create an ABORT packet to be sent as a response, with the specified
|
4597 |
|
|
* error causes.
|
4598 |
|
|
*/
|
4599 |
|
|
struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
|
4600 |
|
|
const struct sctp_association *asoc,
|
4601 |
|
|
struct sctp_chunk *chunk,
|
4602 |
|
|
const void *payload,
|
4603 |
|
|
size_t paylen)
|
4604 |
|
|
{
|
4605 |
|
|
struct sctp_packet *packet;
|
4606 |
|
|
struct sctp_chunk *abort;
|
4607 |
|
|
|
4608 |
|
|
packet = sctp_ootb_pkt_new(asoc, chunk);
|
4609 |
|
|
|
4610 |
|
|
if (packet) {
|
4611 |
|
|
/* Make an ABORT.
|
4612 |
|
|
* The T bit will be set if the asoc is NULL.
|
4613 |
|
|
*/
|
4614 |
|
|
abort = sctp_make_abort(asoc, chunk, paylen);
|
4615 |
|
|
if (!abort) {
|
4616 |
|
|
sctp_ootb_pkt_free(packet);
|
4617 |
|
|
return NULL;
|
4618 |
|
|
}
|
4619 |
|
|
/* Add specified error causes, i.e., payload, to the
|
4620 |
|
|
* end of the chunk.
|
4621 |
|
|
*/
|
4622 |
|
|
sctp_addto_chunk(abort, paylen, payload);
|
4623 |
|
|
|
4624 |
|
|
/* Set the skb to the belonging sock for accounting. */
|
4625 |
|
|
abort->skb->sk = ep->base.sk;
|
4626 |
|
|
|
4627 |
|
|
sctp_packet_append_chunk(packet, abort);
|
4628 |
|
|
|
4629 |
|
|
}
|
4630 |
|
|
|
4631 |
|
|
return packet;
|
4632 |
|
|
}
|
4633 |
|
|
|
4634 |
|
|
/* Allocate a packet for responding in the OOTB conditions. */
|
4635 |
|
|
struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
|
4636 |
|
|
const struct sctp_chunk *chunk)
|
4637 |
|
|
{
|
4638 |
|
|
struct sctp_packet *packet;
|
4639 |
|
|
struct sctp_transport *transport;
|
4640 |
|
|
__u16 sport;
|
4641 |
|
|
__u16 dport;
|
4642 |
|
|
__u32 vtag;
|
4643 |
|
|
|
4644 |
|
|
/* Get the source and destination port from the inbound packet. */
|
4645 |
|
|
sport = ntohs(chunk->sctp_hdr->dest);
|
4646 |
|
|
dport = ntohs(chunk->sctp_hdr->source);
|
4647 |
|
|
|
4648 |
|
|
/* The V-tag is going to be the same as the inbound packet if no
|
4649 |
|
|
* association exists, otherwise, use the peer's vtag.
|
4650 |
|
|
*/
|
4651 |
|
|
if (asoc) {
|
4652 |
|
|
vtag = asoc->peer.i.init_tag;
|
4653 |
|
|
} else {
|
4654 |
|
|
/* Special case the INIT and stale COOKIE_ECHO as there is no
|
4655 |
|
|
* vtag yet.
|
4656 |
|
|
*/
|
4657 |
|
|
switch(chunk->chunk_hdr->type) {
|
4658 |
|
|
case SCTP_CID_INIT:
|
4659 |
|
|
{
|
4660 |
|
|
sctp_init_chunk_t *init;
|
4661 |
|
|
|
4662 |
|
|
init = (sctp_init_chunk_t *)chunk->chunk_hdr;
|
4663 |
|
|
vtag = ntohl(init->init_hdr.init_tag);
|
4664 |
|
|
break;
|
4665 |
|
|
}
|
4666 |
|
|
default:
|
4667 |
|
|
vtag = ntohl(chunk->sctp_hdr->vtag);
|
4668 |
|
|
break;
|
4669 |
|
|
}
|
4670 |
|
|
}
|
4671 |
|
|
|
4672 |
|
|
/* Make a transport for the bucket, Eliza... */
|
4673 |
|
|
transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
|
4674 |
|
|
|
4675 |
|
|
if (!transport)
|
4676 |
|
|
goto nomem;
|
4677 |
|
|
|
4678 |
|
|
/* Allocate a new packet for sending the response. */
|
4679 |
|
|
packet = t_new(struct sctp_packet, GFP_ATOMIC);
|
4680 |
|
|
if (!packet)
|
4681 |
|
|
goto nomem_packet;
|
4682 |
|
|
|
4683 |
|
|
/* Cache a route for the transport with the chunk's destination as
|
4684 |
|
|
* the source address.
|
4685 |
|
|
*/
|
4686 |
|
|
sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
|
4687 |
|
|
sctp_sk(sctp_get_ctl_sock()));
|
4688 |
|
|
|
4689 |
|
|
packet = sctp_packet_init(packet, transport, sport, dport);
|
4690 |
|
|
packet = sctp_packet_config(packet, vtag, 0, NULL);
|
4691 |
|
|
|
4692 |
|
|
return packet;
|
4693 |
|
|
|
4694 |
|
|
nomem_packet:
|
4695 |
|
|
sctp_transport_free(transport);
|
4696 |
|
|
nomem:
|
4697 |
|
|
return NULL;
|
4698 |
|
|
}
|
4699 |
|
|
|
4700 |
|
|
/* Free the packet allocated earlier for responding in the OOTB condition. */
|
4701 |
|
|
void sctp_ootb_pkt_free(struct sctp_packet *packet)
|
4702 |
|
|
{
|
4703 |
|
|
sctp_transport_free(packet->transport);
|
4704 |
|
|
sctp_packet_free(packet);
|
4705 |
|
|
}
|
4706 |
|
|
|
4707 |
|
|
/* Send a stale cookie error when a invalid COOKIE ECHO chunk is found */
|
4708 |
|
|
void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
|
4709 |
|
|
const struct sctp_association *asoc,
|
4710 |
|
|
const struct sctp_chunk *chunk,
|
4711 |
|
|
sctp_cmd_seq_t *commands,
|
4712 |
|
|
struct sctp_chunk *err_chunk)
|
4713 |
|
|
{
|
4714 |
|
|
struct sctp_packet *packet;
|
4715 |
|
|
|
4716 |
|
|
if (err_chunk) {
|
4717 |
|
|
packet = sctp_ootb_pkt_new(asoc, chunk);
|
4718 |
|
|
if (packet) {
|
4719 |
|
|
struct sctp_signed_cookie *cookie;
|
4720 |
|
|
|
4721 |
|
|
/* Override the OOTB vtag from the cookie. */
|
4722 |
|
|
cookie = chunk->subh.cookie_hdr;
|
4723 |
|
|
packet->vtag = cookie->c.peer_vtag;
|
4724 |
|
|
|
4725 |
|
|
/* Set the skb to the belonging sock for accounting. */
|
4726 |
|
|
err_chunk->skb->sk = ep->base.sk;
|
4727 |
|
|
sctp_packet_append_chunk(packet, err_chunk);
|
4728 |
|
|
sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
|
4729 |
|
|
SCTP_PACKET(packet));
|
4730 |
|
|
SCTP_INC_STATS(SctpOutCtrlChunks);
|
4731 |
|
|
} else
|
4732 |
|
|
sctp_chunk_free (err_chunk);
|
4733 |
|
|
}
|
4734 |
|
|
}
|