xref: /freebsd/tools/test/stress2/misc/sctp3.sh (revision 61e21613)
1#!/bin/sh
2
3# Based on https://gist.github.com/zonque/7d03568eab14a2bb57cb by
4# Daniel Mack github@zonque.org
5
6# Modified version of sctp.sh by Michael Tuexen <tuexen@freebsd.org>:
7# Basically it is the first test without calling sctp_recvmsg() on
8# the server side and the required cleanups to avoid unused variables.
9# This program triggers pretty quickly the "Queues are not empty when
10# handling SHUTDOWN-COMPLETE" panic. This happened "by accident" with
11# the original sctp.sh, if the flags argument contained the value
12# MSG_DONTWAIT and sctp_recvmsg() returned -1 indicating EAGAIN. This
13# way no successful sctp_recvmsg() call happened.
14
15# "panic: Queues are not empty when handling SHUTDOWN-COMPLETE" seen.
16
17kldstat -v | grep -q sctp || kldload sctp.ko
18cat > /tmp/sctp3.c <<EOF
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <unistd.h>
22#include <arpa/inet.h>
23#include <libgen.h>
24#include <netinet/in.h>
25#include <netinet/sctp.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30static int my_port_num;
31
32static void
33die(const char *s)
34{
35	perror(s);
36	exit(1);
37}
38
39static void
40server(void)
41{
42#if 0
43	struct sctp_sndrcvinfo sndrcvinfo;
44#endif
45	struct sockaddr_in servaddr = {
46		.sin_family = AF_INET,
47		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
48		.sin_port = htons(my_port_num),
49	};
50	struct sctp_initmsg initmsg = {
51		.sinit_num_ostreams = 1,
52		.sinit_max_instreams = 1,
53		.sinit_max_attempts = 4,
54	};
55	int listen_fd, conn_fd, ret;
56#if 0
57	int flags, in;
58#endif
59
60	listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
61	if (listen_fd < 0)
62		die("socket");
63
64	ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
65	if (ret < 0)
66		die("bind");
67
68	ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
69			sizeof(initmsg));
70	if (ret < 0)
71		die("setsockopt");
72
73	ret = listen(listen_fd, 5);
74	if (ret < 0)
75		die("listen");
76
77	for (;;) {
78#if 0
79		char buffer[1024];
80#endif
81		printf("Waiting for connection\n");
82		fflush(stdout);
83
84		conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL);
85		if(conn_fd < 0)
86			die("accept()");
87
88		printf("New client connected\n");
89		fflush(stdout);
90
91#if 0
92		flags = 0;
93		in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0,
94				&sndrcvinfo, &flags);
95		if (in > 0) {
96			printf("Received data: %s\n", buffer);
97			fflush(stdout);
98		}
99#endif
100		close(conn_fd);
101	}
102}
103
104static void
105client(void)
106{
107	struct sockaddr_in servaddr = {
108		.sin_family = AF_INET,
109		.sin_port = htons(my_port_num),
110		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
111	};
112	int conn_fd, ret;
113	const char *msg = "Hello, Server!";
114
115	conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
116	if (conn_fd < 0)
117		die("socket()");
118
119	ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
120	if (ret < 0)
121		die("connect()");
122
123	ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 );
124	if (ret < 0)
125		die("sctp_sendmsg");
126
127	close(conn_fd);
128}
129
130int
131main(int argc __unused, char *argv[])
132{
133
134	my_port_num = atoi(argv[1]);
135	if (strstr(basename(argv[0]), "server"))
136		server();
137	else
138		client();
139
140	return (0);
141}
142EOF
143
144cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp3.c || exit
145ln -sf /tmp/server /tmp/client
146
147parallel=100
148for i in `jot $parallel 62324`; do
149	/tmp/server $i > /dev/null &
150done
151(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) &
152sleep 2
153
154start=`date +%s`
155while [ $((`date +%s` - start)) -lt 60 ]; do
156	pids=
157	for i in `jot 50`; do
158		for j in `jot $parallel 62324`; do
159			/tmp/client $j &
160			pids="$pids $!"
161		done
162	done
163	for i in $pids; do
164		wait $i
165	done
166done
167pkill server
168wait
169while pkill swap; do :; done
170wait
171rm -f /tmp/sctp3.c /tmp/server /tmp/client
172exit 0
173