mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-20 18:07:49 +00:00
BUG/MINOR: listener: Don't decrease actconn twice when a new session is rejected
When a freshly created session is rejected, for any reason, during the accept in the function "session_accept_fd", the variable "actconn" is decreased twice. The first time when the rejected session is released, then in the function "listener_accpect", because of the failure. So it is possible to have an negative value for actconn. Note that, in this case, we will also have a negatve value for the current number of connections on the listener rejecting the session (actconn and l->nbconn are in/decreased in same time). It is easy to reproduce the bug with this small configuration: global stats socket /tmp/haproxy listen test bind *:12345 tcp-request connection reject if TRUE A "show info" on the stat socket, after a connection attempt, will show a very high value (the unsigned representation of -1). To fix the bug, if the function "session_accept_fd" returns an error, it decrements the right counters and "listener_accpect" leaves them untouched. This patch must be backported in 1.8.
This commit is contained in:
parent
8adae7c15f
commit
fe234281d6
@ -617,9 +617,6 @@ void listener_accept(int fd)
|
||||
* error due to a resource shortage, and we must stop the
|
||||
* listener (ret < 0).
|
||||
*/
|
||||
if (!(l->options & LI_O_UNLIMITED))
|
||||
HA_ATOMIC_SUB(&actconn, 1);
|
||||
HA_ATOMIC_SUB(&l->nbconn, 1);
|
||||
if (ret == 0) /* successful termination */
|
||||
continue;
|
||||
|
||||
|
@ -269,12 +269,16 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr
|
||||
|
||||
/* error unrolling */
|
||||
out_free_sess:
|
||||
/* prevent call to listener_release during session_free. It will be
|
||||
* done below, for all errors. */
|
||||
sess->listener = NULL;
|
||||
session_free(sess);
|
||||
out_free_conn:
|
||||
conn_stop_tracking(cli_conn);
|
||||
conn_xprt_close(cli_conn);
|
||||
conn_free(cli_conn);
|
||||
out_close:
|
||||
listener_release(l);
|
||||
if (ret < 0 && l->bind_conf->xprt == xprt_get(XPRT_RAW) && p->mode == PR_MODE_HTTP) {
|
||||
/* critical error, no more memory, try to emit a 500 response */
|
||||
struct chunk *err_msg = &p->errmsg[HTTP_ERR_500];
|
||||
|
Loading…
Reference in New Issue
Block a user