Path: blob/main/tools/test/stress2/testcases/tcp/tcp.c
39566 views
/*-1* Copyright (c) 2008 Peter Holm <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25*/2627#include <sys/param.h>28#include <sys/socket.h>29#include <sys/wait.h>3031#include <netinet/in.h>3233#include <err.h>34#include <errno.h>35#include <netdb.h>36#include <signal.h>37#include <stdio.h>38#include <stdlib.h>39#include <string.h>40#include <unistd.h>4142#include "stress.h"4344#define NB (400 * 1024 * 1024)4546static int port;47static int bufsize;4849static void50reader(void) {51struct sockaddr_in inetaddr, inetpeer;52socklen_t len;53int on;54int n, *buf;55int tcpsock, msgsock;5657alarm(op->run_time + 30);58on = 1;59if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)60err(1, "socket(), %s:%d", __FILE__, __LINE__);6162if (setsockopt(tcpsock,63SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)64err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);6566inetaddr.sin_family = AF_INET;67inetaddr.sin_addr.s_addr = INADDR_ANY;68inetaddr.sin_port = htons(port);69inetaddr.sin_len = sizeof(inetaddr);7071if (bind(tcpsock,72(struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)73err(1, "bind(), %s:%d", __FILE__, __LINE__);7475if (listen(tcpsock, 5) < 0)76err(1, "listen(), %s:%d", __FILE__, __LINE__);7778if ((random_int(1,100) > 60) || (op->hog == 1)) {79usleep(random_int(1000000,1000000) * 60);80}8182len = sizeof(inetpeer);83if ((msgsock = accept(tcpsock,84(struct sockaddr *)&inetpeer, &len)) < 0)85err(1, "accept(), %s:%d", __FILE__, __LINE__);8687if ((buf = malloc(bufsize)) == NULL)88err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);89while (done_testing == 0) {90if ((n = read(msgsock, buf, bufsize)) < 0)91err(1, "read(), %s:%d", __FILE__, __LINE__);92if (n == 0) break;93}94close(msgsock);95return;96}9798static void99writer(void) {100struct sockaddr_in inetaddr;101struct hostent *hostent;102int i, *buf, r;103int tcpsock, on;104105alarm(op->run_time + 30);106on = 1;107for (i = 1; i < 5; i++) {108if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)109err(1, "socket(), %s:%d", __FILE__, __LINE__);110111if (setsockopt(tcpsock,112SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)113err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);114115hostent = gethostbyname ("localhost");116bzero((char *) &inetaddr, sizeof(inetaddr));117memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,118sizeof (struct in_addr));119120inetaddr.sin_family = AF_INET;121inetaddr.sin_port = htons(port);122inetaddr.sin_len = sizeof(inetaddr);123124r = connect(tcpsock, (struct sockaddr *) &inetaddr,125sizeof(inetaddr));126if (r == 0)127break;128sleep(1);129close(tcpsock);130}131if (r < 0)132err(1, "connect(), %s:%d", __FILE__, __LINE__);133134if ((buf = malloc(bufsize)) == NULL)135err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);136for (i = 0; i < bufsize / (int)sizeof(int); i++)137buf[i] = i;138139for (;;) {140for (i = 0; i < NB; i+= bufsize) {141if (write(tcpsock, buf, bufsize) < 0) {142if (errno == EPIPE)143return;144if (errno != ECONNRESET)145err(1, "write(%d), %s:%d", tcpsock,146__FILE__, __LINE__);147_exit(EXIT_SUCCESS);148}149}150}151return;152}153154int155setup(int nb)156{157port = 12340 + nb;158bufsize = 2 << random_int(1, 12);159return (0);160}161162void163cleanup(void)164{165}166167int168test(void)169{170pid_t pid;171172if ((pid = fork()) == 0) {173writer();174_exit(EXIT_SUCCESS);175176} else if (pid > 0) {177reader();178kill(pid, SIGINT);179if (waitpid(pid, NULL, 0) != pid)180err(1, "waitpid(%d)", pid);181} else182err(1, "fork(), %s:%d", __FILE__, __LINE__);183184return (0);185}186187188