blob: 08bb4c315edc2eba3e92ec42711064a900f8bb64 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Server management functions.
3 *
Willy Tarreau7c669d72008-06-20 15:04:11 +02004 * Copyright 2000-2008 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <stdlib.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020014
15#include <common/config.h>
Willy Tarreau7c669d72008-06-20 15:04:11 +020016#include <common/debug.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020017#include <common/memory.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020018
Willy Tarreaubaaee002006-06-26 02:48:02 +020019#include <types/capture.h>
Willy Tarreau55a8d0e2008-11-30 18:47:21 +010020#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020021
Willy Tarreau1d0dfb12009-07-07 15:10:31 +020022#include <proto/acl.h>
Willy Tarreau55a8d0e2008-11-30 18:47:21 +010023#include <proto/backend.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020024#include <proto/buffers.h>
Krzysztof Piotr Oledzki97f07b82009-12-15 22:31:24 +010025#include <proto/checks.h>
Willy Tarreau5ca791d2009-08-16 19:06:42 +020026#include <proto/dumpstats.h>
Willy Tarreau8d5d7f22007-01-21 19:16:41 +010027#include <proto/hdr_idx.h>
Willy Tarreau332f8bf2007-05-13 21:36:56 +020028#include <proto/log.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020029#include <proto/session.h>
Emeric Brun1d33b292010-01-04 15:47:17 +010030#include <proto/pattern.h>
Willy Tarreau3eba98a2009-01-25 13:56:13 +010031#include <proto/pipe.h>
Willy Tarreau55a8d0e2008-11-30 18:47:21 +010032#include <proto/proto_http.h>
33#include <proto/proto_tcp.h>
Willy Tarreau1d0dfb12009-07-07 15:10:31 +020034#include <proto/proxy.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020035#include <proto/queue.h>
Willy Tarreau7f062c42009-03-05 18:43:00 +010036#include <proto/server.h>
Emeric Brun1d33b292010-01-04 15:47:17 +010037#include <proto/stick_table.h>
Willy Tarreau55a8d0e2008-11-30 18:47:21 +010038#include <proto/stream_interface.h>
39#include <proto/stream_sock.h>
40#include <proto/task.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020041
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020042struct pool_head *pool2_session;
Willy Tarreauf54f8bd2008-11-23 19:53:55 +010043struct list sessions;
Willy Tarreaubaaee002006-06-26 02:48:02 +020044
45/*
46 * frees the context associated to a session. It must have been removed first.
47 */
48void session_free(struct session *s)
49{
Willy Tarreau4dbc4a22007-03-03 16:23:22 +010050 struct http_txn *txn = &s->txn;
Willy Tarreau632f5a72007-07-11 10:42:35 +020051 struct proxy *fe = s->fe;
Willy Tarreau62e4f1d2008-12-07 20:16:23 +010052 struct bref *bref, *back;
Willy Tarreaua4cda672010-06-06 18:28:49 +020053 int i;
Willy Tarreau0f7562b2007-01-07 15:46:13 +010054
Willy Tarreaubaaee002006-06-26 02:48:02 +020055 if (s->pend_pos)
56 pendconn_free(s->pend_pos);
Willy Tarreau922a8062008-12-04 09:33:58 +010057
Willy Tarreau1e62de62008-11-11 20:20:02 +010058 if (s->srv) { /* there may be requests left pending in queue */
59 if (s->flags & SN_CURR_SESS) {
60 s->flags &= ~SN_CURR_SESS;
61 s->srv->cur_sess--;
62 }
Willy Tarreau922a8062008-12-04 09:33:58 +010063 if (may_dequeue_tasks(s->srv, s->be))
64 process_srv_queue(s->srv);
Willy Tarreau1e62de62008-11-11 20:20:02 +010065 }
Willy Tarreau922a8062008-12-04 09:33:58 +010066
Willy Tarreau7c669d72008-06-20 15:04:11 +020067 if (unlikely(s->srv_conn)) {
68 /* the session still has a reserved slot on a server, but
69 * it should normally be only the same as the one above,
70 * so this should not happen in fact.
71 */
72 sess_change_server(s, NULL);
73 }
74
Willy Tarreau3eba98a2009-01-25 13:56:13 +010075 if (s->req->pipe)
76 put_pipe(s->req->pipe);
Willy Tarreau259de1b2009-01-18 21:56:21 +010077
Willy Tarreau3eba98a2009-01-25 13:56:13 +010078 if (s->rep->pipe)
79 put_pipe(s->rep->pipe);
Willy Tarreau259de1b2009-01-18 21:56:21 +010080
Willy Tarreau48d63db2008-08-03 17:41:33 +020081 pool_free2(pool2_buffer, s->req);
82 pool_free2(pool2_buffer, s->rep);
Willy Tarreaubaaee002006-06-26 02:48:02 +020083
Willy Tarreau46023632010-01-07 22:51:47 +010084 http_end_txn(s);
85
Willy Tarreaua4cda672010-06-06 18:28:49 +020086 for (i = 0; i < s->store_count; i++) {
87 if (!s->store[i].ts)
88 continue;
89 stksess_free(s->store[i].table, s->store[i].ts);
90 s->store[i].ts = NULL;
91 }
92
Willy Tarreau92fb9832007-10-16 17:34:28 +020093 if (fe) {
Willy Tarreau48d63db2008-08-03 17:41:33 +020094 pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);
Willy Tarreau46023632010-01-07 22:51:47 +010095 pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
96 pool_free2(fe->req_cap_pool, txn->req.cap);
Willy Tarreaubaaee002006-06-26 02:48:02 +020097 }
Willy Tarreau0937bc42009-12-22 15:03:09 +010098
Willy Tarreau62e4f1d2008-12-07 20:16:23 +010099 list_for_each_entry_safe(bref, back, &s->back_refs, users) {
Willy Tarreaufd3828e2009-02-22 15:17:24 +0100100 /* we have to unlink all watchers. We must not relink them if
101 * this session was the last one in the list.
102 */
Willy Tarreau62e4f1d2008-12-07 20:16:23 +0100103 LIST_DEL(&bref->users);
Willy Tarreaufd3828e2009-02-22 15:17:24 +0100104 LIST_INIT(&bref->users);
105 if (s->list.n != &sessions)
106 LIST_ADDQ(&LIST_ELEM(s->list.n, struct session *, list)->back_refs, &bref->users);
Willy Tarreau62e4f1d2008-12-07 20:16:23 +0100107 bref->ref = s->list.n;
108 }
Willy Tarreauf54f8bd2008-11-23 19:53:55 +0100109 LIST_DEL(&s->list);
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200110 pool_free2(pool2_session, s);
Willy Tarreau632f5a72007-07-11 10:42:35 +0200111
112 /* We may want to free the maximum amount of pools if the proxy is stopping */
Willy Tarreau92fb9832007-10-16 17:34:28 +0200113 if (fe && unlikely(fe->state == PR_STSTOPPED)) {
Willy Tarreau48d63db2008-08-03 17:41:33 +0200114 pool_flush2(pool2_buffer);
115 pool_flush2(fe->hdr_idx_pool);
116 pool_flush2(pool2_requri);
117 pool_flush2(pool2_capture);
118 pool_flush2(pool2_session);
119 pool_flush2(fe->req_cap_pool);
120 pool_flush2(fe->rsp_cap_pool);
Willy Tarreau632f5a72007-07-11 10:42:35 +0200121 }
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200122}
123
124
125/* perform minimal intializations, report 0 in case of error, 1 if OK. */
126int init_session()
127{
Willy Tarreauf54f8bd2008-11-23 19:53:55 +0100128 LIST_INIT(&sessions);
Willy Tarreauc6ca1a02007-05-13 19:43:47 +0200129 pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED);
130 return pool2_session != NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200131}
132
Willy Tarreau30e71012007-11-26 20:15:35 +0100133void session_process_counters(struct session *s)
134{
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100135 unsigned long long bytes;
136
Willy Tarreau30e71012007-11-26 20:15:35 +0100137 if (s->req) {
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100138 bytes = s->req->total - s->logs.bytes_in;
Willy Tarreau30e71012007-11-26 20:15:35 +0100139 s->logs.bytes_in = s->req->total;
140 if (bytes) {
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200141 s->fe->counters.bytes_in += bytes;
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100142
Willy Tarreau30e71012007-11-26 20:15:35 +0100143 if (s->be != s->fe)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200144 s->be->counters.bytes_in += bytes;
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100145
Willy Tarreau30e71012007-11-26 20:15:35 +0100146 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200147 s->srv->counters.bytes_in += bytes;
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200148
149 if (s->listener->counters)
150 s->listener->counters->bytes_in += bytes;
Willy Tarreau30e71012007-11-26 20:15:35 +0100151 }
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100152 }
153
Willy Tarreau30e71012007-11-26 20:15:35 +0100154 if (s->rep) {
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100155 bytes = s->rep->total - s->logs.bytes_out;
Willy Tarreau30e71012007-11-26 20:15:35 +0100156 s->logs.bytes_out = s->rep->total;
157 if (bytes) {
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200158 s->fe->counters.bytes_out += bytes;
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100159
Willy Tarreau30e71012007-11-26 20:15:35 +0100160 if (s->be != s->fe)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200161 s->be->counters.bytes_out += bytes;
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100162
Willy Tarreau30e71012007-11-26 20:15:35 +0100163 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200164 s->srv->counters.bytes_out += bytes;
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +0200165
166 if (s->listener->counters)
167 s->listener->counters->bytes_out += bytes;
Willy Tarreau30e71012007-11-26 20:15:35 +0100168 }
Krzysztof Piotr Oledzki583bc962007-11-24 22:12:47 +0100169 }
170}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200171
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100172/* This function is called with (si->state == SI_ST_CON) meaning that a
173 * connection was attempted and that the file descriptor is already allocated.
174 * We must check for establishment, error and abort. Possible output states
175 * are SI_ST_EST (established), SI_ST_CER (error), SI_ST_DIS (abort), and
176 * SI_ST_CON (no change). The function returns 0 if it switches to SI_ST_CER,
177 * otherwise 1.
178 */
179int sess_update_st_con_tcp(struct session *s, struct stream_interface *si)
180{
181 struct buffer *req = si->ob;
182 struct buffer *rep = si->ib;
183
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100184 /* If we got an error, or if nothing happened and the connection timed
185 * out, we must give up. The CER state handler will take care of retry
186 * attempts and error reports.
187 */
188 if (unlikely(si->flags & (SI_FL_EXP|SI_FL_ERR))) {
Willy Tarreau127334e2009-03-28 10:47:26 +0100189 si->exp = TICK_ETERNITY;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100190 si->state = SI_ST_CER;
Willy Tarreaudc340a92009-06-28 23:10:19 +0200191 si->flags &= ~SI_FL_CAP_SPLICE;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100192 fd_delete(si->fd);
193
194 if (si->err_type)
195 return 0;
196
197 si->err_loc = s->srv;
198 if (si->flags & SI_FL_ERR)
199 si->err_type = SI_ET_CONN_ERR;
200 else
201 si->err_type = SI_ET_CONN_TO;
202 return 0;
203 }
204
205 /* OK, maybe we want to abort */
Willy Tarreau418fd472009-09-06 21:37:23 +0200206 if (unlikely((rep->flags & BF_SHUTW) ||
207 ((req->flags & BF_SHUTW_NOW) && /* FIXME: this should not prevent a connection from establishing */
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200208 (((req->flags & (BF_OUT_EMPTY|BF_WRITE_ACTIVITY)) == BF_OUT_EMPTY) ||
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100209 s->be->options & PR_O_ABRT_CLOSE)))) {
210 /* give up */
211 si->shutw(si);
212 si->err_type |= SI_ET_CONN_ABRT;
213 si->err_loc = s->srv;
Willy Tarreaudc340a92009-06-28 23:10:19 +0200214 si->flags &= ~SI_FL_CAP_SPLICE;
Willy Tarreau84455332009-03-15 22:34:05 +0100215 if (s->srv_error)
216 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100217 return 1;
218 }
219
220 /* we need to wait a bit more if there was no activity either */
221 if (!(req->flags & BF_WRITE_ACTIVITY))
222 return 1;
223
224 /* OK, this means that a connection succeeded. The caller will be
225 * responsible for handling the transition from CON to EST.
226 */
227 s->logs.t_connect = tv_ms_elapsed(&s->logs.tv_accept, &now);
Willy Tarreau127334e2009-03-28 10:47:26 +0100228 si->exp = TICK_ETERNITY;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100229 si->state = SI_ST_EST;
230 si->err_type = SI_ET_NONE;
231 si->err_loc = NULL;
232 return 1;
233}
234
235/* This function is called with (si->state == SI_ST_CER) meaning that a
236 * previous connection attempt has failed and that the file descriptor
237 * has already been released. Possible causes include asynchronous error
238 * notification and time out. Possible output states are SI_ST_CLO when
239 * retries are exhausted, SI_ST_TAR when a delay is wanted before a new
240 * connection attempt, SI_ST_ASS when it's wise to retry on the same server,
241 * and SI_ST_REQ when an immediate redispatch is wanted. The buffers are
242 * marked as in error state. It returns 0.
243 */
244int sess_update_st_cer(struct session *s, struct stream_interface *si)
245{
246 /* we probably have to release last session from the server */
247 if (s->srv) {
Krzysztof Piotr Oledzki97f07b82009-12-15 22:31:24 +0100248 health_adjust(s->srv, HANA_STATUS_L4_ERR);
249
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100250 if (s->flags & SN_CURR_SESS) {
251 s->flags &= ~SN_CURR_SESS;
252 s->srv->cur_sess--;
253 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100254 }
255
256 /* ensure that we have enough retries left */
257 s->conn_retries--;
258 if (s->conn_retries < 0) {
259 if (!si->err_type) {
260 si->err_type = SI_ET_CONN_ERR;
261 si->err_loc = s->srv;
262 }
263
264 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200265 s->srv->counters.failed_conns++;
266 s->be->counters.failed_conns++;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100267 if (may_dequeue_tasks(s->srv, s->be))
268 process_srv_queue(s->srv);
269
270 /* shutw is enough so stop a connecting socket */
271 si->shutw(si);
272 si->ob->flags |= BF_WRITE_ERROR;
273 si->ib->flags |= BF_READ_ERROR;
274
275 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100276 if (s->srv_error)
277 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100278 return 0;
279 }
280
281 /* If the "redispatch" option is set on the backend, we are allowed to
282 * retry on another server for the last retry. In order to achieve this,
283 * we must mark the session unassigned, and eventually clear the DIRECT
284 * bit to ignore any persistence cookie. We won't count a retry nor a
285 * redispatch yet, because this will depend on what server is selected.
286 */
Willy Tarreau4de91492010-01-22 19:10:05 +0100287 if (s->srv && s->conn_retries == 0 &&
288 s->be->options & PR_O_REDISP && !(s->flags & SN_FORCE_PRST)) {
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100289 if (may_dequeue_tasks(s->srv, s->be))
290 process_srv_queue(s->srv);
291
292 s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
293 s->prev_srv = s->srv;
294 si->state = SI_ST_REQ;
295 } else {
296 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200297 s->srv->counters.retries++;
298 s->be->counters.retries++;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100299 si->state = SI_ST_ASS;
300 }
301
302 if (si->flags & SI_FL_ERR) {
303 /* The error was an asynchronous connection error, and we will
304 * likely have to retry connecting to the same server, most
305 * likely leading to the same result. To avoid this, we wait
306 * one second before retrying.
307 */
308
309 if (!si->err_type)
310 si->err_type = SI_ET_CONN_ERR;
311
312 si->state = SI_ST_TAR;
313 si->exp = tick_add(now_ms, MS_TO_TICKS(1000));
314 return 0;
315 }
316 return 0;
317}
318
319/*
320 * This function handles the transition between the SI_ST_CON state and the
Willy Tarreau85e7d002010-05-31 11:57:51 +0200321 * SI_ST_EST state. It must only be called after switching from SI_ST_CON (or
322 * SI_ST_INI) to SI_ST_EST, but only when a ->connect function is defined.
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100323 */
324void sess_establish(struct session *s, struct stream_interface *si)
325{
326 struct buffer *req = si->ob;
327 struct buffer *rep = si->ib;
328
Krzysztof Piotr Oledzki97f07b82009-12-15 22:31:24 +0100329 if (s->srv)
330 health_adjust(s->srv, HANA_STATUS_L4_OK);
331
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100332 if (s->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100333 /* if the user wants to log as soon as possible, without counting
334 * bytes from the server, then this is the right moment. */
335 if (s->fe->to_log && !(s->logs.logwait & LW_BYTES)) {
336 s->logs.t_close = s->logs.t_connect; /* to get a valid end date */
Willy Tarreaua5555ec2008-11-30 19:02:32 +0100337 s->do_log(s);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100338 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100339 }
340 else {
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100341 s->txn.rsp.msg_state = HTTP_MSG_RPBEFORE;
342 /* reset hdr_idx which was already initialized by the request.
343 * right now, the http parser does it.
344 * hdr_idx_init(&s->txn.hdr_idx);
345 */
346 }
347
Willy Tarreau4e5b8282009-08-16 22:57:50 +0200348 rep->analysers |= s->fe->fe_rsp_ana | s->be->be_rsp_ana;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100349 rep->flags |= BF_READ_ATTACHED; /* producer is now attached */
Willy Tarreaud04e8582010-05-31 12:31:35 +0200350 if (si->connect) {
351 /* real connections have timeouts */
352 req->wto = s->be->timeout.server;
353 rep->rto = s->be->timeout.server;
354 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100355 req->wex = TICK_ETERNITY;
356}
357
358/* Update stream interface status for input states SI_ST_ASS, SI_ST_QUE, SI_ST_TAR.
359 * Other input states are simply ignored.
360 * Possible output states are SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ, SI_ST_CON.
361 * Flags must have previously been updated for timeouts and other conditions.
362 */
363void sess_update_stream_int(struct session *s, struct stream_interface *si)
364{
365 DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d\n",
366 now_ms, __FUNCTION__,
367 s,
368 s->req, s->rep,
369 s->req->rex, s->rep->wex,
370 s->req->flags, s->rep->flags,
371 s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state);
372
373 if (si->state == SI_ST_ASS) {
374 /* Server assigned to connection request, we have to try to connect now */
375 int conn_err;
376
377 conn_err = connect_server(s);
378 if (conn_err == SN_ERR_NONE) {
379 /* state = SI_ST_CON now */
Willy Tarreau8f6457c2008-12-01 00:08:28 +0100380 if (s->srv)
Willy Tarreau7f062c42009-03-05 18:43:00 +0100381 srv_inc_sess_ctr(s->srv);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100382 return;
383 }
384
385 /* We have received a synchronous error. We might have to
386 * abort, retry immediately or redispatch.
387 */
388 if (conn_err == SN_ERR_INTERNAL) {
389 if (!si->err_type) {
390 si->err_type = SI_ET_CONN_OTHER;
391 si->err_loc = s->srv;
392 }
393
394 if (s->srv)
Willy Tarreau7f062c42009-03-05 18:43:00 +0100395 srv_inc_sess_ctr(s->srv);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100396 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200397 s->srv->counters.failed_conns++;
398 s->be->counters.failed_conns++;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100399
400 /* release other sessions waiting for this server */
401 if (may_dequeue_tasks(s->srv, s->be))
402 process_srv_queue(s->srv);
403
404 /* Failed and not retryable. */
405 si->shutr(si);
406 si->shutw(si);
407 si->ob->flags |= BF_WRITE_ERROR;
408
409 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
410
411 /* no session was ever accounted for this server */
412 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100413 if (s->srv_error)
414 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100415 return;
416 }
417
418 /* We are facing a retryable error, but we don't want to run a
419 * turn-around now, as the problem is likely a source port
420 * allocation problem, so we want to retry now.
421 */
422 si->state = SI_ST_CER;
423 si->flags &= ~SI_FL_ERR;
424 sess_update_st_cer(s, si);
425 /* now si->state is one of SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ */
426 return;
427 }
428 else if (si->state == SI_ST_QUE) {
429 /* connection request was queued, check for any update */
430 if (!s->pend_pos) {
431 /* The connection is not in the queue anymore. Either
432 * we have a server connection slot available and we
433 * go directly to the assigned state, or we need to
434 * load-balance first and go to the INI state.
435 */
436 si->exp = TICK_ETERNITY;
437 if (unlikely(!(s->flags & SN_ASSIGNED)))
438 si->state = SI_ST_REQ;
439 else {
440 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
441 si->state = SI_ST_ASS;
442 }
443 return;
444 }
445
446 /* Connection request still in queue... */
447 if (si->flags & SI_FL_EXP) {
448 /* ... and timeout expired */
449 si->exp = TICK_ETERNITY;
450 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
451 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200452 s->srv->counters.failed_conns++;
453 s->be->counters.failed_conns++;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100454 si->shutr(si);
455 si->shutw(si);
456 si->ob->flags |= BF_WRITE_TIMEOUT;
457 if (!si->err_type)
458 si->err_type = SI_ET_QUEUE_TO;
459 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100460 if (s->srv_error)
461 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100462 return;
463 }
464
465 /* Connection remains in queue, check if we have to abort it */
Willy Tarreau418fd472009-09-06 21:37:23 +0200466 if ((si->ob->flags & (BF_READ_ERROR)) ||
467 ((si->ob->flags & BF_SHUTW_NOW) && /* empty and client aborted */
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200468 (si->ob->flags & BF_OUT_EMPTY || s->be->options & PR_O_ABRT_CLOSE))) {
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100469 /* give up */
470 si->exp = TICK_ETERNITY;
471 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
472 si->shutr(si);
473 si->shutw(si);
474 si->err_type |= SI_ET_QUEUE_ABRT;
475 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100476 if (s->srv_error)
477 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100478 return;
479 }
480
481 /* Nothing changed */
482 return;
483 }
484 else if (si->state == SI_ST_TAR) {
485 /* Connection request might be aborted */
Willy Tarreau418fd472009-09-06 21:37:23 +0200486 if ((si->ob->flags & (BF_READ_ERROR)) ||
487 ((si->ob->flags & BF_SHUTW_NOW) && /* empty and client aborted */
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200488 (si->ob->flags & BF_OUT_EMPTY || s->be->options & PR_O_ABRT_CLOSE))) {
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100489 /* give up */
490 si->exp = TICK_ETERNITY;
491 si->shutr(si);
492 si->shutw(si);
493 si->err_type |= SI_ET_CONN_ABRT;
494 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100495 if (s->srv_error)
496 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100497 return;
498 }
499
500 if (!(si->flags & SI_FL_EXP))
501 return; /* still in turn-around */
502
503 si->exp = TICK_ETERNITY;
504
505 /* we keep trying on the same server as long as the session is
506 * marked "assigned".
507 * FIXME: Should we force a redispatch attempt when the server is down ?
508 */
509 if (s->flags & SN_ASSIGNED)
510 si->state = SI_ST_ASS;
511 else
512 si->state = SI_ST_REQ;
513 return;
514 }
515}
516
517/* This function initiates a server connection request on a stream interface
518 * already in SI_ST_REQ state. Upon success, the state goes to SI_ST_ASS,
519 * indicating that a server has been assigned. It may also return SI_ST_QUE,
520 * or SI_ST_CLO upon error.
521 */
522static void sess_prepare_conn_req(struct session *s, struct stream_interface *si) {
523 DPRINTF(stderr,"[%u] %s: sess=%p rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d\n",
524 now_ms, __FUNCTION__,
525 s,
526 s->req, s->rep,
527 s->req->rex, s->rep->wex,
528 s->req->flags, s->rep->flags,
529 s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state);
530
531 if (si->state != SI_ST_REQ)
532 return;
533
534 /* Try to assign a server */
535 if (srv_redispatch_connect(s) != 0) {
536 /* We did not get a server. Either we queued the
537 * connection request, or we encountered an error.
538 */
539 if (si->state == SI_ST_QUE)
540 return;
541
542 /* we did not get any server, let's check the cause */
543 si->shutr(si);
544 si->shutw(si);
545 si->ob->flags |= BF_WRITE_ERROR;
546 if (!si->err_type)
547 si->err_type = SI_ET_CONN_OTHER;
548 si->state = SI_ST_CLO;
Willy Tarreau0cac36f2008-11-30 20:44:17 +0100549 if (s->srv_error)
550 s->srv_error(s, si);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100551 return;
552 }
553
554 /* The server is assigned */
555 s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
556 si->state = SI_ST_ASS;
557}
558
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200559/* This stream analyser checks the switching rules and changes the backend
Willy Tarreau4de91492010-01-22 19:10:05 +0100560 * if appropriate. The default_backend rule is also considered, then the
561 * target backend's forced persistence rules are also evaluated last if any.
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200562 * It returns 1 if the processing can continue on next analysers, or zero if it
563 * either needs more data or wants to immediately abort the request.
564 */
565int process_switching_rules(struct session *s, struct buffer *req, int an_bit)
566{
Cyril Bonté47fdd8e2010-04-25 00:00:51 +0200567 struct persist_rule *prst_rule;
Willy Tarreau4de91492010-01-22 19:10:05 +0100568
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200569 req->analysers &= ~an_bit;
570 req->analyse_exp = TICK_ETERNITY;
571
572 DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
573 now_ms, __FUNCTION__,
574 s,
575 req,
576 req->rex, req->wex,
577 req->flags,
578 req->l,
579 req->analysers);
580
581 /* now check whether we have some switching rules for this request */
582 if (!(s->flags & SN_BE_ASSIGNED)) {
583 struct switching_rule *rule;
584
585 list_for_each_entry(rule, &s->fe->switching_rules, list) {
586 int ret;
587
588 ret = acl_exec_cond(rule->cond, s->fe, s, &s->txn, ACL_DIR_REQ);
589 ret = acl_pass(ret);
590 if (rule->cond->pol == ACL_COND_UNLESS)
591 ret = !ret;
592
593 if (ret) {
Willy Tarreaubedb9ba2009-07-12 08:27:39 +0200594 if (!session_set_backend(s, rule->be.backend))
595 goto sw_failed;
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200596 break;
597 }
598 }
599
600 /* To ensure correct connection accounting on the backend, we
601 * have to assign one if it was not set (eg: a listen). This
602 * measure also takes care of correctly setting the default
603 * backend if any.
604 */
605 if (!(s->flags & SN_BE_ASSIGNED))
Willy Tarreaubedb9ba2009-07-12 08:27:39 +0200606 if (!session_set_backend(s, s->fe->defbe.be ? s->fe->defbe.be : s->be))
607 goto sw_failed;
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200608 }
609
610 /* we don't want to run the HTTP filters again if the backend has not changed */
611 if (s->fe == s->be)
612 s->req->analysers &= ~AN_REQ_HTTP_PROCESS_BE;
613
Cyril Bonté47fdd8e2010-04-25 00:00:51 +0200614 /* as soon as we know the backend, we must check if we have a matching forced or ignored
Willy Tarreau4de91492010-01-22 19:10:05 +0100615 * persistence rule, and report that in the session.
616 */
Cyril Bonté47fdd8e2010-04-25 00:00:51 +0200617 list_for_each_entry(prst_rule, &s->be->persist_rules, list) {
Willy Tarreau4de91492010-01-22 19:10:05 +0100618 int ret = 1;
619
620 if (prst_rule->cond) {
621 ret = acl_exec_cond(prst_rule->cond, s->be, s, &s->txn, ACL_DIR_REQ);
622 ret = acl_pass(ret);
623 if (prst_rule->cond->pol == ACL_COND_UNLESS)
624 ret = !ret;
625 }
626
627 if (ret) {
628 /* no rule, or the rule matches */
Cyril Bonté47fdd8e2010-04-25 00:00:51 +0200629 if (prst_rule->type == PERSIST_TYPE_FORCE) {
630 s->flags |= SN_FORCE_PRST;
631 } else {
632 s->flags |= SN_IGNORE_PRST;
633 }
Willy Tarreau4de91492010-01-22 19:10:05 +0100634 break;
635 }
636 }
637
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200638 return 1;
Willy Tarreaubedb9ba2009-07-12 08:27:39 +0200639
640 sw_failed:
641 /* immediately abort this request in case of allocation failure */
642 buffer_abort(s->req);
643 buffer_abort(s->rep);
644
645 if (!(s->flags & SN_ERR_MASK))
646 s->flags |= SN_ERR_RESOURCE;
647 if (!(s->flags & SN_FINST_MASK))
648 s->flags |= SN_FINST_R;
649
650 s->txn.status = 500;
651 s->req->analysers = 0;
652 s->req->analyse_exp = TICK_ETERNITY;
653 return 0;
Willy Tarreau1d0dfb12009-07-07 15:10:31 +0200654}
655
Emeric Brun1d33b292010-01-04 15:47:17 +0100656/* This stream analyser works on a request. It applies all sticking rules on
657 * it then returns 1. The data must already be present in the buffer otherwise
658 * they won't match. It always returns 1.
659 */
660int process_sticking_rules(struct session *s, struct buffer *req, int an_bit)
661{
662 struct proxy *px = s->be;
663 struct sticking_rule *rule;
664
665 DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
666 now_ms, __FUNCTION__,
667 s,
668 req,
669 req->rex, req->wex,
670 req->flags,
671 req->l,
672 req->analysers);
673
674 list_for_each_entry(rule, &px->sticking_rules, list) {
675 int ret = 1 ;
676 int i;
677
678 for (i = 0; i < s->store_count; i++) {
679 if (rule->table.t == s->store[i].table)
680 break;
681 }
682
683 if (i != s->store_count)
684 continue;
685
686 if (rule->cond) {
687 ret = acl_exec_cond(rule->cond, px, s, &s->txn, ACL_DIR_REQ);
688 ret = acl_pass(ret);
689 if (rule->cond->pol == ACL_COND_UNLESS)
690 ret = !ret;
691 }
692
693 if (ret) {
694 struct stktable_key *key;
695
696 key = pattern_process_key(px, s, &s->txn, PATTERN_FETCH_REQ, rule->expr, rule->table.t->type);
697 if (!key)
698 continue;
699
700 if (rule->flags & STK_IS_MATCH) {
701 struct stksess *ts;
702
703 if ((ts = stktable_lookup(rule->table.t, key)) != NULL) {
704 if (!(s->flags & SN_ASSIGNED)) {
705 struct eb32_node *node;
706
707 /* srv found in table */
708 node = eb32_lookup(&px->conf.used_server_id, ts->sid);
709 if (node) {
710 struct server *srv;
711
712 srv = container_of(node, struct server, conf.id);
Willy Tarreau4de91492010-01-22 19:10:05 +0100713 if ((srv->state & SRV_RUNNING) ||
714 (px->options & PR_O_PERSIST) ||
715 (s->flags & SN_FORCE_PRST)) {
Emeric Brun1d33b292010-01-04 15:47:17 +0100716 s->flags |= SN_DIRECT | SN_ASSIGNED;
717 s->srv = srv;
718 }
719 }
720 }
721 ts->expire = tick_add(now_ms, MS_TO_TICKS(rule->table.t->expire));
722 }
723 }
724 if (rule->flags & STK_IS_STORE) {
725 if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
726 struct stksess *ts;
727
728 ts = stksess_new(rule->table.t, key);
729 if (ts) {
730 s->store[s->store_count].table = rule->table.t;
731 s->store[s->store_count++].ts = ts;
732 }
733 }
734 }
735 }
736 }
737
738 req->analysers &= ~an_bit;
739 req->analyse_exp = TICK_ETERNITY;
740 return 1;
741}
742
743/* This stream analyser works on a response. It applies all store rules on it
744 * then returns 1. The data must already be present in the buffer otherwise
745 * they won't match. It always returns 1.
746 */
747int process_store_rules(struct session *s, struct buffer *rep, int an_bit)
748{
749 struct proxy *px = s->be;
750 struct sticking_rule *rule;
751 int i;
752
753 DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
754 now_ms, __FUNCTION__,
755 s,
Willy Tarreau2e2b3eb2010-02-09 20:55:44 +0100756 rep,
757 rep->rex, rep->wex,
758 rep->flags,
759 rep->l,
760 rep->analysers);
Emeric Brun1d33b292010-01-04 15:47:17 +0100761
762 list_for_each_entry(rule, &px->storersp_rules, list) {
763 int ret = 1 ;
764 int storereqidx = -1;
765
766 for (i = 0; i < s->store_count; i++) {
767 if (rule->table.t == s->store[i].table) {
768 if (!(s->store[i].flags))
769 storereqidx = i;
770 break;
771 }
772 }
773
774 if ((i != s->store_count) && (storereqidx == -1))
775 continue;
776
777 if (rule->cond) {
778 ret = acl_exec_cond(rule->cond, px, s, &s->txn, ACL_DIR_RTR);
779 ret = acl_pass(ret);
780 if (rule->cond->pol == ACL_COND_UNLESS)
781 ret = !ret;
782 }
783
784 if (ret) {
785 struct stktable_key *key;
786
787 key = pattern_process_key(px, s, &s->txn, PATTERN_FETCH_RTR, rule->expr, rule->table.t->type);
788 if (!key)
789 continue;
790
791 if (storereqidx != -1) {
792 stksess_key(s->store[storereqidx].table, s->store[storereqidx].ts, key);
793 s->store[storereqidx].flags = 1;
794 }
795 else if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
796 struct stksess *ts;
797
798 ts = stksess_new(rule->table.t, key);
799 if (ts) {
800 s->store[s->store_count].table = rule->table.t;
801 s->store[s->store_count].flags = 1;
802 s->store[s->store_count++].ts = ts;
803 }
804 }
805 }
806 }
807
808 /* process store request and store response */
809 for (i = 0; i < s->store_count; i++) {
810 if (stktable_store(s->store[i].table, s->store[i].ts, s->srv->puid) > 0) {
811 stksess_free(s->store[i].table, s->store[i].ts);
812 s->store[i].ts = NULL;
813 }
814 }
815
816 rep->analysers &= ~an_bit;
817 rep->analyse_exp = TICK_ETERNITY;
818 return 1;
819}
820
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +0100821/* This macro is very specific to the function below. See the comments in
822 * process_session() below to understand the logic and the tests.
823 */
824#define UPDATE_ANALYSERS(real, list, back, flag) { \
825 list = (((list) & ~(flag)) | ~(back)) & (real); \
826 back = real; \
827 if (!(list)) \
828 break; \
829 if (((list) ^ ((list) & ((list) - 1))) < (flag)) \
830 continue; \
831}
832
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100833/* Processes the client, server, request and response jobs of a session task,
834 * then puts it back to the wait queue in a clean state, or cleans up its
835 * resources if it must be deleted. Returns in <next> the date the task wants
836 * to be woken up, or TICK_ETERNITY. In order not to call all functions for
837 * nothing too many times, the request and response buffers flags are monitored
838 * and each function is called only if at least another function has changed at
839 * least one flag it is interested in.
840 */
Willy Tarreau26c25062009-03-08 09:38:41 +0100841struct task *process_session(struct task *t)
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100842{
843 struct session *s = t->context;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100844 unsigned int rqf_last, rpf_last;
Willy Tarreau576507f2010-01-07 00:09:04 +0100845 unsigned int req_ana_back;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100846
847 //DPRINTF(stderr, "%s:%d: cs=%d ss=%d(%d) rqf=0x%08x rpf=0x%08x\n", __FUNCTION__, __LINE__,
848 // s->si[0].state, s->si[1].state, s->si[1].err_type, s->req->flags, s->rep->flags);
849
Krzysztof Piotr Oledzkif9423ae2010-01-29 19:26:18 +0100850 /* this data may be no longer valid, clear it */
851 memset(&s->txn.auth, 0, sizeof(s->txn.auth));
852
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200853 /* This flag must explicitly be set every time */
854 s->req->flags &= ~BF_READ_NOEXP;
855
856 /* Keep a copy of req/rep flags so that we can detect shutdowns */
857 rqf_last = s->req->flags;
858 rpf_last = s->rep->flags;
859
Willy Tarreau89f7ef22009-09-05 20:57:35 +0200860 /* we don't want the stream interface functions to recursively wake us up */
861 if (s->req->prod->owner == t)
862 s->req->prod->flags |= SI_FL_DONT_WAKE;
863 if (s->req->cons->owner == t)
864 s->req->cons->flags |= SI_FL_DONT_WAKE;
865
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100866 /* 1a: Check for low level timeouts if needed. We just set a flag on
867 * stream interfaces when their timeouts have expired.
868 */
869 if (unlikely(t->state & TASK_WOKEN_TIMER)) {
870 stream_int_check_timeouts(&s->si[0]);
871 stream_int_check_timeouts(&s->si[1]);
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200872
873 /* check buffer timeouts, and close the corresponding stream interfaces
874 * for future reads or writes. Note: this will also concern upper layers
875 * but we do not touch any other flag. We must be careful and correctly
876 * detect state changes when calling them.
877 */
878
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100879 buffer_check_timeouts(s->req);
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200880
Willy Tarreau14641402009-12-29 14:49:56 +0100881 if (unlikely((s->req->flags & (BF_SHUTW|BF_WRITE_TIMEOUT)) == BF_WRITE_TIMEOUT)) {
882 s->req->cons->flags |= SI_FL_NOLINGER;
883 s->req->cons->shutw(s->req->cons);
884 }
885
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200886 if (unlikely((s->req->flags & (BF_SHUTR|BF_READ_TIMEOUT)) == BF_READ_TIMEOUT))
887 s->req->prod->shutr(s->req->prod);
888
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100889 buffer_check_timeouts(s->rep);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100890
Willy Tarreau14641402009-12-29 14:49:56 +0100891 if (unlikely((s->rep->flags & (BF_SHUTW|BF_WRITE_TIMEOUT)) == BF_WRITE_TIMEOUT)) {
892 s->rep->cons->flags |= SI_FL_NOLINGER;
893 s->rep->cons->shutw(s->rep->cons);
894 }
895
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200896 if (unlikely((s->rep->flags & (BF_SHUTR|BF_READ_TIMEOUT)) == BF_READ_TIMEOUT))
897 s->rep->prod->shutr(s->rep->prod);
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200898 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100899
900 /* 1b: check for low-level errors reported at the stream interface.
901 * First we check if it's a retryable error (in which case we don't
902 * want to tell the buffer). Otherwise we report the error one level
903 * upper by setting flags into the buffers. Note that the side towards
904 * the client cannot have connect (hence retryable) errors. Also, the
905 * connection setup code must be able to deal with any type of abort.
906 */
907 if (unlikely(s->si[0].flags & SI_FL_ERR)) {
908 if (s->si[0].state == SI_ST_EST || s->si[0].state == SI_ST_DIS) {
909 s->si[0].shutr(&s->si[0]);
910 s->si[0].shutw(&s->si[0]);
911 stream_int_report_error(&s->si[0]);
Willy Tarreau05cb29b2008-12-14 11:44:04 +0100912 if (!(s->req->analysers) && !(s->rep->analysers)) {
Willy Tarreauae526782010-03-04 20:34:23 +0100913 s->be->counters.cli_aborts++;
914 if (s->srv)
915 s->srv->counters.cli_aborts++;
Willy Tarreau05cb29b2008-12-14 11:44:04 +0100916 if (!(s->flags & SN_ERR_MASK))
917 s->flags |= SN_ERR_CLICL;
918 if (!(s->flags & SN_FINST_MASK))
919 s->flags |= SN_FINST_D;
920 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100921 }
922 }
923
924 if (unlikely(s->si[1].flags & SI_FL_ERR)) {
925 if (s->si[1].state == SI_ST_EST || s->si[1].state == SI_ST_DIS) {
926 s->si[1].shutr(&s->si[1]);
927 s->si[1].shutw(&s->si[1]);
928 stream_int_report_error(&s->si[1]);
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200929 s->be->counters.failed_resp++;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100930 if (s->srv)
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +0200931 s->srv->counters.failed_resp++;
Willy Tarreau05cb29b2008-12-14 11:44:04 +0100932 if (!(s->req->analysers) && !(s->rep->analysers)) {
Willy Tarreauae526782010-03-04 20:34:23 +0100933 s->be->counters.srv_aborts++;
934 if (s->srv)
935 s->srv->counters.srv_aborts++;
Willy Tarreau05cb29b2008-12-14 11:44:04 +0100936 if (!(s->flags & SN_ERR_MASK))
937 s->flags |= SN_ERR_SRVCL;
938 if (!(s->flags & SN_FINST_MASK))
939 s->flags |= SN_FINST_D;
940 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100941 }
942 /* note: maybe we should process connection errors here ? */
943 }
944
945 if (s->si[1].state == SI_ST_CON) {
946 /* we were trying to establish a connection on the server side,
947 * maybe it succeeded, maybe it failed, maybe we timed out, ...
948 */
949 if (unlikely(!sess_update_st_con_tcp(s, &s->si[1])))
950 sess_update_st_cer(s, &s->si[1]);
951 else if (s->si[1].state == SI_ST_EST)
952 sess_establish(s, &s->si[1]);
953
954 /* state is now one of SI_ST_CON (still in progress), SI_ST_EST
955 * (established), SI_ST_DIS (abort), SI_ST_CLO (last error),
956 * SI_ST_ASS/SI_ST_TAR/SI_ST_REQ for retryable errors.
957 */
958 }
959
Willy Tarreaub67a9b82009-06-21 22:03:51 +0200960resync_stream_interface:
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100961 /* Check for connection closure */
962
Willy Tarreau55a8d0e2008-11-30 18:47:21 +0100963 DPRINTF(stderr,
964 "[%u] %s:%d: task=%p s=%p, sfl=0x%08x, rq=%p, rp=%p, exp(r,w)=%u,%u rqf=%08x rpf=%08x rql=%d rpl=%d cs=%d ss=%d, cet=0x%x set=0x%x retr=%d\n",
965 now_ms, __FUNCTION__, __LINE__,
966 t,
967 s, s->flags,
968 s->req, s->rep,
969 s->req->rex, s->rep->wex,
970 s->req->flags, s->rep->flags,
971 s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state,
972 s->rep->cons->err_type, s->req->cons->err_type,
973 s->conn_retries);
974
975 /* nothing special to be done on client side */
976 if (unlikely(s->req->prod->state == SI_ST_DIS))
977 s->req->prod->state = SI_ST_CLO;
978
979 /* When a server-side connection is released, we have to count it and
980 * check for pending connections on this server.
981 */
982 if (unlikely(s->req->cons->state == SI_ST_DIS)) {
983 s->req->cons->state = SI_ST_CLO;
984 if (s->srv) {
985 if (s->flags & SN_CURR_SESS) {
986 s->flags &= ~SN_CURR_SESS;
987 s->srv->cur_sess--;
988 }
989 sess_change_server(s, NULL);
990 if (may_dequeue_tasks(s->srv, s->be))
991 process_srv_queue(s->srv);
992 }
993 }
994
995 /*
996 * Note: of the transient states (REQ, CER, DIS), only REQ may remain
997 * at this point.
998 */
999
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001000 resync_request:
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001001 /* Analyse request */
1002 if ((s->req->flags & BF_MASK_ANALYSER) ||
1003 (s->req->flags ^ rqf_last) & BF_MASK_STATIC) {
1004 unsigned int flags = s->req->flags;
1005
1006 if (s->req->prod->state >= SI_ST_EST) {
Willy Tarreaue34070e2010-01-08 00:32:27 +01001007 int max_loops = global.tune.maxpollevents;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001008 unsigned int ana_list;
1009 unsigned int ana_back;
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001010
Willy Tarreau90deb182010-01-07 00:20:41 +01001011 /* it's up to the analysers to stop new connections,
1012 * disable reading or closing. Note: if an analyser
1013 * disables any of these bits, it is responsible for
1014 * enabling them again when it disables itself, so
1015 * that other analysers are called in similar conditions.
1016 */
1017 buffer_auto_read(s->req);
Willy Tarreau520d95e2009-09-19 21:04:57 +02001018 buffer_auto_connect(s->req);
1019 buffer_auto_close(s->req);
Willy Tarreauedcf6682008-11-30 23:15:34 +01001020
1021 /* We will call all analysers for which a bit is set in
1022 * s->req->analysers, following the bit order from LSB
1023 * to MSB. The analysers must remove themselves from
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001024 * the list when not needed. Any analyser may return 0
1025 * to break out of the loop, either because of missing
1026 * data to take a decision, or because it decides to
1027 * kill the session. We loop at least once through each
1028 * analyser, and we may loop again if other analysers
1029 * are added in the middle.
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001030 *
1031 * We build a list of analysers to run. We evaluate all
1032 * of these analysers in the order of the lower bit to
1033 * the higher bit. This ordering is very important.
1034 * An analyser will often add/remove other analysers,
1035 * including itself. Any changes to itself have no effect
1036 * on the loop. If it removes any other analysers, we
1037 * want those analysers not to be called anymore during
1038 * this loop. If it adds an analyser that is located
1039 * after itself, we want it to be scheduled for being
1040 * processed during the loop. If it adds an analyser
1041 * which is located before it, we want it to switch to
1042 * it immediately, even if it has already been called
1043 * once but removed since.
1044 *
1045 * In order to achieve this, we compare the analyser
1046 * list after the call with a copy of it before the
1047 * call. The work list is fed with analyser bits that
1048 * appeared during the call. Then we compare previous
1049 * work list with the new one, and check the bits that
1050 * appeared. If the lowest of these bits is lower than
1051 * the current bit, it means we have enabled a previous
1052 * analyser and must immediately loop again.
Willy Tarreauedcf6682008-11-30 23:15:34 +01001053 */
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001054
1055 ana_list = ana_back = s->req->analysers;
Willy Tarreaue34070e2010-01-08 00:32:27 +01001056 while (ana_list && max_loops--) {
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001057 /* Warning! ensure that analysers are always placed in ascending order! */
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001058
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001059 if (ana_list & AN_REQ_INSPECT) {
Willy Tarreau3a816292009-07-07 10:55:49 +02001060 if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT))
Willy Tarreauedcf6682008-11-30 23:15:34 +01001061 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001062 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_INSPECT);
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001063 }
Willy Tarreauedcf6682008-11-30 23:15:34 +01001064
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001065 if (ana_list & AN_REQ_WAIT_HTTP) {
Willy Tarreau3a816292009-07-07 10:55:49 +02001066 if (!http_wait_for_request(s, s->req, AN_REQ_WAIT_HTTP))
Willy Tarreaud787e662009-07-07 10:14:51 +02001067 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001068 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_WAIT_HTTP);
Willy Tarreaud787e662009-07-07 10:14:51 +02001069 }
1070
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001071 if (ana_list & AN_REQ_HTTP_PROCESS_FE) {
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001072 if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_FE, s->fe))
1073 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001074 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_FE);
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001075 }
1076
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001077 if (ana_list & AN_REQ_SWITCHING_RULES) {
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001078 if (!process_switching_rules(s, s->req, AN_REQ_SWITCHING_RULES))
1079 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001080 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_SWITCHING_RULES);
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001081 }
1082
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001083 if (ana_list & AN_REQ_HTTP_PROCESS_BE) {
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001084 if (!http_process_req_common(s, s->req, AN_REQ_HTTP_PROCESS_BE, s->be))
1085 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001086 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_PROCESS_BE);
Willy Tarreau1d0dfb12009-07-07 15:10:31 +02001087 }
1088
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001089 if (ana_list & AN_REQ_HTTP_TARPIT) {
Willy Tarreau3a816292009-07-07 10:55:49 +02001090 if (!http_process_tarpit(s, s->req, AN_REQ_HTTP_TARPIT))
Willy Tarreau60b85b02008-11-30 23:28:40 +01001091 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001092 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_TARPIT);
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001093 }
Willy Tarreau60b85b02008-11-30 23:28:40 +01001094
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001095 if (ana_list & AN_REQ_HTTP_INNER) {
Willy Tarreauc465fd72009-08-31 00:17:18 +02001096 if (!http_process_request(s, s->req, AN_REQ_HTTP_INNER))
1097 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001098 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_INNER);
Willy Tarreauc465fd72009-08-31 00:17:18 +02001099 }
1100
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001101 if (ana_list & AN_REQ_HTTP_BODY) {
Willy Tarreau3a816292009-07-07 10:55:49 +02001102 if (!http_process_request_body(s, s->req, AN_REQ_HTTP_BODY))
Willy Tarreaud34af782008-11-30 23:36:37 +01001103 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001104 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_BODY);
Willy Tarreau1a52dbd2009-06-28 19:37:53 +02001105 }
Emeric Brun647caf12009-06-30 17:57:00 +02001106
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001107 if (ana_list & AN_REQ_PRST_RDP_COOKIE) {
Emeric Brun647caf12009-06-30 17:57:00 +02001108 if (!tcp_persist_rdp_cookie(s, s->req, AN_REQ_PRST_RDP_COOKIE))
1109 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001110 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_PRST_RDP_COOKIE);
Emeric Brun647caf12009-06-30 17:57:00 +02001111 }
Willy Tarreaud98cf932009-12-27 22:54:55 +01001112
Emeric Brun1d33b292010-01-04 15:47:17 +01001113 if (ana_list & AN_REQ_STICKING_RULES) {
1114 if (!process_sticking_rules(s, s->req, AN_REQ_STICKING_RULES))
1115 break;
1116 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_STICKING_RULES);
1117 }
1118
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001119 if (ana_list & AN_REQ_HTTP_XFER_BODY) {
Willy Tarreaud98cf932009-12-27 22:54:55 +01001120 if (!http_request_forward_body(s, s->req, AN_REQ_HTTP_XFER_BODY))
1121 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001122 UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_HTTP_XFER_BODY);
Willy Tarreaud98cf932009-12-27 22:54:55 +01001123 }
Willy Tarreaue34070e2010-01-08 00:32:27 +01001124 break;
1125 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001126 }
Willy Tarreau84455332009-03-15 22:34:05 +01001127
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001128 if ((s->req->flags ^ flags) & BF_MASK_STATIC) {
1129 rqf_last = s->req->flags;
1130 goto resync_request;
1131 }
1132 }
1133
Willy Tarreau576507f2010-01-07 00:09:04 +01001134 /* we'll monitor the request analysers while parsing the response,
1135 * because some response analysers may indirectly enable new request
1136 * analysers (eg: HTTP keep-alive).
1137 */
1138 req_ana_back = s->req->analysers;
1139
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001140 resync_response:
1141 /* Analyse response */
1142
1143 if (unlikely(s->rep->flags & BF_HIJACK)) {
1144 /* In inject mode, we wake up everytime something has
1145 * happened on the write side of the buffer.
1146 */
1147 unsigned int flags = s->rep->flags;
1148
1149 if ((s->rep->flags & (BF_WRITE_PARTIAL|BF_WRITE_ERROR|BF_SHUTW)) &&
1150 !(s->rep->flags & BF_FULL)) {
1151 s->rep->hijacker(s, s->rep);
1152 }
1153
1154 if ((s->rep->flags ^ flags) & BF_MASK_STATIC) {
1155 rpf_last = s->rep->flags;
1156 goto resync_response;
1157 }
1158 }
1159 else if ((s->rep->flags & BF_MASK_ANALYSER) ||
1160 (s->rep->flags ^ rpf_last) & BF_MASK_STATIC) {
1161 unsigned int flags = s->rep->flags;
1162
1163 if (s->rep->prod->state >= SI_ST_EST) {
Willy Tarreaue34070e2010-01-08 00:32:27 +01001164 int max_loops = global.tune.maxpollevents;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001165 unsigned int ana_list;
1166 unsigned int ana_back;
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001167
Willy Tarreau90deb182010-01-07 00:20:41 +01001168 /* it's up to the analysers to stop disable reading or
1169 * closing. Note: if an analyser disables any of these
1170 * bits, it is responsible for enabling them again when
1171 * it disables itself, so that other analysers are called
1172 * in similar conditions.
1173 */
1174 buffer_auto_read(s->rep);
Willy Tarreau520d95e2009-09-19 21:04:57 +02001175 buffer_auto_close(s->rep);
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001176
1177 /* We will call all analysers for which a bit is set in
1178 * s->rep->analysers, following the bit order from LSB
1179 * to MSB. The analysers must remove themselves from
1180 * the list when not needed. Any analyser may return 0
1181 * to break out of the loop, either because of missing
1182 * data to take a decision, or because it decides to
1183 * kill the session. We loop at least once through each
1184 * analyser, and we may loop again if other analysers
1185 * are added in the middle.
1186 */
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001187
1188 ana_list = ana_back = s->rep->analysers;
Willy Tarreaue34070e2010-01-08 00:32:27 +01001189 while (ana_list && max_loops--) {
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001190 /* Warning! ensure that analysers are always placed in ascending order! */
1191
1192 if (ana_list & AN_RES_WAIT_HTTP) {
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001193 if (!http_wait_for_response(s, s->rep, AN_RES_WAIT_HTTP))
1194 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001195 UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_WAIT_HTTP);
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001196 }
1197
Emeric Brun1d33b292010-01-04 15:47:17 +01001198 if (ana_list & AN_RES_STORE_RULES) {
1199 if (!process_store_rules(s, s->rep, AN_RES_STORE_RULES))
1200 break;
1201 UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_STORE_RULES);
1202 }
1203
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001204 if (ana_list & AN_RES_HTTP_PROCESS_BE) {
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001205 if (!http_process_res_common(s, s->rep, AN_RES_HTTP_PROCESS_BE, s->be))
1206 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001207 UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_PROCESS_BE);
Willy Tarreaub37c27e2009-10-18 22:53:08 +02001208 }
Willy Tarreaud98cf932009-12-27 22:54:55 +01001209
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001210 if (ana_list & AN_RES_HTTP_XFER_BODY) {
Willy Tarreaud98cf932009-12-27 22:54:55 +01001211 if (!http_response_forward_body(s, s->rep, AN_RES_HTTP_XFER_BODY))
1212 break;
Willy Tarreau1e0bbaf2010-01-06 23:53:24 +01001213 UPDATE_ANALYSERS(s->rep->analysers, ana_list, ana_back, AN_RES_HTTP_XFER_BODY);
Willy Tarreaud98cf932009-12-27 22:54:55 +01001214 }
Willy Tarreaue34070e2010-01-08 00:32:27 +01001215 break;
1216 }
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001217 }
1218
1219 if ((s->rep->flags ^ flags) & BF_MASK_STATIC) {
1220 rpf_last = s->rep->flags;
1221 goto resync_response;
1222 }
1223 }
1224
Willy Tarreau576507f2010-01-07 00:09:04 +01001225 /* maybe someone has added some request analysers, so we must check and loop */
1226 if (s->req->analysers & ~req_ana_back)
1227 goto resync_request;
1228
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001229 /* FIXME: here we should call protocol handlers which rely on
1230 * both buffers.
1231 */
1232
1233
1234 /*
Willy Tarreauae526782010-03-04 20:34:23 +01001235 * Now we propagate unhandled errors to the session. Normally
1236 * we're just in a data phase here since it means we have not
1237 * seen any analyser who could set an error status.
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001238 */
1239 if (!(s->flags & SN_ERR_MASK)) {
1240 if (s->req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) {
1241 /* Report it if the client got an error or a read timeout expired */
Willy Tarreau84455332009-03-15 22:34:05 +01001242 s->req->analysers = 0;
Willy Tarreauae526782010-03-04 20:34:23 +01001243 if (s->req->flags & BF_READ_ERROR) {
1244 s->be->counters.cli_aborts++;
1245 if (s->srv)
1246 s->srv->counters.cli_aborts++;
Willy Tarreau84455332009-03-15 22:34:05 +01001247 s->flags |= SN_ERR_CLICL;
Willy Tarreauae526782010-03-04 20:34:23 +01001248 }
1249 else if (s->req->flags & BF_READ_TIMEOUT) {
1250 s->be->counters.cli_aborts++;
1251 if (s->srv)
1252 s->srv->counters.cli_aborts++;
Willy Tarreau84455332009-03-15 22:34:05 +01001253 s->flags |= SN_ERR_CLITO;
Willy Tarreauae526782010-03-04 20:34:23 +01001254 }
1255 else if (s->req->flags & BF_WRITE_ERROR) {
1256 s->be->counters.srv_aborts++;
1257 if (s->srv)
1258 s->srv->counters.srv_aborts++;
Willy Tarreau84455332009-03-15 22:34:05 +01001259 s->flags |= SN_ERR_SRVCL;
Willy Tarreauae526782010-03-04 20:34:23 +01001260 }
1261 else {
1262 s->be->counters.srv_aborts++;
1263 if (s->srv)
1264 s->srv->counters.srv_aborts++;
Willy Tarreau84455332009-03-15 22:34:05 +01001265 s->flags |= SN_ERR_SRVTO;
Willy Tarreauae526782010-03-04 20:34:23 +01001266 }
Willy Tarreau84455332009-03-15 22:34:05 +01001267 sess_set_term_flags(s);
1268 }
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001269 else if (s->rep->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) {
1270 /* Report it if the server got an error or a read timeout expired */
1271 s->rep->analysers = 0;
Willy Tarreauae526782010-03-04 20:34:23 +01001272 if (s->rep->flags & BF_READ_ERROR) {
1273 s->be->counters.srv_aborts++;
1274 if (s->srv)
1275 s->srv->counters.srv_aborts++;
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001276 s->flags |= SN_ERR_SRVCL;
Willy Tarreauae526782010-03-04 20:34:23 +01001277 }
1278 else if (s->rep->flags & BF_READ_TIMEOUT) {
1279 s->be->counters.srv_aborts++;
1280 if (s->srv)
1281 s->srv->counters.srv_aborts++;
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001282 s->flags |= SN_ERR_SRVTO;
Willy Tarreauae526782010-03-04 20:34:23 +01001283 }
1284 else if (s->rep->flags & BF_WRITE_ERROR) {
1285 s->be->counters.cli_aborts++;
1286 if (s->srv)
1287 s->srv->counters.cli_aborts++;
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001288 s->flags |= SN_ERR_CLICL;
Willy Tarreauae526782010-03-04 20:34:23 +01001289 }
1290 else {
1291 s->be->counters.cli_aborts++;
1292 if (s->srv)
1293 s->srv->counters.cli_aborts++;
1294 s->flags |= SN_ERR_CLITO;
1295 }
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001296 sess_set_term_flags(s);
1297 }
Willy Tarreau84455332009-03-15 22:34:05 +01001298 }
1299
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001300 /*
1301 * Here we take care of forwarding unhandled data. This also includes
1302 * connection establishments and shutdown requests.
1303 */
1304
1305
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001306 /* If noone is interested in analysing data, it's time to forward
Willy Tarreau31971e52009-09-20 12:07:52 +02001307 * everything. We configure the buffer to forward indefinitely.
Willy Tarreau6b66f3e2008-12-14 17:31:54 +01001308 */
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001309 if (!s->req->analysers &&
Willy Tarreau82eeaf22009-12-29 12:09:05 +01001310 !(s->req->flags & (BF_HIJACK|BF_SHUTW|BF_SHUTW_NOW)) &&
Willy Tarreau31971e52009-09-20 12:07:52 +02001311 (s->req->prod->state >= SI_ST_EST) &&
1312 (s->req->to_forward != BUF_INFINITE_FORWARD)) {
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001313 /* This buffer is freewheeling, there's no analyser nor hijacker
1314 * attached to it. If any data are left in, we'll permit them to
1315 * move.
1316 */
Willy Tarreau90deb182010-01-07 00:20:41 +01001317 buffer_auto_read(s->req);
Willy Tarreau520d95e2009-09-19 21:04:57 +02001318 buffer_auto_connect(s->req);
1319 buffer_auto_close(s->req);
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001320 buffer_flush(s->req);
Willy Tarreau5bd8c372009-01-19 00:32:22 +01001321
Willy Tarreau31971e52009-09-20 12:07:52 +02001322 /* If the producer is still connected, we'll enable data to flow
1323 * from the producer to the consumer (which might possibly not be
1324 * connected yet).
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001325 */
Willy Tarreau31971e52009-09-20 12:07:52 +02001326 if (!(s->req->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)))
1327 buffer_forward(s->req, BUF_INFINITE_FORWARD);
Willy Tarreau6b66f3e2008-12-14 17:31:54 +01001328 }
Willy Tarreauf890dc92008-12-13 21:12:26 +01001329
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001330 /* check if it is wise to enable kernel splicing to forward request data */
1331 if (!(s->req->flags & (BF_KERN_SPLICING|BF_SHUTR)) &&
1332 s->req->to_forward &&
1333 (global.tune.options & GTUNE_USE_SPLICE) &&
Willy Tarreaudc340a92009-06-28 23:10:19 +02001334 (s->si[0].flags & s->si[1].flags & SI_FL_CAP_SPLICE) &&
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001335 (pipes_used < global.maxpipes) &&
1336 (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) ||
1337 (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
1338 (s->req->flags & BF_STREAMER_FAST)))) {
1339 s->req->flags |= BF_KERN_SPLICING;
1340 }
1341
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001342 /* reflect what the L7 analysers have seen last */
1343 rqf_last = s->req->flags;
1344
1345 /*
1346 * Now forward all shutdown requests between both sides of the buffer
1347 */
1348
Willy Tarreau520d95e2009-09-19 21:04:57 +02001349 /* first, let's check if the request buffer needs to shutdown(write), which may
1350 * happen either because the input is closed or because we want to force a close
Willy Tarreaue4599762010-03-21 23:25:09 +01001351 * once the server has begun to respond.
Willy Tarreau520d95e2009-09-19 21:04:57 +02001352 */
Willy Tarreau82eeaf22009-12-29 12:09:05 +01001353 if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTR)) ==
Willy Tarreaue4599762010-03-21 23:25:09 +01001354 (BF_AUTO_CLOSE|BF_SHUTR)))
Willy Tarreauba0b63d2009-09-20 08:09:44 +02001355 buffer_shutw_now(s->req);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001356
1357 /* shutdown(write) pending */
Willy Tarreauba0b63d2009-09-20 08:09:44 +02001358 if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_OUT_EMPTY)) == (BF_SHUTW_NOW|BF_OUT_EMPTY)))
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001359 s->req->cons->shutw(s->req->cons);
1360
1361 /* shutdown(write) done on server side, we must stop the client too */
Willy Tarreau3dbc6942008-12-07 13:05:04 +01001362 if (unlikely((s->req->flags & (BF_SHUTW|BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTW &&
1363 !s->req->analysers))
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001364 buffer_shutr_now(s->req);
1365
1366 /* shutdown(read) pending */
1367 if (unlikely((s->req->flags & (BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTR_NOW))
1368 s->req->prod->shutr(s->req->prod);
1369
Willy Tarreau520d95e2009-09-19 21:04:57 +02001370 /* it's possible that an upper layer has requested a connection setup or abort.
1371 * There are 2 situations where we decide to establish a new connection :
1372 * - there are data scheduled for emission in the buffer
1373 * - the BF_AUTO_CONNECT flag is set (active connection)
1374 */
1375 if (s->req->cons->state == SI_ST_INI) {
Willy Tarreaue4599762010-03-21 23:25:09 +01001376 if (!(s->req->flags & BF_SHUTW)) {
Willy Tarreauba0b63d2009-09-20 08:09:44 +02001377 if ((s->req->flags & (BF_AUTO_CONNECT|BF_OUT_EMPTY)) != BF_OUT_EMPTY) {
Willy Tarreau85e7d002010-05-31 11:57:51 +02001378 /* If we have an iohandler without a connect method, we immediately
1379 * switch to the connected state, otherwise we perform a connection
1380 * request.
Willy Tarreau520d95e2009-09-19 21:04:57 +02001381 */
Willy Tarreau85e7d002010-05-31 11:57:51 +02001382 s->req->cons->state = SI_ST_REQ; /* new connection requested */
1383 if (unlikely(s->req->cons->iohandler && !s->req->cons->connect)) {
Willy Tarreau520d95e2009-09-19 21:04:57 +02001384 s->req->cons->state = SI_ST_EST; /* connection established */
Willy Tarreau85e7d002010-05-31 11:57:51 +02001385 s->rep->flags |= BF_READ_ATTACHED; /* producer is now attached */
1386 s->req->wex = TICK_ETERNITY;
1387 }
Willy Tarreau520d95e2009-09-19 21:04:57 +02001388 }
Willy Tarreau73201222009-08-16 18:27:24 +02001389 }
Willy Tarreauf41ffdc2009-09-20 08:19:25 +02001390 else {
Willy Tarreau92795622009-03-06 12:51:23 +01001391 s->req->cons->state = SI_ST_CLO; /* shutw+ini = abort */
Willy Tarreauf41ffdc2009-09-20 08:19:25 +02001392 buffer_shutw_now(s->req); /* fix buffer flags upon abort */
1393 buffer_shutr_now(s->rep);
1394 }
Willy Tarreau92795622009-03-06 12:51:23 +01001395 }
1396
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001397
1398 /* we may have a pending connection request, or a connection waiting
1399 * for completion.
1400 */
1401 if (s->si[1].state >= SI_ST_REQ && s->si[1].state < SI_ST_CON) {
1402 do {
1403 /* nb: step 1 might switch from QUE to ASS, but we first want
1404 * to give a chance to step 2 to perform a redirect if needed.
1405 */
1406 if (s->si[1].state != SI_ST_REQ)
1407 sess_update_stream_int(s, &s->si[1]);
1408 if (s->si[1].state == SI_ST_REQ)
1409 sess_prepare_conn_req(s, &s->si[1]);
1410
1411 if (s->si[1].state == SI_ST_ASS && s->srv &&
1412 s->srv->rdr_len && (s->flags & SN_REDIRECTABLE))
1413 perform_http_redirect(s, &s->si[1]);
1414 } while (s->si[1].state == SI_ST_ASS);
1415 }
1416
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001417 /* Benchmarks have shown that it's optimal to do a full resync now */
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001418 if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001419 goto resync_stream_interface;
1420
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001421 /* otherwise wewant to check if we need to resync the req buffer or not */
1422 if ((s->req->flags ^ rqf_last) & BF_MASK_STATIC)
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001423 goto resync_request;
1424
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001425 /* perform output updates to the response buffer */
Willy Tarreau84455332009-03-15 22:34:05 +01001426
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001427 /* If noone is interested in analysing data, it's time to forward
Willy Tarreau31971e52009-09-20 12:07:52 +02001428 * everything. We configure the buffer to forward indefinitely.
Willy Tarreau6b66f3e2008-12-14 17:31:54 +01001429 */
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001430 if (!s->rep->analysers &&
Willy Tarreau82eeaf22009-12-29 12:09:05 +01001431 !(s->rep->flags & (BF_HIJACK|BF_SHUTW|BF_SHUTW_NOW)) &&
Willy Tarreau31971e52009-09-20 12:07:52 +02001432 (s->rep->prod->state >= SI_ST_EST) &&
1433 (s->rep->to_forward != BUF_INFINITE_FORWARD)) {
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001434 /* This buffer is freewheeling, there's no analyser nor hijacker
1435 * attached to it. If any data are left in, we'll permit them to
1436 * move.
1437 */
Willy Tarreau90deb182010-01-07 00:20:41 +01001438 buffer_auto_read(s->rep);
Willy Tarreau520d95e2009-09-19 21:04:57 +02001439 buffer_auto_close(s->rep);
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001440 buffer_flush(s->rep);
Willy Tarreau31971e52009-09-20 12:07:52 +02001441 if (!(s->rep->flags & (BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)))
1442 buffer_forward(s->rep, BUF_INFINITE_FORWARD);
Willy Tarreau6b66f3e2008-12-14 17:31:54 +01001443 }
Willy Tarreauf890dc92008-12-13 21:12:26 +01001444
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001445 /* check if it is wise to enable kernel splicing to forward response data */
1446 if (!(s->rep->flags & (BF_KERN_SPLICING|BF_SHUTR)) &&
1447 s->rep->to_forward &&
1448 (global.tune.options & GTUNE_USE_SPLICE) &&
Willy Tarreaudc340a92009-06-28 23:10:19 +02001449 (s->si[0].flags & s->si[1].flags & SI_FL_CAP_SPLICE) &&
Willy Tarreau7c84bab2009-03-08 21:38:23 +01001450 (pipes_used < global.maxpipes) &&
1451 (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) ||
1452 (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&
1453 (s->rep->flags & BF_STREAMER_FAST)))) {
1454 s->rep->flags |= BF_KERN_SPLICING;
1455 }
1456
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001457 /* reflect what the L7 analysers have seen last */
1458 rpf_last = s->rep->flags;
1459
1460 /*
1461 * Now forward all shutdown requests between both sides of the buffer
1462 */
1463
1464 /*
1465 * FIXME: this is probably where we should produce error responses.
1466 */
1467
Willy Tarreau6b66f3e2008-12-14 17:31:54 +01001468 /* first, let's check if the response buffer needs to shutdown(write) */
Willy Tarreau520d95e2009-09-19 21:04:57 +02001469 if (unlikely((s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTR)) ==
1470 (BF_AUTO_CLOSE|BF_SHUTR)))
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001471 buffer_shutw_now(s->rep);
1472
1473 /* shutdown(write) pending */
Willy Tarreauba0b63d2009-09-20 08:09:44 +02001474 if (unlikely((s->rep->flags & (BF_SHUTW|BF_OUT_EMPTY|BF_SHUTW_NOW)) == (BF_OUT_EMPTY|BF_SHUTW_NOW)))
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001475 s->rep->cons->shutw(s->rep->cons);
1476
1477 /* shutdown(write) done on the client side, we must stop the server too */
Willy Tarreau3dbc6942008-12-07 13:05:04 +01001478 if (unlikely((s->rep->flags & (BF_SHUTW|BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTW) &&
1479 !s->rep->analysers)
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001480 buffer_shutr_now(s->rep);
1481
1482 /* shutdown(read) pending */
1483 if (unlikely((s->rep->flags & (BF_SHUTR|BF_SHUTR_NOW)) == BF_SHUTR_NOW))
1484 s->rep->prod->shutr(s->rep->prod);
1485
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001486 if (s->req->prod->state == SI_ST_DIS || s->req->cons->state == SI_ST_DIS)
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001487 goto resync_stream_interface;
1488
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001489 if (s->req->flags != rqf_last)
1490 goto resync_request;
1491
Willy Tarreau3deb3d02009-06-21 22:43:05 +02001492 if ((s->rep->flags ^ rpf_last) & BF_MASK_STATIC)
Willy Tarreau0be0ef92009-03-08 19:20:25 +01001493 goto resync_response;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001494
Willy Tarreau89f7ef22009-09-05 20:57:35 +02001495 /* we're interested in getting wakeups again */
1496 s->req->prod->flags &= ~SI_FL_DONT_WAKE;
1497 s->req->cons->flags &= ~SI_FL_DONT_WAKE;
1498
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001499 /* This is needed only when debugging is enabled, to indicate
1500 * client-side or server-side close. Please note that in the unlikely
1501 * event where both sides would close at once, the sequence is reported
1502 * on the server side first.
1503 */
1504 if (unlikely((global.mode & MODE_DEBUG) &&
1505 (!(global.mode & MODE_QUIET) ||
1506 (global.mode & MODE_VERBOSE)))) {
1507 int len;
1508
1509 if (s->si[1].state == SI_ST_CLO &&
1510 s->si[1].prev_state == SI_ST_EST) {
1511 len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n",
1512 s->uniq_id, s->be->id,
1513 (unsigned short)s->si[0].fd,
1514 (unsigned short)s->si[1].fd);
1515 write(1, trash, len);
1516 }
1517
1518 if (s->si[0].state == SI_ST_CLO &&
1519 s->si[0].prev_state == SI_ST_EST) {
1520 len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n",
1521 s->uniq_id, s->be->id,
1522 (unsigned short)s->si[0].fd,
1523 (unsigned short)s->si[1].fd);
1524 write(1, trash, len);
1525 }
1526 }
1527
1528 if (likely((s->rep->cons->state != SI_ST_CLO) ||
1529 (s->req->cons->state > SI_ST_INI && s->req->cons->state < SI_ST_CLO))) {
1530
1531 if ((s->fe->options & PR_O_CONTSTATS) && (s->flags & SN_BE_ASSIGNED))
1532 session_process_counters(s);
1533
Willy Tarreau1accfc02009-09-05 20:57:35 +02001534 if (s->rep->cons->state == SI_ST_EST && !s->rep->cons->iohandler)
Willy Tarreaudc85b392009-08-18 07:38:19 +02001535 s->rep->cons->update(s->rep->cons);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001536
Willy Tarreau1accfc02009-09-05 20:57:35 +02001537 if (s->req->cons->state == SI_ST_EST && !s->req->cons->iohandler)
Willy Tarreaudc85b392009-08-18 07:38:19 +02001538 s->req->cons->update(s->req->cons);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001539
Willy Tarreaua6eebb32010-06-04 11:40:20 +02001540 s->req->flags &= ~(BF_READ_NULL|BF_READ_PARTIAL|BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_READ_ATTACHED);
1541 s->rep->flags &= ~(BF_READ_NULL|BF_READ_PARTIAL|BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_READ_ATTACHED);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001542 s->si[0].prev_state = s->si[0].state;
1543 s->si[1].prev_state = s->si[1].state;
Willy Tarreaub0ef7352008-12-14 13:26:20 +01001544 s->si[0].flags &= ~(SI_FL_ERR|SI_FL_EXP);
1545 s->si[1].flags &= ~(SI_FL_ERR|SI_FL_EXP);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001546
1547 /* Trick: if a request is being waiting for the server to respond,
1548 * and if we know the server can timeout, we don't want the timeout
1549 * to expire on the client side first, but we're still interested
1550 * in passing data from the client to the server (eg: POST). Thus,
1551 * we can cancel the client's request timeout if the server's
1552 * request timeout is set and the server has not yet sent a response.
1553 */
1554
Willy Tarreau520d95e2009-09-19 21:04:57 +02001555 if ((s->rep->flags & (BF_AUTO_CLOSE|BF_SHUTR)) == 0 &&
Willy Tarreau86491c32008-12-14 09:04:47 +01001556 (tick_isset(s->req->wex) || tick_isset(s->rep->rex))) {
1557 s->req->flags |= BF_READ_NOEXP;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001558 s->req->rex = TICK_ETERNITY;
Willy Tarreau86491c32008-12-14 09:04:47 +01001559 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001560
Willy Tarreau1accfc02009-09-05 20:57:35 +02001561 /* Call the second stream interface's I/O handler if it's embedded.
1562 * Note that this one may wake the task up again.
1563 */
1564 if (s->req->cons->iohandler) {
1565 s->req->cons->iohandler(s->req->cons);
1566 if (task_in_rq(t)) {
1567 /* If we woke up, we don't want to requeue the
1568 * task to the wait queue, but rather requeue
1569 * it into the runqueue ASAP.
1570 */
1571 t->expire = TICK_ETERNITY;
1572 return t;
1573 }
1574 }
1575
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001576 t->expire = tick_first(tick_first(s->req->rex, s->req->wex),
1577 tick_first(s->rep->rex, s->rep->wex));
1578 if (s->req->analysers)
1579 t->expire = tick_first(t->expire, s->req->analyse_exp);
1580
1581 if (s->si[0].exp)
1582 t->expire = tick_first(t->expire, s->si[0].exp);
1583
1584 if (s->si[1].exp)
1585 t->expire = tick_first(t->expire, s->si[1].exp);
1586
1587#ifdef DEBUG_FULL
Willy Tarreau127334e2009-03-28 10:47:26 +01001588 fprintf(stderr,
1589 "[%u] queuing with exp=%u req->rex=%u req->wex=%u req->ana_exp=%u"
1590 " rep->rex=%u rep->wex=%u, si[0].exp=%u, si[1].exp=%u, cs=%d, ss=%d\n",
1591 now_ms, t->expire, s->req->rex, s->req->wex, s->req->analyse_exp,
1592 s->rep->rex, s->rep->wex, s->si[0].exp, s->si[1].exp, s->si[0].state, s->si[1].state);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001593#endif
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001594
1595#ifdef DEBUG_DEV
1596 /* this may only happen when no timeout is set or in case of an FSM bug */
Willy Tarreaud0a201b2009-03-08 15:53:06 +01001597 if (!tick_isset(t->expire))
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001598 ABORT_NOW();
1599#endif
Willy Tarreau26c25062009-03-08 09:38:41 +01001600 return t; /* nothing more to do */
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001601 }
1602
1603 s->fe->feconn--;
1604 if (s->flags & SN_BE_ASSIGNED)
1605 s->be->beconn--;
1606 actconn--;
Willy Tarreau6e6fb2b2009-08-16 18:20:44 +02001607 s->listener->nbconn--;
1608 if (s->listener->state == LI_FULL &&
1609 s->listener->nbconn < s->listener->maxconn) {
1610 /* we should reactivate the listener */
1611 EV_FD_SET(s->listener->fd, DIR_RD);
1612 s->listener->state = LI_READY;
1613 }
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001614
1615 if (unlikely((global.mode & MODE_DEBUG) &&
1616 (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)))) {
1617 int len;
Willy Tarreauec22b2c2009-03-06 13:07:40 +01001618 len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n",
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001619 s->uniq_id, s->be->id,
Willy Tarreauec22b2c2009-03-06 13:07:40 +01001620 (unsigned short)s->req->prod->fd, (unsigned short)s->req->cons->fd);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001621 write(1, trash, len);
1622 }
1623
1624 s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now);
1625 session_process_counters(s);
1626
Krzysztof Piotr Oledzkide71d162009-10-24 15:36:15 +02001627 if (s->txn.status) {
1628 int n;
1629
1630 n = s->txn.status / 100;
1631 if (n < 1 || n > 5)
1632 n = 0;
1633
1634 if (s->fe->mode == PR_MODE_HTTP)
Willy Tarreau24657792010-02-26 10:30:28 +01001635 s->fe->counters.fe.http.rsp[n]++;
Krzysztof Piotr Oledzkide71d162009-10-24 15:36:15 +02001636
Willy Tarreau24657792010-02-26 10:30:28 +01001637 if ((s->flags & SN_BE_ASSIGNED) &&
Krzysztof Piotr Oledzkide71d162009-10-24 15:36:15 +02001638 (s->be->mode == PR_MODE_HTTP))
Willy Tarreau24657792010-02-26 10:30:28 +01001639 s->be->counters.be.http.rsp[n]++;
Krzysztof Piotr Oledzkide71d162009-10-24 15:36:15 +02001640 }
1641
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001642 /* let's do a final log if we need it */
1643 if (s->logs.logwait &&
1644 !(s->flags & SN_MONITOR) &&
1645 (!(s->fe->options & PR_O_NULLNOLOG) || s->req->total)) {
Willy Tarreaua5555ec2008-11-30 19:02:32 +01001646 s->do_log(s);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001647 }
1648
1649 /* the task MUST not be in the run queue anymore */
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001650 session_free(s);
Willy Tarreau26c25062009-03-08 09:38:41 +01001651 task_delete(t);
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001652 task_free(t);
Willy Tarreau26c25062009-03-08 09:38:41 +01001653 return NULL;
Willy Tarreau55a8d0e2008-11-30 18:47:21 +01001654}
1655
Willy Tarreau7c669d72008-06-20 15:04:11 +02001656/*
1657 * This function adjusts sess->srv_conn and maintains the previous and new
1658 * server's served session counts. Setting newsrv to NULL is enough to release
1659 * current connection slot. This function also notifies any LB algo which might
1660 * expect to be informed about any change in the number of active sessions on a
1661 * server.
1662 */
1663void sess_change_server(struct session *sess, struct server *newsrv)
1664{
1665 if (sess->srv_conn == newsrv)
1666 return;
1667
1668 if (sess->srv_conn) {
1669 sess->srv_conn->served--;
1670 if (sess->srv_conn->proxy->lbprm.server_drop_conn)
1671 sess->srv_conn->proxy->lbprm.server_drop_conn(sess->srv_conn);
1672 sess->srv_conn = NULL;
1673 }
1674
1675 if (newsrv) {
1676 newsrv->served++;
1677 if (newsrv->proxy->lbprm.server_take_conn)
1678 newsrv->proxy->lbprm.server_take_conn(newsrv);
1679 sess->srv_conn = newsrv;
1680 }
1681}
1682
Willy Tarreau84455332009-03-15 22:34:05 +01001683/* Set correct session termination flags in case no analyser has done it. It
1684 * also counts a failed request if the server state has not reached the request
1685 * stage.
1686 */
1687void sess_set_term_flags(struct session *s)
1688{
1689 if (!(s->flags & SN_FINST_MASK)) {
1690 if (s->si[1].state < SI_ST_REQ) {
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02001691
Krzysztof Piotr Oledzki052d4fd2009-10-04 14:52:57 +02001692 s->fe->counters.failed_req++;
Krzysztof Piotr Oledzkiaeebf9b2009-10-04 15:43:17 +02001693 if (s->listener->counters)
1694 s->listener->counters->failed_req++;
1695
Willy Tarreau84455332009-03-15 22:34:05 +01001696 s->flags |= SN_FINST_R;
1697 }
1698 else if (s->si[1].state == SI_ST_QUE)
1699 s->flags |= SN_FINST_Q;
1700 else if (s->si[1].state < SI_ST_EST)
1701 s->flags |= SN_FINST_C;
Willy Tarreau033b2db2010-03-04 17:54:21 +01001702 else if (s->si[1].state == SI_ST_EST || s->si[1].prev_state == SI_ST_EST)
Willy Tarreau84455332009-03-15 22:34:05 +01001703 s->flags |= SN_FINST_D;
1704 else
1705 s->flags |= SN_FINST_L;
1706 }
1707}
1708
1709/* Handle server-side errors for default protocols. It is called whenever a a
1710 * connection setup is aborted or a request is aborted in queue. It sets the
1711 * session termination flags so that the caller does not have to worry about
1712 * them. It's installed as ->srv_error for the server-side stream_interface.
1713 */
1714void default_srv_error(struct session *s, struct stream_interface *si)
1715{
1716 int err_type = si->err_type;
1717 int err = 0, fin = 0;
1718
1719 if (err_type & SI_ET_QUEUE_ABRT) {
1720 err = SN_ERR_CLICL;
1721 fin = SN_FINST_Q;
1722 }
1723 else if (err_type & SI_ET_CONN_ABRT) {
1724 err = SN_ERR_CLICL;
1725 fin = SN_FINST_C;
1726 }
1727 else if (err_type & SI_ET_QUEUE_TO) {
1728 err = SN_ERR_SRVTO;
1729 fin = SN_FINST_Q;
1730 }
1731 else if (err_type & SI_ET_QUEUE_ERR) {
1732 err = SN_ERR_SRVCL;
1733 fin = SN_FINST_Q;
1734 }
1735 else if (err_type & SI_ET_CONN_TO) {
1736 err = SN_ERR_SRVTO;
1737 fin = SN_FINST_C;
1738 }
1739 else if (err_type & SI_ET_CONN_ERR) {
1740 err = SN_ERR_SRVCL;
1741 fin = SN_FINST_C;
1742 }
1743 else /* SI_ET_CONN_OTHER and others */ {
1744 err = SN_ERR_INTERNAL;
1745 fin = SN_FINST_C;
1746 }
1747
1748 if (!(s->flags & SN_ERR_MASK))
1749 s->flags |= err;
1750 if (!(s->flags & SN_FINST_MASK))
1751 s->flags |= fin;
1752}
Willy Tarreau7c669d72008-06-20 15:04:11 +02001753
Willy Tarreaubaaee002006-06-26 02:48:02 +02001754/*
1755 * Local variables:
1756 * c-indent-level: 8
1757 * c-basic-offset: 8
1758 * End:
1759 */