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
* $Id: ft_frame_lost_cookie_ack.c,
10
* This is Functional Test 4 for the SCTP kernel reference
11
* implementation state machine.
13
* Case Study 3: A Lost COOKIE-ACK
14
* Scenario: A lost COOKIE-ACK during the startuo sequence.
16
* Set up a link, send data from sk1 to sk2 first. Let COOKIE ACK lost.
17
* See COOKIE ECHO retransmitted. See the association is up. See messages
18
* appear on both sides. Then go home.
20
* The SCTP reference implementation is free software;
21
* you can redistribute it and/or modify it under the terms of
22
* the GNU General Public License as published by
23
* the Free Software Foundation; either version 2, or (at your option)
26
* The SCTP reference implementation is distributed in the hope that it
27
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
28
* ************************
29
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30
* See the GNU General Public License for more details.
32
* You should have received a copy of the GNU General Public License
33
* along with GNU CC; see the file COPYING. If not, write to
34
* the Free Software Foundation, 59 Temple Place - Suite 330,
35
* Boston, MA 02111-1307, USA.
37
* Please send any bug reports or fixes you make to the
39
* lksctp developers <lksctp-developers@lists.sourceforge.net>
41
* Or submit a bug report through the following website:
42
* http://www.sf.net/projects/lksctp
44
* Written or modified by:
45
* La Monte H.P. Yarroll <piggy@acm.org>
46
* Narasimha Budihal <narsi@refcode.org>
47
* Karl Knutson <karl@athena.chicago.il.us>
48
* Jon "Taz" Mischo <taz@refcode.org>
49
* Sridhar Samudrala <samudrala@us.ibm.com>
50
* Dajiang Zhang <dajiang.zhang@nokia.com>
52
* Any bugs reported given to us we will try to fix... any fixes shared will
53
* be incorporated into the next SCTP release.
56
#include <linux/types.h>
57
#include <linux/list.h> /* For struct list_head */
58
#include <linux/socket.h>
60
#include <linux/time.h> /* For struct timeval */
62
#include <linux/wait.h> /* For wait_queue_head_t */
63
#include <linux/skbuff.h>
64
#include <linux/errno.h>
65
#include <net/sctp/sctp.h>
66
#include <errno.h> /* for sys_errlist[] */
70
main(int argc, char *argv[])
72
struct sctp_endpoint *ep1;
73
struct sctp_association *asoc1;
76
struct sockaddr_in loop1, loop2;
77
uint8_t *message01 = "First message from A!\n";
78
uint8_t *message02 = "Second message from A!\n";
79
uint8_t *message11 = "First message from Z!\n";
80
uint8_t *message12 = "Second message from Z!\n";
83
/* Do all that random stuff needed to make a sensible universe. */
86
/* Create the two endpoints which will talk to each other. */
87
sk1 = sctp_socket(PF_INET, SOCK_SEQPACKET);
88
sk2 = sctp_socket(PF_INET, SOCK_SEQPACKET);
90
loop1.sin_family = AF_INET;
91
loop1.sin_addr.s_addr = SCTP_IP_LOOPBACK;
92
loop1.sin_port = htons(SCTP_TESTPORT_1);
93
loop2.sin_family = AF_INET;
94
loop2.sin_addr.s_addr = SCTP_IP_LOOPBACK;
95
loop2.sin_port = htons(SCTP_TESTPORT_2);
97
/* Bind these sockets to the test ports. */
98
error = test_bind(sk1, (struct sockaddr *)&loop1, sizeof(loop1));
99
if (error != 0) { DUMP_CORE; }
101
error = test_bind(sk2, (struct sockaddr *)&loop2, sizeof(loop2));
102
if (error != 0) { DUMP_CORE; }
104
/* Mark sk2 as being able to accept new associations. */
105
if (0 != sctp_seqpacket_listen(sk2, 1)) {
109
test_frame_send_message(sk1, (struct sockaddr *)&loop2, message01);
111
/* Walk through the startup sequence. */
112
/* We should have an INIT sitting on the Internet. */
113
if (!test_for_chunk(SCTP_CID_INIT, TEST_NETWORK0)) {
116
printf("INIT! \n\n");
118
/* Next we expect an INIT ACK. */
119
if (test_step(SCTP_CID_INIT_ACK, TEST_NETWORK0) <= 0) {
122
printf("INIT_ACK! \n\n");
124
/* We expect a COOKIE ECHO and DATA. */
125
if (test_step(SCTP_CID_COOKIE_ECHO, TEST_NETWORK0) <= 0) {
128
printf("COOKIE_ECHO! \n\n");
130
if (!test_for_chunk(SCTP_CID_DATA, TEST_NETWORK0)) {
133
printf("DATA! \n\n");
135
/* Let COOKIE_ACK lost. */
136
if (test_step(SCTP_CID_COOKIE_ACK, TEST_NETWORK0) <= 0) {
139
printf("COOKIE_ACK is lost! \n\n");
141
test_kill_next_packet(SCTP_CID_COOKIE_ACK);
142
error = test_run_network_once(TEST_NETWORK0);
143
test_kill_next_packet(SCTP_CID_SACK);
144
error = test_run_network_once(TEST_NETWORK0);
146
/* Sleep to make cookie stale. */
149
/* Let COOKIE_ECHO be sent again. */
150
ep1 = sctp_sk(sk1)->ep;
151
asoc1 = test_ep_first_asoc(ep1);
153
/* Resend COOKIE_ECHO. */
154
jiffies += asoc1->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] + 1;
157
/* We expect a COOKIE ECHO and DATA again. */
158
if (!test_for_chunk(SCTP_CID_COOKIE_ECHO, TEST_NETWORK0)) {
161
printf("Send COOKIE_ECHO again! \n\n");
163
/* We expect a COOKIE ECHO and DATA again. */
164
if (!test_for_chunk(SCTP_CID_DATA, TEST_NETWORK0)) {
167
printf("DATA! \n\n");
169
/* We expect a COOKIE ACK. */
170
if (test_step(SCTP_CID_COOKIE_ACK, TEST_NETWORK0) <= 0) {
173
printf("COOKIE_ACK! \n\n");
175
/* We expect a SACK. */
176
if (test_step(SCTP_CID_SACK, TEST_NETWORK0) <= 0) {
179
printf("SACK! \n\n");
181
test_frame_send_message(sk2, (struct sockaddr *)&loop1, message11);
183
error = test_run_network();
184
if (error != 0) { DUMP_CORE; }
186
/* See the messages up. */
187
test_frame_get_event(sk2, SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
188
test_frame_get_event(sk1, SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
190
test_frame_get_message(sk2, message01);
191
test_frame_get_message(sk1, message11);
193
/* Send messages again. */
194
printf("Send meaasage again! \n\n");
195
test_frame_send_message(sk1, (struct sockaddr *)&loop2, message02);
196
test_frame_send_message(sk2, (struct sockaddr *)&loop1, message12);
198
error = test_run_network();
199
if (error != 0) { DUMP_CORE; }
201
test_frame_get_message(sk2, message02);
202
test_frame_get_message(sk1, message12);
204
/* If we get to this point, the test has passed. The rest is
207
/* Shut down the link. */
208
sctp_close(sk1, /* timeout */ 0);
210
error = test_run_network();
211
if (error != 0) { DUMP_CORE; }
213
sctp_close(sk2, /* timeout */ 0);
216
printk("\n\n%s passed\n\n\n", argv[0]);
219
/* Indicate successful completion. */