|
46 | 46 |
|
47 | 47 | static void accept_connection(h2o_socket_t *listener, const char *err);
|
48 | 48 | static void accept_http_connection(h2o_socket_t *listener, const char *err);
|
49 |
| -static int get_listener_socket(const char *bind_address, uint16_t port); |
| 49 | +static int get_listener_socket(bool is_main_thread, |
| 50 | + int bpf_fd, |
| 51 | + const char *bind_address, |
| 52 | + uint16_t port); |
50 | 53 | static void on_close_connection(void *data);
|
51 | 54 | static void process_messages(h2o_multithread_receiver_t *receiver, h2o_linklist_t *messages);
|
52 | 55 | static void shutdown_server(h2o_socket_t *listener, const char *err);
|
53 |
| -static void start_accept_polling(const config_t *config, |
| 56 | +static void start_accept_polling(bool is_main_thread, |
| 57 | + int bpf_fd, |
| 58 | + const config_t *config, |
54 | 59 | h2o_socket_cb accept_cb,
|
55 | 60 | bool is_https,
|
56 | 61 | event_loop_t *loop);
|
@@ -98,7 +103,10 @@ static void accept_http_connection(h2o_socket_t *listener, const char *err)
|
98 | 103 | ctx->event_loop.h2o_accept_ctx.ssl_ctx = ssl_ctx;
|
99 | 104 | }
|
100 | 105 |
|
101 |
| -static int get_listener_socket(const char *bind_address, uint16_t port) |
| 106 | +static int get_listener_socket(bool is_main_thread, |
| 107 | + int bpf_fd, |
| 108 | + const char *bind_address, |
| 109 | + uint16_t port) |
102 | 110 | {
|
103 | 111 | int ret = -1;
|
104 | 112 | char buf[16];
|
@@ -148,6 +156,15 @@ static int get_listener_socket(const char *bind_address, uint16_t port)
|
148 | 156 | LOCAL_CHECK_ERRNO(setsockopt, s, IPPROTO_TCP, TCP_FASTOPEN, &option, sizeof(option));
|
149 | 157 | LOCAL_CHECK_ERRNO(bind, s, iter->ai_addr, iter->ai_addrlen);
|
150 | 158 | LOCAL_CHECK_ERRNO(listen, s, INT_MAX);
|
| 159 | + |
| 160 | + if (is_main_thread && bpf_fd >= 0) |
| 161 | + LOCAL_CHECK_ERRNO(setsockopt, |
| 162 | + s, |
| 163 | + SOL_SOCKET, |
| 164 | + SO_ATTACH_REUSEPORT_EBPF, |
| 165 | + &bpf_fd, |
| 166 | + sizeof(bpf_fd)); |
| 167 | + |
151 | 168 | ret = s;
|
152 | 169 | break;
|
153 | 170 |
|
@@ -256,16 +273,17 @@ static void shutdown_server(h2o_socket_t *listener, const char *err)
|
256 | 273 | }
|
257 | 274 | }
|
258 | 275 |
|
259 |
| -static void start_accept_polling(const config_t *config, |
| 276 | +static void start_accept_polling(bool is_main_thread, |
| 277 | + int bpf_fd, |
| 278 | + const config_t *config, |
260 | 279 | h2o_socket_cb accept_cb,
|
261 | 280 | bool is_https,
|
262 | 281 | event_loop_t *loop)
|
263 | 282 | {
|
264 |
| - const int listener_sd = get_listener_socket(config->bind_address, |
| 283 | + const int listener_sd = get_listener_socket(is_main_thread, |
| 284 | + bpf_fd, |
| 285 | + config->bind_address, |
265 | 286 | is_https ? config->https_port : config->port);
|
266 |
| - // Let all the threads race to call accept() on the socket; since the latter is |
267 |
| - // non-blocking, that will virtually act as load balancing, and SO_REUSEPORT |
268 |
| - // will make it efficient. |
269 | 287 | h2o_socket_t * const h2o_socket = h2o_evloop_socket_create(loop->h2o_ctx.loop,
|
270 | 288 | listener_sd,
|
271 | 289 | H2O_SOCKET_FLAG_DONT_READ);
|
@@ -345,13 +363,18 @@ void initialize_event_loop(bool is_main_thread,
|
345 | 363 |
|
346 | 364 | if (global_data->ssl_ctx) {
|
347 | 365 | loop->h2o_accept_ctx.ssl_ctx = global_data->ssl_ctx;
|
348 |
| - start_accept_polling(config, accept_connection, true, loop); |
| 366 | + start_accept_polling(is_main_thread, |
| 367 | + global_data->bpf_fd, |
| 368 | + config, |
| 369 | + accept_connection, |
| 370 | + true, |
| 371 | + loop); |
349 | 372 | // Assume that the majority of the connections use HTTPS,
|
350 | 373 | // so HTTP can take a few extra operations.
|
351 | 374 | accept_cb = accept_http_connection;
|
352 | 375 | }
|
353 | 376 |
|
354 |
| - start_accept_polling(config, accept_cb, false, loop); |
| 377 | + start_accept_polling(is_main_thread, global_data->bpf_fd, config, accept_cb, false, loop); |
355 | 378 | h2o_multithread_register_receiver(loop->h2o_ctx.queue,
|
356 | 379 | h2o_receiver,
|
357 | 380 | process_messages);
|
|
0 commit comments