From ee991369924ea656d2ed363f83a4ac2b904f19b1 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 14 May 2007 14:37:50 +0200 Subject: [BUG] pre-initialize timeouts with tv_eternity during parsing ETERNITY is not 0 anymore, so all timeouts will not be initialized to ETERNITY by a simple calloc(). We have to explictly assign them. This bug caused random session aborts. --- src/cfgparse.c | 35 ++++++++++++++++++++++++++++++----- src/client.c | 2 +- src/proto_http.c | 26 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index 5165474..5045ed2 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -464,7 +464,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args) static struct proxy *curproxy = NULL; struct server *newsrv = NULL; const char *err; - int rc; + int rc, val; if (!strcmp(args[0], "listen")) rc = PR_CAP_LISTEN; @@ -496,6 +496,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args) LIST_INIT(&curproxy->acl); LIST_INIT(&curproxy->block_cond); + /* Timeouts are defined as -1, so we cannot use the zeroed area + * as a default value. + */ + tv_eternity(&curproxy->clitimeout); + tv_eternity(&curproxy->srvtimeout); + tv_eternity(&curproxy->contimeout); + tv_eternity(&curproxy->appsession_timeout); + curproxy->id = strdup(args[1]); curproxy->cap = rc; @@ -766,7 +774,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args) curproxy->appsession_name = strdup(args[1]); curproxy->appsession_name_len = strlen(curproxy->appsession_name); curproxy->appsession_len = atoi(args[3]); - __tv_from_ms(&curproxy->appsession_timeout, atoi(args[5])); + val = atoi(args[5]); + if (val > 0) + __tv_from_ms(&curproxy->appsession_timeout, val); + else + tv_eternity(&curproxy->appsession_timeout); + rc = chtbl_init(&(curproxy->htbl_proxy), TBLSIZ, hashpjw, match_str, destroy); if (rc) { Alert("Error Init Appsession Hashtable.\n"); @@ -871,7 +884,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args) file, linenum, args[0]); return -1; } - __tv_from_ms(&curproxy->contimeout, atol(args[1])); + val = atoi(args[1]); + if (val > 0) + __tv_from_ms(&curproxy->contimeout, val); + else + tv_eternity(&curproxy->contimeout); } else if (!strcmp(args[0], "clitimeout")) { /* client timeout */ if (!__tv_iseq(&curproxy->clitimeout, &defproxy.clitimeout)) { @@ -887,7 +904,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args) file, linenum, args[0]); return -1; } - __tv_from_ms(&curproxy->clitimeout, atol(args[1])); + val = atoi(args[1]); + if (val > 0) + __tv_from_ms(&curproxy->clitimeout, val); + else + tv_eternity(&curproxy->clitimeout); } else if (!strcmp(args[0], "srvtimeout")) { /* server timeout */ if (!__tv_iseq(&curproxy->srvtimeout, &defproxy.srvtimeout)) { @@ -902,7 +923,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args) file, linenum, args[0]); return -1; } - __tv_from_ms(&curproxy->srvtimeout, atol(args[1])); + val = atoi(args[1]); + if (val > 0) + __tv_from_ms(&curproxy->srvtimeout, val); + else + tv_eternity(&curproxy->srvtimeout); } else if (!strcmp(args[0], "retries")) { /* connection retries */ if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) diff --git a/src/client.c b/src/client.c index 50a0f5d..7c77189 100644 --- a/src/client.c +++ b/src/client.c @@ -384,7 +384,7 @@ int event_accept(int fd) { s->rep->rto = s->be->srvtimeout; s->rep->wto = s->fe->clitimeout; - tv_zero(&s->rep->cto); + tv_eternity(&s->rep->cto); fd_insert(cfd); fdtab[cfd].owner = t; diff --git a/src/proto_http.c b/src/proto_http.c index 4e9e683..8655372 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -2247,6 +2247,32 @@ int process_srv(struct session *t) #ifdef DEBUG_FULL fprintf(stderr,"process_srv: c=%s, s=%s\n", cli_stnames[c], srv_stnames[s]); #endif + +#if 0 + fprintf(stderr,"%s:%d fe->clito=%d.%d, fe->conto=%d.%d, fe->srvto=%d.%d\n", + __FUNCTION__, __LINE__, + t->fe->clitimeout.tv_sec, t->fe->clitimeout.tv_usec, + t->fe->contimeout.tv_sec, t->fe->contimeout.tv_usec, + t->fe->srvtimeout.tv_sec, t->fe->srvtimeout.tv_usec); + fprintf(stderr,"%s:%d be->clito=%d.%d, be->conto=%d.%d, be->srvto=%d.%d\n", + __FUNCTION__, __LINE__, + t->be->clitimeout.tv_sec, t->be->clitimeout.tv_usec, + t->be->contimeout.tv_sec, t->be->contimeout.tv_usec, + t->be->srvtimeout.tv_sec, t->be->srvtimeout.tv_usec); + + fprintf(stderr,"%s:%d req->cto=%d.%d, req->rto=%d.%d, req->wto=%d.%d\n", + __FUNCTION__, __LINE__, + req->cto.tv_sec, req->cto.tv_usec, + req->rto.tv_sec, req->rto.tv_usec, + req->wto.tv_sec, req->wto.tv_usec); + + fprintf(stderr,"%s:%d rep->cto=%d.%d, rep->rto=%d.%d, rep->wto=%d.%d\n", + __FUNCTION__, __LINE__, + rep->cto.tv_sec, rep->cto.tv_usec, + rep->rto.tv_sec, rep->rto.tv_usec, + rep->wto.tv_sec, rep->wto.tv_usec); +#endif + //fprintf(stderr,"process_srv: c=%d, s=%d, cr=%d, cw=%d, sr=%d, sw=%d\n", c, s, //EV_FD_ISSET(t->cli_fd, DIR_RD), EV_FD_ISSET(t->cli_fd, DIR_WR), //EV_FD_ISSET(t->srv_fd, DIR_RD), EV_FD_ISSET(t->srv_fd, DIR_WR) -- 1.5.0.3