1#!/bin/sh 2 3# 4# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org> 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Copy of callout_reset_on.sh. Waiting to see if this catches anything. 30 31. ../default.cfg 32 33rm -f /tmp/crwriter2 /tmp/crlogger2 || exit 1 34 35cat > /tmp/crwriter2.c <<EOF 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39#include <time.h> 40#include <unistd.h> 41 42char *txt[] = { 43 "0 This is a line of text: abcdefghijklmnopqrstuvwxyz", 44 "1 Another line of text: ABCDEFGHIJKLMNOPQRSTUVWXYZ", 45 "2 A different line of text", 46 "3 A very, very different text", 47 "4 A much longer line with a lot of characters in the line", 48 "5 Now this is a quite long line of text, with both upper and lower case letters, and one digit!" 49}; 50 51#define RUNTIME (10 * 60) 52 53int 54main(void) 55{ 56 time_t start; 57 int j, n; 58 char help[256]; 59 60 start = time(NULL); 61 while (time(NULL) - start < RUNTIME) { 62 j = arc4random() % 6; 63 n = arc4random() % strlen(txt[j]); 64 strncpy(help, txt[j], n); 65 help[n] = 0; 66 printf("%s\n", txt[j]); 67 if ((arc4random() % 1000) == 1) 68 usleep(100000); 69 } 70 71 return (0); 72} 73EOF 74mycc -o /tmp/crwriter2 -Wall -Wextra -O2 -g /tmp/crwriter2.c 75rm -f /tmp/crwriter2.c 76 77cat > /tmp/crlogger2.c <<EOF 78#include <sys/param.h> 79#include <sys/mman.h> 80#include <sys/socket.h> 81#include <sys/wait.h> 82 83#include <machine/atomic.h> 84 85#include <err.h> 86#include <err.h> 87#include <errno.h> 88#include <fcntl.h> 89#include <netdb.h> 90#include <netinet/in.h> 91#include <signal.h> 92#include <stdio.h> 93#include <stdio.h> 94#include <stdlib.h> 95#include <string.h> 96#include <unistd.h> 97#include <unistd.h> 98 99volatile u_int *share; 100 101#define SYNC 0 102 103pid_t pid; 104int bufsize; 105int port; 106int alarm_exit; 107 108void 109killer(void) 110{ 111 setproctitle("killer"); 112 while (share[SYNC] == 0) 113 ; 114 alarm(120); 115 for (;;) { 116 if (pid == 0) 117 break; 118 if (kill(pid, SIGUSR1) == -1) 119 break; 120 usleep(arc4random() % 2000 + 10); 121 } 122 _exit(0); 123} 124 125void 126handler(int s __unused) 127{ 128} 129 130void 131ahandler(int s __unused) 132{ 133 if (alarm_exit) 134 _exit(0); 135} 136 137/* Read form socket, discard */ 138static void 139reader(void) { 140 int tcpsock, msgsock; 141 int on; 142 socklen_t len; 143 struct sockaddr_in inetaddr, inetpeer; 144 int n, *buf; 145 146 setproctitle("reader - init"); 147 on = 1; 148 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 149 err(1, "socket(), %s:%d", __FILE__, __LINE__); 150 151 if (setsockopt(tcpsock, 152 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 153 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 154 155 inetaddr.sin_family = AF_INET; 156 inetaddr.sin_addr.s_addr = INADDR_ANY; 157 inetaddr.sin_port = htons(port); 158 inetaddr.sin_len = sizeof(inetaddr); 159 160 signal(SIGUSR1, handler); 161 alarm(60); 162 if (bind(tcpsock, 163 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) 164 err(1, "bind(), %s:%d", __FILE__, __LINE__); 165 166 if (listen(tcpsock, 5) < 0) 167 err(1, "listen(), %s:%d", __FILE__, __LINE__); 168 169 len = sizeof(inetpeer); 170 if ((msgsock = accept(tcpsock, 171 (struct sockaddr *)&inetpeer, &len)) < 0) 172 err(1, "accept(), %s:%d", __FILE__, __LINE__); 173 174 if ((buf = malloc(bufsize)) == NULL) 175 err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); 176 setproctitle("reader"); 177 alarm(0); 178 signal(SIGALRM, ahandler); 179 for (;;) { 180 ualarm(arc4random() % 5000 + 100, 0); 181 if ((n = recvfrom(msgsock, buf, bufsize, 0, NULL, NULL)) < 0) { 182 if (errno == EAGAIN) 183 continue; 184 err(1, "read(), %s:%d", __FILE__, __LINE__); 185 } 186 if (n == 0) 187 break; 188 if (write(msgsock, "OK", 3) != 3) 189 err(1, "write ack. %s:%d", __FILE__, __LINE__); 190 191 } 192 close(msgsock); 193 _exit(0); 194} 195 196/* read from stdin, write to socket */ 197static void 198writer(void) { 199 int tcpsock, on; 200 struct sockaddr_in inetaddr; 201 struct hostent *hostent; 202 int i, r; 203 char line[1024], ack[80];; 204 205 setproctitle("writer - init"); 206 share[SYNC] = 1; 207 signal(SIGUSR1, handler); 208 signal(SIGALRM, ahandler); 209 alarm(60); 210 on = 1; 211 for (i = 1; i < 5; i++) { 212 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 213 err(1, "socket(), %s:%d", __FILE__, __LINE__); 214 215 if (setsockopt(tcpsock, 216 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 217 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 218 219 hostent = gethostbyname ("localhost"); 220 bzero(&inetaddr, sizeof(inetaddr)); 221 memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, 222 sizeof (struct in_addr)); 223 224 inetaddr.sin_family = AF_INET; 225 inetaddr.sin_port = htons(port); 226 inetaddr.sin_len = sizeof(inetaddr); 227 228 r = connect(tcpsock, (struct sockaddr *) &inetaddr, 229 sizeof(inetaddr)); 230 if (r == 0) 231 break; 232 sleep(1); 233 close(tcpsock); 234 } 235 if (r < 0) 236 err(1, "connect(), %s:%d", __FILE__, __LINE__); 237 238 setproctitle("writer"); 239 alarm(0); 240 while (fgets(line, sizeof(line), stdin) != NULL) { 241 alarm(10); 242 alarm_exit = 1; 243 if (write(tcpsock, line, strlen(line)) < 0) 244 err(1, "socket write(). %s:%d", __FILE__, __LINE__); 245 alarm_exit = 0; 246 ualarm(arc4random() % 5000 + 1000, 0); 247 if (recvfrom(tcpsock, ack, 4, 0, NULL, NULL) < 0) { 248 if (errno == EAGAIN) 249 continue; 250 err(1, "read(), %s:%d", __FILE__, __LINE__); 251 } 252 } 253 sleep(30); 254 return; 255} 256 257int 258main(int argc, char **argv) 259{ 260 261 pid_t kpid; 262 size_t len; 263 264 if (argc != 2) { 265 fprintf(stderr, "Usage: %s <port number>\n", argv[0]); 266 _exit(1); 267 } 268 port = atoi(argv[1]); 269 bufsize = 128; 270 271 len = PAGE_SIZE; 272 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 273 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 274 err(1, "mmap"); 275 276 signal(SIGCHLD, SIG_IGN); 277 if ((pid = fork()) == 0) 278 reader(); 279 280 if ((kpid = fork()) == 0) 281 killer(); 282 283 writer(); 284 sleep(1); 285 kill(pid, SIGINT); 286 kill(kpid, SIGINT); 287 288 return (0); 289} 290EOF 291mycc -o /tmp/crlogger2 -Wall -Wextra -O2 -g /tmp/crlogger2.c 292rm -f /tmp/crlogger2.c 293 294N=50 295cd /tmp 296for j in `jot $N`; do 297 /tmp/crwriter2 | /tmp/crlogger2 1236$j & 298done 299wait 300rm -f /tmp/crwriter2 /tmp/crlogger2 301exit 0 302