From 8bfa426cadfd6812823b563956ce7de3474e4589 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 27 Nov 2008 09:25:45 +0100 Subject: [PATCH] [MEDIUM] process shutw during connection attempt It sometimes happens that a connection is aborted at the exact same moment it establishes. We have to close the socket and not only to shut it down for writes. Some corner cases remain. We have to handle the shutr/shutw at the stream interface and only report the status to the buffer, not the opposite. --- src/proto_http.c | 2 +- src/stream_sock.c | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index f73964a3c..b3b46ef70 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -1298,7 +1298,7 @@ void process_session(struct task *t, int *next) } if (likely((s->rep->cons->state != SI_ST_CLO) || - (s->req->cons->state != SI_ST_CLO && s->req->cons->state != SI_ST_INI))) { + (s->req->cons->state > SI_ST_INI && s->req->cons->state < SI_ST_CLO))) { if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED)) session_process_counters(s); diff --git a/src/stream_sock.c b/src/stream_sock.c index 584a1cd87..8d531ed15 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -486,9 +486,6 @@ int stream_sock_write(int fd) { void stream_sock_shutw(struct stream_interface *si) { switch (si->state) { - case SI_ST_INI: - si->state = SI_ST_CLO; - return; case SI_ST_EST: if (!(si->ib->flags & BF_SHUTR)) { EV_FD_CLR(si->fd, DIR_WR); @@ -497,7 +494,11 @@ void stream_sock_shutw(struct stream_interface *si) } /* fall through */ case SI_ST_CON: + /* we may have to close a pending connection, and mark the + * response buffer as shutr + */ fd_delete(si->fd); + buffer_shutr(si->ib); si->state = SI_ST_DIS; return; } @@ -513,11 +514,8 @@ void stream_sock_shutw(struct stream_interface *si) */ void stream_sock_shutr(struct stream_interface *si) { - if (si->state != SI_ST_EST && si->state != SI_ST_CON) { - if (likely(si->state == SI_ST_INI)) - si->state = SI_ST_CLO; + if (si->state != SI_ST_EST && si->state != SI_ST_CON) return; - } if (si->ob->flags & BF_SHUTW) { fd_delete(si->fd);