diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index 4ff43c095..25449e451 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -203,6 +203,7 @@ struct bind_conf { int maxaccept; /* if set, max number of connections accepted at once (-1 when disabled) */ unsigned int backlog; /* if set, listen backlog */ int maxconn; /* maximum connections allowed on this listener */ + int (*accept)(struct connection *conn); /* upper layer's accept() */ int level; /* stats access level (ACCESS_LVL_*) */ int severity_output; /* default severity output format in cli feedback messages */ struct list listeners; /* list of listeners using this bind config */ @@ -244,7 +245,6 @@ struct listener { struct fe_counters *counters; /* statistics counters */ int nbconn; /* current number of connections on this listener */ - int (*accept)(struct connection *conn); /* upper layer's accept() */ enum obj_type *default_target; /* default target to use for accepted sessions or NULL */ /* cache line boundary */ struct mt_list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */ diff --git a/src/cfgparse.c b/src/cfgparse.c index ed9c85c5b..88e772871 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -716,6 +716,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) } bind_conf->maxaccept = 1; + bind_conf->accept = session_accept_fd; if (*args[0] == 'b') { struct listener *l; @@ -746,7 +747,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) * Newly allocated listener is at the end of the list */ l = LIST_ELEM(bind_conf->listeners.p, typeof(l), by_bind); - l->accept = session_accept_fd; l->default_target = curpeers->peers_fe->default_target; l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */ global.maxsock++; /* for the listening socket */ @@ -949,6 +949,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) } bind_conf->maxaccept = 1; + bind_conf->accept = session_accept_fd; if (!LIST_ISEMPTY(&bind_conf->listeners)) { ha_alert("parsing [%s:%d] : One listener per \"peers\" section is authorized but another is already configured at [%s:%d].\n", file, linenum, bind_conf->file, bind_conf->line); @@ -971,7 +972,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) * Newly allocated listener is at the end of the list */ l = LIST_ELEM(bind_conf->listeners.p, typeof(l), by_bind); - l->accept = session_accept_fd; l->default_target = curpeers->peers_fe->default_target; l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */ global.maxsock++; /* for the listening socket */ @@ -4289,6 +4289,7 @@ init_proxies_list_stage2: bind_conf->analysers |= curproxy->fe_req_ana; if (!bind_conf->maxaccept) bind_conf->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : MAX_ACCEPT; + bind_conf->accept = session_accept_fd; } /* adjust this proxy's listeners */ @@ -4314,10 +4315,7 @@ init_proxies_list_stage2: if (curproxy->options & PR_O_TCP_NOLING) listener->options |= LI_O_NOLINGER; - /* listener accept callback */ - listener->accept = session_accept_fd; #ifdef USE_QUIC - /* override the accept callback for QUIC listeners. */ if (listener->flags & LI_F_QUIC_LISTENER) { if (!global.cluster_secret) { diag_no_cluster_secret = 1; diff --git a/src/cli.c b/src/cli.c index ced990cce..c917ea21e 100644 --- a/src/cli.c +++ b/src/cli.c @@ -551,8 +551,8 @@ static int cli_parse_global(char **args, int section_type, struct proxy *curpx, return -1; } + bind_conf->accept = session_accept_fd; list_for_each_entry(l, &bind_conf->listeners, by_bind) { - l->accept = session_accept_fd; l->default_target = global.cli_fe->default_target; l->options |= LI_O_UNLIMITED; /* don't make the peers subject to global limits */ l->nice = -64; /* we want to boost priority for local stats */ @@ -3044,8 +3044,8 @@ struct bind_conf *mworker_cli_proxy_new_listener(char *line) } + bind_conf->accept = session_accept_fd; list_for_each_entry(l, &bind_conf->listeners, by_bind) { - l->accept = session_accept_fd; l->default_target = mworker_proxy->default_target; /* don't make the peers subject to global limits and don't close it in the master */ l->options |= LI_O_UNLIMITED; @@ -3111,8 +3111,8 @@ int mworker_cli_sockpair_new(struct mworker_proc *mworker_proc, int proc) } ha_free(&path); + bind_conf->accept = session_accept_fd; list_for_each_entry(l, &bind_conf->listeners, by_bind) { - l->accept = session_accept_fd; l->default_target = global.cli_fe->default_target; l->options |= (LI_O_UNLIMITED | LI_O_NOSTOP); HA_ATOMIC_INC(&unstoppable_jobs); diff --git a/src/listener.c b/src/listener.c index 0a44b1bba..86cf85cba 100644 --- a/src/listener.c +++ b/src/listener.c @@ -142,14 +142,15 @@ struct task *accept_queue_process(struct task *t, void *context, unsigned int st li = __objt_listener(conn->target); _HA_ATOMIC_INC(&li->thr_conn[tid]); - ret = li->accept(conn); + ret = li->bind_conf->accept(conn); if (ret <= 0) { /* connection was terminated by the application */ continue; } /* increase the per-process number of cumulated sessions, this - * may only be done once l->accept() has accepted the connection. + * may only be done once l->bind_conf->accept() has accepted the + * connection. */ if (!(li->options & LI_O_UNLIMITED)) { HA_ATOMIC_UPDATE_MAX(&global.sps_max, @@ -1007,7 +1008,7 @@ void listener_accept(struct listener *l) _HA_ATOMIC_INC(&activity[tid].accepted); - /* past this point, l->accept() will automatically decrement + /* past this point, l->bind_conf->accept() will automatically decrement * l->nbconn, feconn and actconn once done. Setting next_*conn=0 * allows the error path not to rollback on nbconn. It's more * convenient than duplicating all exit labels. @@ -1137,7 +1138,7 @@ void listener_accept(struct listener *l) local_accept: _HA_ATOMIC_INC(&l->thr_conn[tid]); - ret = l->accept(cli_conn); + ret = l->bind_conf->accept(cli_conn); if (unlikely(ret <= 0)) { /* The connection was closed by stream_accept(). Either * we just have to ignore it (ret == 0) or it's a critical @@ -1151,7 +1152,8 @@ void listener_accept(struct listener *l) } /* increase the per-process number of cumulated sessions, this - * may only be done once l->accept() has accepted the connection. + * may only be done once l->bind_conf->accept() has accepted the + * connection. */ if (!(l->options & LI_O_UNLIMITED)) { count = update_freq_ctr(&global.sess_per_sec, 1); diff --git a/src/log.c b/src/log.c index 91396a3db..b64262148 100644 --- a/src/log.c +++ b/src/log.c @@ -3811,6 +3811,7 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm) } bind_conf->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : MAX_ACCEPT; + bind_conf->accept = session_accept_fd; if (!str2listener(args[1], cfg_log_forward, bind_conf, file, linenum, &errmsg)) { if (errmsg && *errmsg) { @@ -3825,7 +3826,6 @@ int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm) } } list_for_each_entry(l, &bind_conf->listeners, by_bind) { - l->accept = session_accept_fd; l->default_target = cfg_log_forward->default_target; global.maxsock++; }