Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/test/stress2/testcases/tcp/tcp.c
39566 views
1
/*-
2
* Copyright (c) 2008 Peter Holm <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*
26
*/
27
28
#include <sys/param.h>
29
#include <sys/socket.h>
30
#include <sys/wait.h>
31
32
#include <netinet/in.h>
33
34
#include <err.h>
35
#include <errno.h>
36
#include <netdb.h>
37
#include <signal.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <unistd.h>
42
43
#include "stress.h"
44
45
#define NB (400 * 1024 * 1024)
46
47
static int port;
48
static int bufsize;
49
50
static void
51
reader(void) {
52
struct sockaddr_in inetaddr, inetpeer;
53
socklen_t len;
54
int on;
55
int n, *buf;
56
int tcpsock, msgsock;
57
58
alarm(op->run_time + 30);
59
on = 1;
60
if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
61
err(1, "socket(), %s:%d", __FILE__, __LINE__);
62
63
if (setsockopt(tcpsock,
64
SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
65
err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
66
67
inetaddr.sin_family = AF_INET;
68
inetaddr.sin_addr.s_addr = INADDR_ANY;
69
inetaddr.sin_port = htons(port);
70
inetaddr.sin_len = sizeof(inetaddr);
71
72
if (bind(tcpsock,
73
(struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)
74
err(1, "bind(), %s:%d", __FILE__, __LINE__);
75
76
if (listen(tcpsock, 5) < 0)
77
err(1, "listen(), %s:%d", __FILE__, __LINE__);
78
79
if ((random_int(1,100) > 60) || (op->hog == 1)) {
80
usleep(random_int(1000000,1000000) * 60);
81
}
82
83
len = sizeof(inetpeer);
84
if ((msgsock = accept(tcpsock,
85
(struct sockaddr *)&inetpeer, &len)) < 0)
86
err(1, "accept(), %s:%d", __FILE__, __LINE__);
87
88
if ((buf = malloc(bufsize)) == NULL)
89
err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);
90
while (done_testing == 0) {
91
if ((n = read(msgsock, buf, bufsize)) < 0)
92
err(1, "read(), %s:%d", __FILE__, __LINE__);
93
if (n == 0) break;
94
}
95
close(msgsock);
96
return;
97
}
98
99
static void
100
writer(void) {
101
struct sockaddr_in inetaddr;
102
struct hostent *hostent;
103
int i, *buf, r;
104
int tcpsock, on;
105
106
alarm(op->run_time + 30);
107
on = 1;
108
for (i = 1; i < 5; i++) {
109
if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
110
err(1, "socket(), %s:%d", __FILE__, __LINE__);
111
112
if (setsockopt(tcpsock,
113
SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
114
err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
115
116
hostent = gethostbyname ("localhost");
117
bzero((char *) &inetaddr, sizeof(inetaddr));
118
memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,
119
sizeof (struct in_addr));
120
121
inetaddr.sin_family = AF_INET;
122
inetaddr.sin_port = htons(port);
123
inetaddr.sin_len = sizeof(inetaddr);
124
125
r = connect(tcpsock, (struct sockaddr *) &inetaddr,
126
sizeof(inetaddr));
127
if (r == 0)
128
break;
129
sleep(1);
130
close(tcpsock);
131
}
132
if (r < 0)
133
err(1, "connect(), %s:%d", __FILE__, __LINE__);
134
135
if ((buf = malloc(bufsize)) == NULL)
136
err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);
137
for (i = 0; i < bufsize / (int)sizeof(int); i++)
138
buf[i] = i;
139
140
for (;;) {
141
for (i = 0; i < NB; i+= bufsize) {
142
if (write(tcpsock, buf, bufsize) < 0) {
143
if (errno == EPIPE)
144
return;
145
if (errno != ECONNRESET)
146
err(1, "write(%d), %s:%d", tcpsock,
147
__FILE__, __LINE__);
148
_exit(EXIT_SUCCESS);
149
}
150
}
151
}
152
return;
153
}
154
155
int
156
setup(int nb)
157
{
158
port = 12340 + nb;
159
bufsize = 2 << random_int(1, 12);
160
return (0);
161
}
162
163
void
164
cleanup(void)
165
{
166
}
167
168
int
169
test(void)
170
{
171
pid_t pid;
172
173
if ((pid = fork()) == 0) {
174
writer();
175
_exit(EXIT_SUCCESS);
176
177
} else if (pid > 0) {
178
reader();
179
kill(pid, SIGINT);
180
if (waitpid(pid, NULL, 0) != pid)
181
err(1, "waitpid(%d)", pid);
182
} else
183
err(1, "fork(), %s:%d", __FILE__, __LINE__);
184
185
return (0);
186
}
187
188