1
/* SCTP kernel reference Implementation
2
* (C) Copyright IBM Corp. 2001, 2003
3
* Copyright (C) 1999 Cisco and Motorola
4
* Copyright (c) Nokia, 2002
6
* This file is part of the SCTP kernel reference Implementation
8
* This is Functional Test 4 for the SCTP kernel reference
9
* implementation state machine.
11
* Case Study 2: Initialization Collision
12
* Scenario 2. a variation form Scenario 1. Due to network reordering event
13
* the INIT that endpoint Z sends crosses ahead of its previously sent
16
* Set up a link, send message from sk1 to sk2 first. But INIT_ACK is delayed.
17
* Then send message from sk2 to sk1. This will cause overlapping INIT chunk.
18
* See the association is up and messages appear. Send the messages once more.
21
* The SCTP reference implementation is free software;
22
* you can redistribute it and/or modify it under the terms of
23
* the GNU General Public License as published by
24
* the Free Software Foundation; either version 2, or (at your option)
27
* The SCTP reference implementation is distributed in the hope that it
28
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
29
* ************************
30
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
* See the GNU General Public License for more details.
33
* You should have received a copy of the GNU General Public License
34
* along with GNU CC; see the file COPYING. If not, write to
35
* the Free Software Foundation, 59 Temple Place - Suite 330,
36
* Boston, MA 02111-1307, USA.
38
* Please send any bug reports or fixes you make to the
40
* lksctp developers <lksctp-developers@lists.sourceforge.net>
42
* Or submit a bug report through the following website:
43
* http://www.sf.net/projects/lksctp
45
* Written or modified by:
46
* La Monte H.P. Yarroll <piggy@acm.org>
47
* Narasimha Budihal <narsi@refcode.org>
48
* Karl Knutson <karl@athena.chicago.il.us>
49
* Jon "Taz" Mischo <taz@refcode.org>
50
* Sridhar Samudrala <samudrala@us.ibm.com>
51
* Dajiang Zhang <dajiang.zhang@nokia.com>
53
* Any bugs reported given to us we will try to fix... any fixes shared will
54
* be incorporated into the next SCTP release.
57
#include <linux/types.h>
58
#include <linux/list.h> /* For struct list_head */
59
#include <linux/socket.h>
61
#include <linux/time.h> /* For struct timeval */
63
#include <linux/wait.h> /* For wait_queue_head_t */
64
#include <linux/skbuff.h>
65
#include <linux/errno.h>
66
#include <net/sctp/sctp.h>
69
#include <test_kernel.h>
74
main(int argc, char *argv[])
76
struct sock *sk[NSOCK];
77
struct sctp_endpoint *ep[NSOCK];
78
struct sctp_association *asoc[NSOCK];
79
union sctp_addr loop[6];
81
char addr_buf[sizeof(struct sockaddr_in6)*8];
82
int pf_class, bufsize, flags;
83
struct sk_buff *pkt1, *pkt2, *pkt3;
86
/* Do all that random stuff needed to make a sensible universe. */
90
/* Initialize the server addresses. */
93
loop[0].v6.sin6_family = AF_INET6;
94
loop[0].v6.sin6_addr = (struct in6_addr) SCTP_ADDR6_SITELOCAL_ETH0;
95
loop[0].v6.sin6_scope_id = 0;
96
loop[0].v6.sin6_port = htons(SCTP_TESTPORT_1);
97
netw[0] = TEST_NETWORK_ETH0;
99
loop[1].v6.sin6_family = AF_INET6;
100
loop[1].v6.sin6_addr = (struct in6_addr) SCTP_B_ADDR6_SITELOCAL_ETH0;
101
loop[1].v6.sin6_scope_id = 0;
102
loop[1].v6.sin6_port = htons(SCTP_TESTPORT_1);
103
netw[1] = TEST_NETWORK_ETH0;
105
loop[2].v6.sin6_family = AF_INET6;
106
loop[2].v6.sin6_addr = (struct in6_addr) SCTP_ADDR6_SITELOCAL_ETH1;
107
loop[2].v6.sin6_scope_id = 0;
108
loop[2].v6.sin6_port = htons(SCTP_TESTPORT_1);
109
netw[2] = TEST_NETWORK_ETH1;
111
loop[3].v6.sin6_family = AF_INET6;
112
loop[3].v6.sin6_addr = (struct in6_addr) SCTP_C_ADDR6_SITELOCAL_ETH0;
113
loop[3].v6.sin6_scope_id = 0;
114
loop[3].v6.sin6_port = htons(SCTP_TESTPORT_1);
115
netw[3] = TEST_NETWORK_ETH0;
117
loop[4].v4.sin_family = AF_INET;
118
loop[4].v4.sin_addr.s_addr = SCTP_ADDR_ETH2;
119
loop[4].v4.sin_port = htons(SCTP_TESTPORT_1);
120
netw[4] = TEST_NETWORK_ETH2;
122
loop[5].v6.sin6_family = AF_INET6;
123
loop[5].v6.sin6_addr = (struct in6_addr) SCTP_D_ADDR6_SITELOCAL_ETH0;
124
loop[5].v6.sin6_scope_id = 0;
125
loop[5].v6.sin6_port = htons(SCTP_TESTPORT_1);
126
netw[5] = TEST_NETWORK_ETH0;
129
loop[0].v4.sin_family = AF_INET;
130
loop[0].v4.sin_addr.s_addr = SCTP_ADDR_ETH0;
131
loop[0].v4.sin_port = htons(SCTP_TESTPORT_1);
132
netw[0] = TEST_NETWORK_ETH0;
134
loop[1].v4.sin_family = AF_INET;
135
loop[1].v4.sin_addr.s_addr = SCTP_B_ETH0;
136
loop[1].v4.sin_port = htons(SCTP_TESTPORT_1);
137
netw[1] = TEST_NETWORK_ETH0;
139
loop[2].v4.sin_family = AF_INET;
140
loop[2].v4.sin_addr.s_addr = SCTP_ADDR_ETH1;
141
loop[2].v4.sin_port = htons(SCTP_TESTPORT_1);
142
netw[2] = TEST_NETWORK_ETH1;
144
loop[3].v4.sin_family = AF_INET;
145
loop[3].v4.sin_addr.s_addr = SCTP_C_ETH0;
146
loop[3].v4.sin_port = htons(SCTP_TESTPORT_1);
147
netw[3] = TEST_NETWORK_ETH0;
149
loop[4].v4.sin_family = AF_INET;
150
loop[4].v4.sin_addr.s_addr = SCTP_ADDR_ETH2;
151
loop[4].v4.sin_port = htons(SCTP_TESTPORT_1);
152
netw[4] = TEST_NETWORK_ETH2;
154
loop[5].v4.sin_family = AF_INET;
155
loop[5].v4.sin_addr.s_addr = SCTP_D_ETH0;
156
loop[5].v4.sin_port = htons(SCTP_TESTPORT_1);
157
netw[5] = TEST_NETWORK_ETH0;
160
/* Create the endpoints which will talk to each other. */
161
for (i = 0; i < NSOCK; i++ )
162
sk[i] = sctp_socket(pf_class, SOCK_SEQPACKET);
164
/* Bind socket 1 to the test ports. */
165
error = test_bind(sk[0], (struct sockaddr *)&loop[0],
167
if (error != 0) { DUMP_CORE; }
169
/* Bind socket 2 to the test ports. */
170
error = test_bind(sk[1], (struct sockaddr *)&loop[1],
172
if (error != 0) { DUMP_CORE; }
174
bufsize = fill_addr_buf(addr_buf, loop, 2, 2);
175
error = test_bindx(sk[1], (struct sockaddr *)addr_buf, bufsize,
176
SCTP_BINDX_ADD_ADDR);
177
if (error != 0) { DUMP_CORE; }
179
/* Bind socket 3 to the test ports. */
180
error = test_bind(sk[2], (struct sockaddr *)&loop[3],
182
if (error != 0) { DUMP_CORE; }
184
bufsize = fill_addr_buf(addr_buf, loop, 4, 4);
185
error = test_bindx(sk[2], (struct sockaddr *)addr_buf, bufsize,
186
SCTP_BINDX_ADD_ADDR);
187
if (error != 0) { DUMP_CORE; }
189
/* Bind socket 4 to the test ports. */
190
error = test_bind(sk[3], (struct sockaddr *)&loop[5],
192
if (error != 0) { DUMP_CORE; }
194
/* Mark sk[1] and sk[2] as being able to accept new associations. */
195
if (0 != sctp_seqpacket_listen(sk[1], 1)) {
198
if (0 != sctp_seqpacket_listen(sk[2], 1)) {
202
printk("----------------------------------------------------\n"
204
"----------------------------------------------------\n");
206
/* Set sk[0] as non-blocking. */
207
flags = sk[0]->sk_socket->file->f_flags;
208
sk[0]->sk_socket->file->f_flags |= O_NONBLOCK;
210
/* Do a non-blocking connect from sk[0] to sk[1]/3 */
211
bufsize = fill_addr_buf(addr_buf, loop, 1, 4);
212
error = test_connectx(sk[0], (struct sockaddr *)addr_buf, bufsize);
214
/* Non-blocking connect should return immediately with EINPROGRESS. */
215
if (error != -EINPROGRESS) { DUMP_CORE; }
217
/* Walk through the startup sequence. */
218
/* We should have an INIT sitting on the Internet. */
219
if (!test_for_chunk(SCTP_CID_INIT, netw[0])) {
222
printk("\n 1->2/3 INIT\n\n");
224
/* Next we expect an INIT ACK, but it will be delayed. */
225
if (test_step(SCTP_CID_INIT_ACK, netw[0]) <=0 ) {
229
printk("\n 2->1 INIT_ACK will be delayed\n\n");
230
pkt1 = test_steal_packet(netw[0]);
231
if (test_for_chunk(SCTP_CID_INIT_ACK, netw[0])) {
235
/* Now, let sk[1] and sk[2] connect to sk[0] to cause INIT collision.
238
/* Mark sk[0] as being able to accept new associations. */
239
if (0 != sctp_seqpacket_listen(sk[0], 1)) {
243
/* Set sk[1] as non-blocking. */
244
flags = sk[1]->sk_socket->file->f_flags;
245
sk[1]->sk_socket->file->f_flags |= O_NONBLOCK;
247
/* Do a non-blocking connect from sk[1] to sk[0] */
248
printk("\n Connect 2->1\n\n");
249
bufsize = fill_addr_buf(addr_buf, loop, 0, 0);
250
error = test_connectx(sk[1], (struct sockaddr *)addr_buf, bufsize);
252
/* Non-blocking connect should return immediately with EINPROGRESS. */
253
if (error != -EINPROGRESS) { DUMP_CORE; }
255
/* 2 sends INIT to 1. */
256
printk("\n 2->1 INIT\n\n");
257
if (!test_for_chunk(SCTP_CID_INIT, netw[0])) {
261
printk("\n 1->2 INIT ACK\n\n");
262
if (test_step(SCTP_CID_INIT_ACK, netw[0])<= 0 ) {
265
printk("\n Hold 1-2> INIT ACK\n\n");
266
pkt2 = test_steal_packet(netw[0]);
268
/* Set sk[2] as non-blocking. */
269
flags = sk[2]->sk_socket->file->f_flags;
270
sk[2]->sk_socket->file->f_flags |= O_NONBLOCK;
272
/* Do a non-blocking connect from sk[2] to sk[0] */
273
printk("\n Connect 3->1\n\n");
274
bufsize = fill_addr_buf(addr_buf, loop, 0, 0);
275
error = test_connectx(sk[2], (struct sockaddr *)addr_buf, bufsize);
277
/* Non-blocking connect should return immediately with EINPROGRESS. */
278
if (error != -EINPROGRESS) { DUMP_CORE; }
280
/* 3 sends INIT to 1. */
281
printk("\n 3->1 INIT\n\n");
282
if (!test_for_chunk(SCTP_CID_INIT, netw[0])) {
286
ep[0] = sctp_sk(sk[0])->ep;
287
asoc[0] = test_ep_first_asoc(ep[0]);
288
ep[1] = sctp_sk(sk[1])->ep;
289
asoc[1] = test_ep_first_asoc(ep[1]);
290
printk("\n Association 0 (%p):\n", asoc[0]);
291
print_assoc_peer_transports(asoc[0]);
292
printk("\n Association 1 (%p):\n", asoc[1]);
293
print_assoc_peer_transports(asoc[1]);
294
test_assoc_peer_transports(asoc[0], &loop[1], 4);
295
test_assoc_peer_transports(asoc[1], &loop[0], 1);
297
printk("\n 1->3 INIT ACK\n\n");
298
if (test_step(SCTP_CID_INIT_ACK, netw[0])<= 0 ) {
302
printk("\n 1->3 INIT_ACK will be delayed\n\n");
303
pkt3 = test_steal_packet(netw[0]);
304
if (test_for_chunk(SCTP_CID_INIT_ACK, netw[0])) {
308
/* Set sk[3] as non-blocking. */
309
flags = sk[3]->sk_socket->file->f_flags;
310
sk[3]->sk_socket->file->f_flags |= O_NONBLOCK;
312
/* Do a non-blocking connect from sk[3] to sk[0] */
313
printk("\n Connect 4->1\n\n");
314
bufsize = fill_addr_buf(addr_buf, loop, 0, 0);
315
error = test_connectx(sk[3], (struct sockaddr *)addr_buf, bufsize);
317
/* Non-blocking connect should return immediately with EINPROGRESS. */
318
if (error != -EINPROGRESS) { DUMP_CORE; }
320
/* 4 sends INIT to 1. */
321
printk("\n 4->1 INIT\n\n");
322
if (!test_for_chunk(SCTP_CID_INIT, netw[0])) {
326
printk("\n 1->3 INIT ACK\n\n");
327
if (test_step(SCTP_CID_INIT_ACK, netw[0])<= 0 ) {
331
printk("\n 3->1 COOKIE ECHO\n\n");
332
if (test_step(SCTP_CID_COOKIE_ECHO, netw[0])<= 0 ) {
336
printk("\n 1->3 COOKIE ACK\n\n");
337
if (test_step(SCTP_CID_COOKIE_ACK, netw[0])<= 0 ) {
341
if (test_run_network_once(netw[0]) < 0) {
345
/* Return 2->1 INIT ACK to queue. */
346
printk("\n Return 2->1 INIT ACK to queue.\n\n");
347
test_inject_packet(netw[0], pkt1);
349
if (test_step(SCTP_CID_COOKIE_ECHO, netw[0])<= 0 ) {
353
/* Hold 1->2 COOKIE ECHO. */
354
printk("\n Hold 1->2 COOKIE ECHO.\n\n");
355
pkt1 = test_steal_packet(netw[0]);
357
/* Return 1->2 INIT ACK to queue. */
358
printk("\n Return 1->2 INIT ACK to queue.\n\n");
359
test_inject_packet(netw[0], pkt2);
361
printk("\n 2->1 COOKIE ECHO\n\n");
362
if (test_step(SCTP_CID_COOKIE_ECHO, netw[0])<= 0 ) {
366
/* Hold 2->1 COOKIE ECHO. */
367
printk("\n Hold 1->2 COOKIE ECHO.\n\n");
368
pkt2 = test_steal_packet(netw[0]);
370
/* Return 1->2 COOKIE ECHO to queue. */
371
printk("\n Return 1->2 COOKIE ECHO to queue.\n\n");
372
test_inject_packet(netw[0], pkt1);
374
printk("\n 1->2 COOKIE ECHO DROPPED\n\n");
375
if (test_step(SCTP_CID_COOKIE_ACK, netw[0])> 0 ) {
379
printk("\n Association 0 (%p):\n", asoc[0]);
380
print_assoc_peer_transports(asoc[0]);
381
printk("\n Association 1 (%p):\n", asoc[1]);
382
print_assoc_peer_transports(asoc[1]);
383
test_assoc_peer_transports(asoc[0], &loop[1], 2);
384
test_assoc_peer_transports(asoc[1], &loop[0], 1);
386
/* Return 2->1 COOKIE ECHO to queue. */
387
printk("\n Return 2->1 COOKIE ECHO to queue.\n\n");
388
test_inject_packet(netw[0], pkt2);
390
printk("\n 1->2 COOKIE ACK\n\n");
391
if (test_step(SCTP_CID_COOKIE_ACK, netw[0])<= 0 ) {
395
if (test_run_network_once(netw[0]) < 0) {
399
/* Return 1->3 INIT ACK to queue. */
400
printk("\n Return 1->3 INIT ACK to queue.\n\n");
401
test_inject_packet(netw[0], pkt3);
403
printk("\n 3->1 COOKIE ECHO\n\n");
404
if (test_step(SCTP_CID_COOKIE_ECHO, netw[0])<= 0 ) {
408
printk("\n 1->3 COOKIE ACK\n\n");
409
if (test_step(SCTP_CID_COOKIE_ACK, netw[0])<= 0 ) {
413
error = test_run_network();
414
if (error != 0) { DUMP_CORE; }
416
printk("Test asoc[0] state ESTABLISHED\n");
417
if (!sctp_state(asoc[0], ESTABLISHED)) {
421
printk("Test asoc[1] state ESTABLISHED\n");
422
if (!sctp_state(asoc[1], ESTABLISHED)) {
426
ep[2] = sctp_sk(sk[2])->ep;
427
asoc[2] = test_ep_first_asoc(ep[2]);
428
ep[3] = sctp_sk(sk[3])->ep;
429
asoc[3] = test_ep_first_asoc(ep[3]);
431
printk("Test asoc[2] state ESTABLISHED\n");
432
if (!sctp_state(asoc[2], ESTABLISHED)) {
436
printk("Test asoc[3] state ESTABLISHED\n");
437
if (!sctp_state(asoc[3], ESTABLISHED)) {
441
printk("\n Association 0 (%p):\n", asoc[0]);
442
print_assoc_peer_transports(asoc[0]);
443
printk("\n Association 1 (%p):\n", asoc[1]);
444
print_assoc_peer_transports(asoc[1]);
445
printk("\n Association 2 (%p):\n", asoc[2]);
446
print_assoc_peer_transports(asoc[2]);
447
printk("\n Association 3 (%p):\n", asoc[3]);
448
print_assoc_peer_transports(asoc[3]);
449
test_assoc_peer_transports(asoc[0], &loop[1], 2);
450
test_assoc_peer_transports(asoc[1], &loop[0], 1);
451
test_assoc_peer_transports(asoc[2], &loop[0], 1);
452
test_assoc_peer_transports(asoc[3], &loop[0], 1);
454
/* If we get to this point, the test has passed. The rest is
457
/* Shut down the link. */
458
sctp_close(sk[0], /* timeout */ 0);
460
error = test_run_network();
461
if (error != 0) { DUMP_CORE; }
463
sctp_close(sk[1], /* timeout */ 0);
464
sctp_close(sk[2], /* timeout */ 0);
465
sctp_close(sk[3], /* timeout */ 0);
468
printk("\n%s passed\n\n\n", argv[0]);
471
/* Indicate successful completion. */