]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
* released 1.1.20 v1.1.20
authorwilly tarreau <willy@wtap.(none)>
Sat, 17 Dec 2005 12:51:03 +0000 (13:51 +0100)
committerwilly tarreau <willy@wtap.(none)>
Sat, 17 Dec 2005 12:51:03 +0000 (13:51 +0100)
* fixed two problems with time-outs, one where a server would be logged as
  timed out during transfer that take longer to complete than the fixed
  time-out, and one where clients were logged as timed-out during the data
  phase because they didn't have anything to send. This sometimes caused
  slow client connections to close too early while in fact there was no
  problem. The proper fix would be to have a per-fd time-out with
  conditions depending on the state of the HTTP FSM.

CHANGELOG
haproxy.c

index bbd4d6b277d3f608fd6aa09ea8f14f68fb91299a..47512a73c126468159a4f1688f8176a6408f4966 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,15 @@
 ChangeLog :
 ===========
 
+2003/04/21 : 1.1.20
+  - fixed two problems with time-outs, one where a server would be logged as
+    timed out during transfer that take longer to complete than the fixed
+    time-out, and one where clients were logged as timed-out during the data
+    phase because they didn't have anything to send. This sometimes caused
+    slow client connections to close too early while in fact there was no
+    problem. The proper fix would be to have a per-fd time-out with
+    conditions depending on the state of the HTTP FSM.
+
 2003/04/16 : 1.1.19
   - haproxy was NOT RFC compliant because it was case-sensitive on HTTP
     "Cookie:" and "Set-Cookie:" headers. This caused JVM 1.4 to fail on
index 7050fefbeddd9d6b3097c95a9f940e9df6e92b5d..5c3572641028b87f08d257ab28f20c90e664b5cc 100644 (file)
--- a/haproxy.c
+++ b/haproxy.c
@@ -53,8 +53,8 @@
 #include <linux/netfilter_ipv4.h>
 #endif
 
-#define HAPROXY_VERSION "1.1.19"
-#define HAPROXY_DATE   "2003/04/16"
+#define HAPROXY_VERSION "1.1.20"
+#define HAPROXY_DATE   "2003/04/21"
 
 /* this is for libc5 for example */
 #ifndef TCP_NODELAY
@@ -1524,7 +1524,7 @@ int event_cli_read(int fd) {
     }
 
     if (s->res_cr != RES_SILENT) {
-       if (s->proxy->clitimeout)
+       if (s->proxy->clitimeout && FD_ISSET(fd, StaticReadEvent))
            tv_delayfrom(&s->crexpire, &now, s->proxy->clitimeout);
        else
            tv_eternity(&s->crexpire);
@@ -1619,7 +1619,7 @@ int event_srv_read(int fd) {
     }
 
     if (s->res_sr != RES_SILENT) {
-       if (s->proxy->srvtimeout)
+       if (s->proxy->srvtimeout && FD_ISSET(fd, StaticReadEvent))
            tv_delayfrom(&s->srexpire, &now, s->proxy->srvtimeout);
        else
            tv_eternity(&s->srexpire);
@@ -1661,6 +1661,8 @@ int event_cli_write(int fd) {
        if (max == 0) {
            s->res_cw = RES_NULL;
            task_wakeup(&rq, t);
+           tv_eternity(&s->cwexpire);
+           FD_CLR(fd, StaticWriteEvent);
            return 0;
        }
 
@@ -1702,8 +1704,11 @@ int event_cli_write(int fd) {
        fdtab[fd].state = FD_STERROR;
     }
 
-    if (s->proxy->clitimeout)
+    if (s->proxy->clitimeout) {
        tv_delayfrom(&s->cwexpire, &now, s->proxy->clitimeout);
+       /* FIXME: to avoid the client to read-time-out during writes, we refresh it */
+       s->crexpire = s->cwexpire;
+    }
     else
        tv_eternity(&s->cwexpire);
 
@@ -1744,6 +1749,8 @@ int event_srv_write(int fd) {
            s->res_sw = RES_NULL;
            task_wakeup(&rq, t);
            fdtab[fd].state = FD_STREADY;
+           tv_eternity(&s->swexpire);
+           FD_CLR(fd, StaticWriteEvent);
            return 0;
        }
 
@@ -1786,8 +1793,11 @@ int event_srv_write(int fd) {
        fdtab[fd].state = FD_STERROR;
     }
 
-    if (s->proxy->srvtimeout)
+    if (s->proxy->srvtimeout) {
        tv_delayfrom(&s->swexpire, &now, s->proxy->srvtimeout);
+       /* FIXME: to avoid the server to read-time-out during writes, we refresh it */
+       s->srexpire = s->swexpire;
+    }
     else
        tv_eternity(&s->swexpire);
 
@@ -2025,7 +2035,7 @@ int event_accept(int fd) {
        s->req->total = 0;
        s->req->h = s->req->r = s->req->lr = s->req->w = s->req->data;  /* r and w will be reset further */
        s->req->rlim = s->req->data + BUFSIZE;
-       if (s->cli_state == CL_STHEADERS) /* reserver some space for header rewriting */
+       if (s->cli_state == CL_STHEADERS) /* reserve some space for header rewriting */
            s->req->rlim -= MAXREWRITE;
 
        if ((s->rep = pool_alloc(buffer)) == NULL) { /* no memory */
@@ -2706,7 +2716,7 @@ int process_cli(struct session *t) {
            shutdown(t->cli_fd, SHUT_WR);
            t->cli_state = CL_STSHUTW;
            if (!(t->flags & SN_ERR_MASK))
-               t->flags |= SN_ERR_CLICL;
+               t->flags |= SN_ERR_CLITO;
            if (!(t->flags & SN_FINST_MASK))
                t->flags |= SN_FINST_D;
            return 1;
@@ -2741,8 +2751,11 @@ int process_cli(struct session *t) {
        else { /* buffer not empty */
            if (! FD_ISSET(t->cli_fd, StaticWriteEvent)) {
                FD_SET(t->cli_fd, StaticWriteEvent); /* restart writing */
-               if (t->proxy->clitimeout)
+               if (t->proxy->clitimeout) {
                    tv_delayfrom(&t->cwexpire, &now, t->proxy->clitimeout);
+                   /* FIXME: to avoid the client to read-time-out during writes, we refresh it */
+                   t->crexpire = t->cwexpire;
+               }
                else
                    tv_eternity(&t->cwexpire);
            }
@@ -2786,8 +2799,11 @@ int process_cli(struct session *t) {
        else { /* buffer not empty */
            if (! FD_ISSET(t->cli_fd, StaticWriteEvent)) {
                FD_SET(t->cli_fd, StaticWriteEvent); /* restart writing */
-               if (t->proxy->clitimeout)
+               if (t->proxy->clitimeout) {
                    tv_delayfrom(&t->cwexpire, &now, t->proxy->clitimeout);
+                   /* FIXME: to avoid the client to read-time-out during writes, we refresh it */
+                   t->crexpire = t->cwexpire;
+               }
                else
                    tv_eternity(&t->cwexpire);
            }
@@ -2961,10 +2977,19 @@ int process_srv(struct session *t) {
            t->logs.t_connect = tv_diff(&t->logs.tv_accept, &now);
 
            //fprintf(stderr,"3: c=%d, s=%d\n", c, s);
-           if (req->l == 0) /* nothing to write */
+           if (req->l == 0) /* nothing to write */ {
                FD_CLR(t->srv_fd, StaticWriteEvent);
-           else  /* need the right to write */
+               tv_eternity(&t->swexpire);
+           } else  /* need the right to write */ {
                FD_SET(t->srv_fd, StaticWriteEvent);
+               if (t->proxy->srvtimeout) {
+                   tv_delayfrom(&t->swexpire, &now, t->proxy->srvtimeout);
+                   /* FIXME: to avoid the server to read-time-out during writes, we refresh it */
+                   t->srexpire = t->swexpire;
+               }
+               else
+                   tv_eternity(&t->swexpire);
+           }
 
            if (t->proxy->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
                FD_SET(t->srv_fd, StaticReadEvent);
@@ -3314,8 +3339,11 @@ int process_srv(struct session *t) {
        else { /* client buffer not empty */
            if (! FD_ISSET(t->srv_fd, StaticWriteEvent)) {
                FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-               if (t->proxy->srvtimeout)
+               if (t->proxy->srvtimeout) {
                    tv_delayfrom(&t->swexpire, &now, t->proxy->srvtimeout);
+                   /* FIXME: to avoid the server to read-time-out during writes, we refresh it */
+                   t->srexpire = t->swexpire;
+               }
                else
                    tv_eternity(&t->swexpire);
            }
@@ -3374,22 +3402,28 @@ int process_srv(struct session *t) {
                t->flags |= SN_FINST_D;
            return 1;
        }
-       else if (req->l == 0) {
+
+       /* recompute request time-outs */
+       if (req->l == 0) {
            if (FD_ISSET(t->srv_fd, StaticWriteEvent)) {
                FD_CLR(t->srv_fd, StaticWriteEvent); /* stop writing */
                tv_eternity(&t->swexpire);
            }
        }
-       else { /* buffer not empty */
+       else { /* buffer not empty, there are still data to be transferred */
            if (! FD_ISSET(t->srv_fd, StaticWriteEvent)) {
                FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-               if (t->proxy->srvtimeout)
+               if (t->proxy->srvtimeout) {
                    tv_delayfrom(&t->swexpire, &now, t->proxy->srvtimeout);
+                   /* FIXME: to avoid the server to read-time-out during writes, we refresh it */
+                   t->srexpire = t->swexpire;
+               }
                else
                    tv_eternity(&t->swexpire);
            }
        }
 
+       /* recompute response time-outs */
        if (rep->l == BUFSIZE) { /* no room to read more data */
            if (FD_ISSET(t->srv_fd, StaticReadEvent)) {
                FD_CLR(t->srv_fd, StaticReadEvent);
@@ -3450,8 +3484,11 @@ int process_srv(struct session *t) {
        else { /* buffer not empty */
            if (! FD_ISSET(t->srv_fd, StaticWriteEvent)) {
                FD_SET(t->srv_fd, StaticWriteEvent); /* restart writing */
-               if (t->proxy->srvtimeout)
+               if (t->proxy->srvtimeout) {
                    tv_delayfrom(&t->swexpire, &now, t->proxy->srvtimeout);
+                   /* FIXME: to avoid the server to read-time-out during writes, we refresh it */
+                   t->srexpire = t->swexpire;
+               }
                else
                    tv_eternity(&t->swexpire);
            }