diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 04091745c..80eb55cb9 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -176,6 +176,8 @@ static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt, @@ -424,6 +426,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_object, .u.members = nxt_conf_vldt_client_ip_members + }, { + .name = nxt_string("backlog"), + .type = NXT_CONF_VLDT_NUMBER, + .validator = nxt_conf_vldt_listen_backlog, }, #if (NXT_TLS) @@ -2677,6 +2683,32 @@ nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, } +static nxt_int_t +nxt_conf_vldt_listen_backlog(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data) +{ + int64_t backlog; + + backlog = nxt_conf_get_number(value); + + /* + * POSIX allows this to be 0 and some systems use -1 to + * indicate to use the OS's default value. + */ + if (backlog < -1) { + return nxt_conf_vldt_error(vldt, "The \"backlog\" number must be " + "equal to or greater than -1."); + } + + if (backlog > NXT_INT32_T_MAX) { + return nxt_conf_vldt_error(vldt, "The \"backlog\" number must " + "not exceed %d.", NXT_INT32_T_MAX); + } + + return NXT_OK; +} + + static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) diff --git a/src/nxt_router.c b/src/nxt_router.c index 432094511..2de107f69 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -37,11 +37,6 @@ typedef struct { } nxt_router_app_conf_t; -typedef struct { - nxt_str_t pass; - nxt_str_t application; -} nxt_router_listener_conf_t; - #if (NXT_TLS) @@ -1494,6 +1489,12 @@ static nxt_conf_map_t nxt_router_listener_conf[] = { NXT_CONF_MAP_STR_COPY, offsetof(nxt_router_listener_conf_t, application), }, + + { + nxt_string("backlog"), + NXT_CONF_MAP_INT32, + offsetof(nxt_router_listener_conf_t, backlog), + }, }; @@ -1964,13 +1965,10 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, break; } - skcf = nxt_router_socket_conf(task, tmcf, &name); - if (skcf == NULL) { - goto fail; - } - nxt_memzero(&lscf, sizeof(lscf)); + lscf.backlog = -1; + ret = nxt_conf_map_object(mp, listener, nxt_router_listener_conf, nxt_nitems(nxt_router_listener_conf), &lscf); @@ -1981,6 +1979,13 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_debug(task, "application: %V", &lscf.application); + tmcf->listener_conf = &lscf; + + skcf = nxt_router_socket_conf(task, tmcf, &name); + if (skcf == NULL) { + goto fail; + } + // STUB, default values if http block is not defined. skcf->header_buffer_size = 2048; skcf->large_header_buffer_size = 8192; @@ -2686,12 +2691,13 @@ static nxt_socket_conf_t * nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_str_t *name) { - size_t size; - nxt_int_t ret; - nxt_bool_t wildcard; - nxt_sockaddr_t *sa; - nxt_socket_conf_t *skcf; - nxt_listen_socket_t *ls; + size_t size; + nxt_int_t ret; + nxt_bool_t wildcard; + nxt_sockaddr_t *sa; + nxt_socket_conf_t *skcf; + nxt_listen_socket_t *ls; + nxt_router_listener_conf_t *lscf; sa = nxt_sockaddr_parse(tmcf->mem_pool, name); if (nxt_slow_path(sa == NULL)) { @@ -2727,8 +2733,10 @@ nxt_router_socket_conf(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_listen_socket_remote_size(ls); + lscf = tmcf->listener_conf; + ls->socket = -1; - ls->backlog = NXT_LISTEN_BACKLOG; + ls->backlog = lscf->backlog > -1 ? lscf->backlog : NXT_LISTEN_BACKLOG; ls->flags = NXT_NONBLOCK; ls->read_after_accept = 1; } @@ -2875,7 +2883,7 @@ nxt_router_listen_socket_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_socket_defer_accept(task, s, rpc->socket_conf->listen->sockaddr); - ret = nxt_listen_socket(task, s, NXT_LISTEN_BACKLOG); + ret = nxt_listen_socket(task, s, rpc->socket_conf->listen->backlog); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } diff --git a/src/nxt_router.h b/src/nxt_router.h index cfc7258c5..5c97ec838 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -70,28 +70,34 @@ typedef struct { } action; } nxt_router_engine_conf_t; +typedef struct { + nxt_str_t pass; + nxt_str_t application; + int backlog; +} nxt_router_listener_conf_t; typedef struct { #if (NXT_TLS) - nxt_queue_t tls; /* of nxt_router_tlssock_t */ + nxt_queue_t tls; /* of nxt_router_tlssock_t */ #endif #if (NXT_HAVE_NJS) - nxt_queue_t js_modules; + nxt_queue_t js_modules; #endif - nxt_queue_t apps; /* of nxt_app_t */ - nxt_queue_t previous; /* of nxt_app_t */ + nxt_queue_t apps; /* of nxt_app_t */ + nxt_queue_t previous; /* of nxt_app_t */ - uint32_t new_threads; - uint32_t stream; - uint32_t count; + uint32_t new_threads; + uint32_t stream; + uint32_t count; - nxt_event_engine_t *engine; - nxt_port_t *port; - nxt_array_t *engines; - nxt_router_conf_t *router_conf; - nxt_mp_t *mem_pool; + nxt_event_engine_t *engine; + nxt_port_t *port; + nxt_array_t *engines; + nxt_router_conf_t *router_conf; + nxt_router_listener_conf_t *listener_conf; + nxt_mp_t *mem_pool; } nxt_router_temp_conf_t;