[MEDIUM] process_srv: don't rely at all on client state
A new buffer flag BF_MAY_CONNECT has been added so that the server
FSM can check whether it is allowed to establish a connection or
not. That way, the client FSM only has to move this flag and the
server side does not need to monitor client state anymore.
diff --git a/include/types/buffers.h b/include/types/buffers.h
index 7539901..8cc8d29 100644
--- a/include/types/buffers.h
+++ b/include/types/buffers.h
@@ -45,14 +45,15 @@
#define BF_PARTIAL_WRITE 256
#define BF_COMPLETE_WRITE 512
-#define BF_WRITE_ERROR 1024
-#define BF_WRITE_NULL 2048
-#define BF_WRITE_STATUS (BF_PARTIAL_WRITE|BF_COMPLETE_WRITE|BF_WRITE_ERROR|BF_WRITE_NULL)
-#define BF_CLEAR_WRITE (~BF_WRITE_STATUS)
+#define BF_WRITE_ERROR 1024
+#define BF_WRITE_NULL 2048
+#define BF_WRITE_STATUS (BF_PARTIAL_WRITE|BF_COMPLETE_WRITE|BF_WRITE_ERROR|BF_WRITE_NULL)
+#define BF_CLEAR_WRITE (~BF_WRITE_STATUS)
-#define BF_STREAMER 4096
-#define BF_STREAMER_FAST 8192
+#define BF_STREAMER 4096
+#define BF_STREAMER_FAST 8192
+#define BF_MAY_CONNECT 16384 /* consumer side is allowed to forward the connection */
/* describes a chunk of string */
struct chunk {
diff --git a/src/client.c b/src/client.c
index a4d5265..e04a066 100644
--- a/src/client.c
+++ b/src/client.c
@@ -341,6 +341,9 @@
if (p->mode == PR_MODE_HTTP) /* reserve some space for header rewriting */
s->req->rlim -= MAXREWRITE;
+ if (s->cli_state == CL_STDATA)
+ s->req->flags |= BF_MAY_CONNECT; /* don't wait to establish connection */
+
s->req->rto = s->fe->timeout.client;
s->req->wto = s->be->timeout.server;
s->req->cto = s->be->timeout.connect;
diff --git a/src/proto_http.c b/src/proto_http.c
index 42f2531..5d45f02 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1644,6 +1644,7 @@
t->txn.exp = tick_add_ifset(now_ms, t->fe->timeout.httpreq);
} else {
t->cli_state = CL_STDATA;
+ req->flags |= BF_MAY_CONNECT;
}
t->inspect_exp = TICK_ETERNITY;
return 1;
@@ -2365,6 +2366,8 @@
************************************************************/
t->cli_state = CL_STDATA;
+ req->flags |= BF_MAY_CONNECT;
+
req->rlim = req->data + BUFSIZE; /* no more rewrite needed */
t->logs.tv_request = now;
@@ -2685,7 +2688,6 @@
int process_srv(struct session *t)
{
int s = t->srv_state;
- int c = t->cli_state;
struct http_txn *txn = &t->txn;
struct buffer *req = t->req;
struct buffer *rep = t->rep;
@@ -2696,44 +2698,13 @@
EV_FD_ISSET(t->srv_fd, DIR_RD), EV_FD_ISSET(t->srv_fd, DIR_WR),
rep->rex, req->wex);
-#if 0
- fprintf(stderr,"%s:%d fe->clito=%d.%d, fe->conto=%d.%d, fe->srvto=%d.%d\n",
- __FUNCTION__, __LINE__,
- t->fe->timeout.client.tv_sec, t->fe->timeout.client.tv_usec,
- t->fe->timeout.connect.tv_sec, t->fe->timeout.connect.tv_usec,
- t->fe->timeout.server.tv_sec, t->fe->timeout.server.tv_usec);
- fprintf(stderr,"%s:%d be->clito=%d.%d, be->conto=%d.%d, be->srvto=%d.%d\n",
- __FUNCTION__, __LINE__,
- t->be->timeout.client.tv_sec, t->be->timeout.client.tv_usec,
- t->be->timeout.connect.tv_sec, t->be->timeout.connect.tv_usec,
- t->be->timeout.server.tv_sec, t->be->timeout.server.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)
- //);
if (s == SV_STIDLE) {
/* NOTE: The client processor may switch to SV_STANALYZE, which switches back SV_STIDLE.
* This is logcially after CL_STHEADERS completed, CL_STDATA has started, but
* we need to defer server selection until more data arrives, if possible.
* This is rare, and only if balancing on parameter hash with values in the entity of a POST
*/
- if (c == CL_STHEADERS || c == CL_STINSPECT)
- return 0; /* stay in idle, waiting for data to reach the client side */
- else if ((rep->flags & BF_SHUTW_STATUS) ||
+ if ((rep->flags & BF_SHUTW_STATUS) ||
((req->flags & BF_SHUTR_STATUS) &&
(req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
req->cex = TICK_ETERNITY;
@@ -2749,7 +2720,8 @@
return 1;
}
- else {
+ else if (req->flags & BF_MAY_CONNECT) {
+ /* the client allows the server to connect */
if (txn->flags & TX_CLTARPIT) {
/* This connection is being tarpitted. The CLIENT side has
* already set the connect expiration date to the right