xref: /freebsd/tools/test/stress2/misc/sctp2.sh (revision 59c8e88e72633afbc47a4ace0d2170d00d51f7dc)
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# * Use loopback as the address of the server on both side initialized using
8#   htonl(INADDR_LOOPBACK).
9# * Negotiate only 1 stream in both directions since only one stream is used.
10# * Don't use initmsg.sinit_max_instreams as an argument in listen(), which
11#   does not make sense.
12#   Use an arbitrary positive integer, 5 in this case.
13# * Initialize flags before calling sctp_recvmsg().
14
15# "panic: Don't own TCB lock" seen:
16# https://people.freebsd.org/~pho/stress/log/sctp2.txt
17
18# "panic: soclose: SS_NOFDREF on enter" seen:
19# https://people.freebsd.org/~pho/stress/log/sctp2-2.txt
20
21kldstat -v | grep -q sctp || kldload sctp.ko
22cat > /tmp/sctp2.c <<EOF
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <unistd.h>
26#include <arpa/inet.h>
27#include <libgen.h>
28#include <netinet/in.h>
29#include <netinet/sctp.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34static int my_port_num;
35
36static void
37die(const char *s)
38{
39	perror(s);
40	exit(1);
41}
42
43static void
44server(void)
45{
46	struct sctp_sndrcvinfo sndrcvinfo;
47	struct sockaddr_in servaddr = {
48		.sin_family = AF_INET,
49		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
50		.sin_port = htons(my_port_num),
51	};
52	struct sctp_initmsg initmsg = {
53		.sinit_num_ostreams = 1,
54		.sinit_max_instreams = 1,
55		.sinit_max_attempts = 4,
56	};
57	int listen_fd, conn_fd, flags, ret, in;
58
59	listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
60	if (listen_fd < 0)
61		die("socket");
62
63	ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
64	if (ret < 0)
65		die("bind");
66
67	ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
68			sizeof(initmsg));
69	if (ret < 0)
70		die("setsockopt");
71
72	ret = listen(listen_fd, 5);
73	if (ret < 0)
74		die("listen");
75
76	for (;;) {
77		char buffer[1024];
78
79		printf("Waiting for connection\n");
80		fflush(stdout);
81
82		conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL);
83		if(conn_fd < 0)
84			die("accept()");
85
86		printf("New client connected\n");
87		fflush(stdout);
88
89		flags = 0;
90		in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0,
91				&sndrcvinfo, &flags);
92		if (in > 0) {
93			printf("Received data: %s\n", buffer);
94			fflush(stdout);
95		}
96
97		close(conn_fd);
98	}
99}
100
101static void
102client(void)
103{
104	struct sockaddr_in servaddr = {
105		.sin_family = AF_INET,
106		.sin_port = htons(my_port_num),
107		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
108	};
109	int conn_fd, ret;
110	const char *msg = "Hello, Server!";
111
112	conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
113	if (conn_fd < 0)
114		die("socket()");
115
116	ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
117	if (ret < 0)
118		die("connect()");
119
120	ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 );
121	if (ret < 0)
122		die("sctp_sendmsg");
123
124	close(conn_fd);
125}
126
127int
128main(int argc __unused, char *argv[])
129{
130
131	my_port_num = atoi(argv[1]);
132	if (strstr(basename(argv[0]), "server"))
133		server();
134	else
135		client();
136
137	return (0);
138}
139EOF
140
141cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp2.c || exit
142ln -sf /tmp/server /tmp/client
143
144parallel=100
145for i in `jot $parallel 62324`; do
146	/tmp/server $i > /dev/null &
147done
148(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) &
149sleep 2
150
151start=`date +%s`
152while [ $((`date +%s` - start)) -lt 60 ]; do
153	pids=
154	for i in `jot 50`; do
155		for j in `jot $parallel 62324`; do
156			/tmp/client $j &
157			pids="$pids $!"
158		done
159	done
160	for i in $pids; do
161		wait $i
162	done
163done
164pkill server
165wait
166while pkill swap; do :; done
167wait
168rm -f /tmp/sctp2.c /tmp/server /tmp/client
169exit 0
170