1*2c042e8eSKuniyuki Iwashima // SPDX-License-Identifier: GPL-2.0
2*2c042e8eSKuniyuki Iwashima /* Copyright Amazon.com Inc. or its affiliates. */
3*2c042e8eSKuniyuki Iwashima 
4*2c042e8eSKuniyuki Iwashima #include <sys/socket.h>
5*2c042e8eSKuniyuki Iwashima #include <netinet/in.h>
6*2c042e8eSKuniyuki Iwashima 
7*2c042e8eSKuniyuki Iwashima #include "../kselftest_harness.h"
8*2c042e8eSKuniyuki Iwashima 
FIXTURE(bind_timewait)9*2c042e8eSKuniyuki Iwashima FIXTURE(bind_timewait)
10*2c042e8eSKuniyuki Iwashima {
11*2c042e8eSKuniyuki Iwashima 	struct sockaddr_in addr;
12*2c042e8eSKuniyuki Iwashima 	socklen_t addrlen;
13*2c042e8eSKuniyuki Iwashima };
14*2c042e8eSKuniyuki Iwashima 
FIXTURE_VARIANT(bind_timewait)15*2c042e8eSKuniyuki Iwashima FIXTURE_VARIANT(bind_timewait)
16*2c042e8eSKuniyuki Iwashima {
17*2c042e8eSKuniyuki Iwashima 	__u32 addr_const;
18*2c042e8eSKuniyuki Iwashima };
19*2c042e8eSKuniyuki Iwashima 
FIXTURE_VARIANT_ADD(bind_timewait,localhost)20*2c042e8eSKuniyuki Iwashima FIXTURE_VARIANT_ADD(bind_timewait, localhost)
21*2c042e8eSKuniyuki Iwashima {
22*2c042e8eSKuniyuki Iwashima 	.addr_const = INADDR_LOOPBACK
23*2c042e8eSKuniyuki Iwashima };
24*2c042e8eSKuniyuki Iwashima 
FIXTURE_VARIANT_ADD(bind_timewait,addrany)25*2c042e8eSKuniyuki Iwashima FIXTURE_VARIANT_ADD(bind_timewait, addrany)
26*2c042e8eSKuniyuki Iwashima {
27*2c042e8eSKuniyuki Iwashima 	.addr_const = INADDR_ANY
28*2c042e8eSKuniyuki Iwashima };
29*2c042e8eSKuniyuki Iwashima 
FIXTURE_SETUP(bind_timewait)30*2c042e8eSKuniyuki Iwashima FIXTURE_SETUP(bind_timewait)
31*2c042e8eSKuniyuki Iwashima {
32*2c042e8eSKuniyuki Iwashima 	self->addr.sin_family = AF_INET;
33*2c042e8eSKuniyuki Iwashima 	self->addr.sin_port = 0;
34*2c042e8eSKuniyuki Iwashima 	self->addr.sin_addr.s_addr = htonl(variant->addr_const);
35*2c042e8eSKuniyuki Iwashima 	self->addrlen = sizeof(self->addr);
36*2c042e8eSKuniyuki Iwashima }
37*2c042e8eSKuniyuki Iwashima 
FIXTURE_TEARDOWN(bind_timewait)38*2c042e8eSKuniyuki Iwashima FIXTURE_TEARDOWN(bind_timewait)
39*2c042e8eSKuniyuki Iwashima {
40*2c042e8eSKuniyuki Iwashima }
41*2c042e8eSKuniyuki Iwashima 
create_timewait_socket(struct __test_metadata * _metadata,FIXTURE_DATA (bind_timewait)* self)42*2c042e8eSKuniyuki Iwashima void create_timewait_socket(struct __test_metadata *_metadata,
43*2c042e8eSKuniyuki Iwashima 			    FIXTURE_DATA(bind_timewait) *self)
44*2c042e8eSKuniyuki Iwashima {
45*2c042e8eSKuniyuki Iwashima 	int server_fd, client_fd, child_fd, ret;
46*2c042e8eSKuniyuki Iwashima 	struct sockaddr_in addr;
47*2c042e8eSKuniyuki Iwashima 	socklen_t addrlen;
48*2c042e8eSKuniyuki Iwashima 
49*2c042e8eSKuniyuki Iwashima 	server_fd = socket(AF_INET, SOCK_STREAM, 0);
50*2c042e8eSKuniyuki Iwashima 	ASSERT_GT(server_fd, 0);
51*2c042e8eSKuniyuki Iwashima 
52*2c042e8eSKuniyuki Iwashima 	ret = bind(server_fd, (struct sockaddr *)&self->addr, self->addrlen);
53*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(ret, 0);
54*2c042e8eSKuniyuki Iwashima 
55*2c042e8eSKuniyuki Iwashima 	ret = listen(server_fd, 1);
56*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(ret, 0);
57*2c042e8eSKuniyuki Iwashima 
58*2c042e8eSKuniyuki Iwashima 	ret = getsockname(server_fd, (struct sockaddr *)&self->addr, &self->addrlen);
59*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(ret, 0);
60*2c042e8eSKuniyuki Iwashima 
61*2c042e8eSKuniyuki Iwashima 	client_fd = socket(AF_INET, SOCK_STREAM, 0);
62*2c042e8eSKuniyuki Iwashima 	ASSERT_GT(client_fd, 0);
63*2c042e8eSKuniyuki Iwashima 
64*2c042e8eSKuniyuki Iwashima 	ret = connect(client_fd, (struct sockaddr *)&self->addr, self->addrlen);
65*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(ret, 0);
66*2c042e8eSKuniyuki Iwashima 
67*2c042e8eSKuniyuki Iwashima 	addrlen = sizeof(addr);
68*2c042e8eSKuniyuki Iwashima 	child_fd = accept(server_fd, (struct sockaddr *)&addr, &addrlen);
69*2c042e8eSKuniyuki Iwashima 	ASSERT_GT(child_fd, 0);
70*2c042e8eSKuniyuki Iwashima 
71*2c042e8eSKuniyuki Iwashima 	close(child_fd);
72*2c042e8eSKuniyuki Iwashima 	close(client_fd);
73*2c042e8eSKuniyuki Iwashima 	close(server_fd);
74*2c042e8eSKuniyuki Iwashima }
75*2c042e8eSKuniyuki Iwashima 
76*2c042e8eSKuniyuki Iwashima TEST_F(bind_timewait, 1)
77*2c042e8eSKuniyuki Iwashima {
78*2c042e8eSKuniyuki Iwashima 	int fd, ret;
79*2c042e8eSKuniyuki Iwashima 
80*2c042e8eSKuniyuki Iwashima 	create_timewait_socket(_metadata, self);
81*2c042e8eSKuniyuki Iwashima 
82*2c042e8eSKuniyuki Iwashima 	fd = socket(AF_INET, SOCK_STREAM, 0);
83*2c042e8eSKuniyuki Iwashima 	ASSERT_GT(fd, 0);
84*2c042e8eSKuniyuki Iwashima 
85*2c042e8eSKuniyuki Iwashima 	ret = bind(fd, (struct sockaddr *)&self->addr, self->addrlen);
86*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(ret, -1);
87*2c042e8eSKuniyuki Iwashima 	ASSERT_EQ(errno, EADDRINUSE);
88*2c042e8eSKuniyuki Iwashima 
89*2c042e8eSKuniyuki Iwashima 	close(fd);
90*2c042e8eSKuniyuki Iwashima }
91*2c042e8eSKuniyuki Iwashima 
92*2c042e8eSKuniyuki Iwashima TEST_HARNESS_MAIN
93