File Index
Files and directories
Sign in
FILE

connect_close.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/netfilter/connect_close.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <fcntl.h>
  6#include <string.h>
  7#include <unistd.h>
  8#include <signal.h>
  9
 10#include <arpa/inet.h>
 11#include <sys/socket.h>
 12
 13#define PORT 12345
 14#define RUNTIME 10
 15
 16static struct {
 17	unsigned int timeout;
 18	unsigned int port;
 19} opts = {
 20	.timeout = RUNTIME,
 21	.port = PORT,
 22};
 23
 24static void handler(int sig)
 25{
 26	_exit(sig == SIGALRM ? 0 : 1);
 27}
 28
 29static void set_timeout(void)
 30{
 31	struct sigaction action = {
 32		.sa_handler = handler,
 33	};
 34
 35	sigaction(SIGALRM, &action, NULL);
 36
 37	alarm(opts.timeout);
 38}
 39
 40static void do_connect(const struct sockaddr_in *dst)
 41{
 42	int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 43
 44	if (s >= 0)
 45		fcntl(s, F_SETFL, O_NONBLOCK);
 46
 47	connect(s, (struct sockaddr *)dst, sizeof(*dst));
 48	close(s);
 49}
 50
 51static void do_accept(const struct sockaddr_in *src)
 52{
 53	int c, one = 1, s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 54
 55	if (s < 0)
 56		return;
 57
 58	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
 59	setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
 60
 61	bind(s, (struct sockaddr *)src, sizeof(*src));
 62
 63	listen(s, 16);
 64
 65	c = accept(s, NULL, NULL);
 66	if (c >= 0)
 67		close(c);
 68
 69	close(s);
 70}
 71
 72static int accept_loop(void)
 73{
 74	struct sockaddr_in src = {
 75		.sin_family = AF_INET,
 76		.sin_port = htons(opts.port),
 77	};
 78
 79	inet_pton(AF_INET, "127.0.0.1", &src.sin_addr);
 80
 81	set_timeout();
 82
 83	for (;;)
 84		do_accept(&src);
 85
 86	return 1;
 87}
 88
 89static int connect_loop(void)
 90{
 91	struct sockaddr_in dst = {
 92		.sin_family = AF_INET,
 93		.sin_port = htons(opts.port),
 94	};
 95
 96	inet_pton(AF_INET, "127.0.0.1", &dst.sin_addr);
 97
 98	set_timeout();
 99
100	for (;;)
101		do_connect(&dst);
102
103	return 1;
104}
105
106static void parse_opts(int argc, char **argv)
107{
108	int c;
109
110	while ((c = getopt(argc, argv, "t:p:")) != -1) {
111		switch (c) {
112		case 't':
113			opts.timeout = atoi(optarg);
114			break;
115		case 'p':
116			opts.port = atoi(optarg);
117			break;
118		}
119	}
120}
121
122int main(int argc, char *argv[])
123{
124	pid_t p;
125
126	parse_opts(argc, argv);
127
128	p = fork();
129	if (p < 0)
130		return 111;
131
132	if (p > 0)
133		return accept_loop();
134
135	return connect_loop();
136}
~/ Read-only file preview.