1 // SPDX-License-Identifier: GPL-2.0
3 * This times how long it takes to bind to a port when the port already
4 * has multiple sockets in its bhash table.
6 * In the setup(), we populate the port's bhash table with
7 * MAX_THREADS * MAX_CONNECTIONS number of entries.
17 #define MAX_THREADS 600
18 #define MAX_CONNECTIONS 40
20 static const char *setup_addr_v6
= "::1";
21 static const char *setup_addr_v4
= "127.0.0.1";
22 static const char *setup_addr
;
23 static const char *bind_addr
;
24 static const char *port
;
28 static int fd_array
[MAX_THREADS
][MAX_CONNECTIONS
];
30 static int bind_socket(int opt
, const char *addr
)
32 struct addrinfo
*res
, hint
= {};
33 int sock_fd
, reuse
= 1, err
;
34 int domain
= use_v6
? AF_INET6
: AF_INET
;
36 sock_fd
= socket(domain
, SOCK_STREAM
, 0);
38 perror("socket fd err");
42 hint
.ai_family
= domain
;
43 hint
.ai_socktype
= SOCK_STREAM
;
45 err
= getaddrinfo(addr
, port
, &hint
, &res
);
47 perror("getaddrinfo failed");
52 err
= setsockopt(sock_fd
, SOL_SOCKET
, opt
, &reuse
, sizeof(reuse
));
54 perror("setsockopt failed");
59 err
= bind(sock_fd
, res
->ai_addr
, res
->ai_addrlen
);
61 perror("failed to bind to port");
72 static void *setup(void *arg
)
75 int *array
= (int *)arg
;
77 for (i
= 0; i
< MAX_CONNECTIONS
; i
++) {
78 sock_fd
= bind_socket(SO_REUSEADDR
| SO_REUSEPORT
, setup_addr
);
89 int main(int argc
, const char *argv
[])
91 int listener_fd
, sock_fd
, i
, j
;
92 pthread_t tid
[MAX_THREADS
];
96 printf("Usage: listener <port> <ipv6 | ipv4> <bind-addr>\n");
101 use_v6
= strcmp(argv
[2], "ipv6") == 0;
104 setup_addr
= use_v6
? setup_addr_v6
: setup_addr_v4
;
106 listener_fd
= bind_socket(SO_REUSEADDR
| SO_REUSEPORT
, setup_addr
);
107 if (listen(listener_fd
, 100) < 0) {
108 perror("listen failed");
112 /* Set up threads to populate the bhash table entry for the port */
113 for (i
= 0; i
< MAX_THREADS
; i
++)
114 pthread_create(&tid
[i
], NULL
, setup
, fd_array
[i
]);
116 for (i
= 0; i
< MAX_THREADS
; i
++)
117 pthread_join(tid
[i
], NULL
);
124 /* Bind to the same port on a different address */
125 sock_fd
= bind_socket(0, bind_addr
);
131 printf("time spent = %f\n", (double)(end
- begin
) / CLOCKS_PER_SEC
);
138 for (i
= 0; i
< MAX_THREADS
; i
++) {
139 for (j
= 0; i
< MAX_THREADS
; i
++)
140 close(fd_array
[i
][j
]);