1#!/bin/sh 2 3# Based on https://gist.github.com/zonque/7d03568eab14a2bb57cb by 4# Daniel Mack github@zonque.org 5 6# "panic: general protection fault" seen: 7# https://people.freebsd.org/~pho/stress/log/sctp.txt 8# Fixed by r350626 9 10kldstat -v | grep -q sctp || kldload sctp.ko 11cat > /tmp/sctp.c <<EOF 12#include <sys/types.h> 13#include <sys/socket.h> 14#include <unistd.h> 15#include <arpa/inet.h> 16#include <libgen.h> 17#include <netinet/in.h> 18#include <netinet/sctp.h> 19#include <stdio.h> 20#include <stdlib.h> 21#include <string.h> 22 23static int my_port_num; 24 25static void 26die(const char *s) 27{ 28 perror(s); 29 exit(1); 30} 31 32 static void 33server(void) 34{ 35 struct sctp_sndrcvinfo sndrcvinfo; 36 struct sockaddr_in servaddr = { 37 .sin_family = AF_INET, 38 .sin_addr.s_addr = htonl(INADDR_ANY), 39 .sin_port = htons(my_port_num), 40 }; 41 struct sctp_initmsg initmsg = { 42 .sinit_num_ostreams = 5, 43 .sinit_max_instreams = 5, 44 .sinit_max_attempts = 4, 45 }; 46 int listen_fd, conn_fd, flags, ret, in; 47 48 listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); 49 if (listen_fd < 0) 50 die("socket"); 51 52 ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 53 if (ret < 0) 54 die("bind"); 55 56 ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, 57 sizeof(initmsg)); 58 if (ret < 0) 59 die("setsockopt"); 60 61 ret = listen(listen_fd, initmsg.sinit_max_instreams); 62 if (ret < 0) 63 die("listen"); 64 65 for (;;) { 66 char buffer[1024]; 67 68 printf("Waiting for connection\n"); 69 fflush(stdout); 70 71 conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL); 72 if(conn_fd < 0) 73 die("accept()"); 74 75 printf("New client connected\n"); 76 fflush(stdout); 77 78 /* Note that flags is uninitialized here */ 79 in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0, 80 &sndrcvinfo, &flags); 81 if (in > 0) { 82 printf("Received data: %s\n", buffer); 83 fflush(stdout); 84 } 85 86 close(conn_fd); 87 } 88} 89 90static void 91client(void) 92{ 93 struct sockaddr_in servaddr = { 94 .sin_family = AF_INET, 95 .sin_port = htons(my_port_num), 96 .sin_addr.s_addr = inet_addr("127.0.0.1"), 97 }; 98 int conn_fd, ret; 99 const char *msg = "Hello, Server!"; 100 101 conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); 102 if (conn_fd < 0) 103 die("socket()"); 104 105 ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 106 if (ret < 0) 107 die("connect()"); 108 109 ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 ); 110 if (ret < 0) 111 die("sctp_sendmsg"); 112 113 close(conn_fd); 114} 115 116int 117main(int argc __unused, char *argv[]) 118{ 119 120 my_port_num = atoi(argv[1]); 121 if (strstr(basename(argv[0]), "server")) 122 server(); 123 else 124 client(); 125 126 return (0); 127} 128EOF 129 130cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp.c || exit 131ln -sf /tmp/server /tmp/client 132 133parallel=100 134for i in `jot $parallel 62324`; do 135 /tmp/server $i > /dev/null & 136done 137(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) & 138sleep 2 139 140start=`date +%s` 141while [ $((`date +%s` - start)) -lt 60 ]; do 142 pids= 143 for i in `jot 50`; do 144 for j in `jot $parallel 62324`; do 145 /tmp/client $j & 146 pids="$pids $!" 147 done 148 done 149 for i in $pids; do 150 wait $i 151 done 152done 153pkill server 154wait 155while pkill swap; do :; done 156wait 157rm -f /tmp/sctp.c /tmp/server /tmp/client 158exit 0 159