blob: 5ff22916aef7c90e7c21927f43e261ff92c7856e [file] [log] [blame]
Willy TARREAU3dc06442006-06-15 21:48:13 +02001/*
Willy Tarreau87b09662015-04-03 00:22:06 +02002 * include/proto/stream.h
3 * This file defines everything related to streams.
Willy Tarreau81f9aa32010-06-01 17:45:26 +02004 *
5 * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
Willy TARREAU3dc06442006-06-15 21:48:13 +020021
Willy Tarreau87b09662015-04-03 00:22:06 +020022#ifndef _PROTO_STREAM_H
23#define _PROTO_STREAM_H
Willy Tarreaubaaee002006-06-26 02:48:02 +020024
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020025#include <common/config.h>
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020026#include <common/memory.h>
Willy Tarreau87b09662015-04-03 00:22:06 +020027#include <types/stream.h>
Willy Tarreaua24adf02014-11-27 01:11:56 +010028#include <proto/fd.h>
Willy Tarreau91c43d72010-06-20 11:19:22 +020029#include <proto/freq_ctr.h>
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020030#include <proto/stick_table.h>
Willy Tarreaua24adf02014-11-27 01:11:56 +010031#include <proto/task.h>
Willy TARREAU3dc06442006-06-15 21:48:13 +020032
Willy Tarreau87b09662015-04-03 00:22:06 +020033extern struct pool_head *pool2_stream;
34extern struct list streams;
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020035
Willy Tarreaubc174aa2012-11-19 16:10:32 +010036extern struct data_cb sess_conn_cb;
37
Willy Tarreau73b65ac2015-04-08 18:26:29 +020038struct stream *stream_new(struct session *sess, struct task *t, enum obj_type *origin);
Willy Tarreaubaaee002006-06-26 02:48:02 +020039
Willy Tarreauc6ca1a02007-05-13 19:43:47 +020040/* perform minimal intializations, report 0 in case of error, 1 if OK. */
Willy Tarreau87b09662015-04-03 00:22:06 +020041int init_stream();
Willy Tarreaubaaee002006-06-26 02:48:02 +020042
Willy Tarreaue7dff022015-04-03 01:14:29 +020043/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
Willy Tarreau87b09662015-04-03 00:22:06 +020044void stream_shutdown(struct stream *stream, int why);
Simon Hormandec5be42011-06-08 09:19:07 +090045
Willy Tarreau87b09662015-04-03 00:22:06 +020046void stream_process_counters(struct stream *s);
47void sess_change_server(struct stream *sess, struct server *newsrv);
48struct task *process_stream(struct task *t);
49void default_srv_error(struct stream *s, struct stream_interface *si);
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020050int parse_track_counters(char **args, int *arg,
51 int section_type, struct proxy *curpx,
52 struct track_ctr_prm *prm,
Willy Tarreau0a3dd742012-05-08 19:47:01 +020053 struct proxy *defpx, char **err);
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020054
Willy Tarreau87b09662015-04-03 00:22:06 +020055/* Update the stream's backend and server time stats */
56void stream_update_time_stats(struct stream *s);
Willy Tarreau87b09662015-04-03 00:22:06 +020057void stream_release_buffers(struct stream *s);
Willy Tarreau4bfc5802014-06-17 12:19:18 +020058
Willy Tarreaub1ec8c42015-04-03 13:53:24 +020059/* returns the session this stream belongs to */
60static inline struct session *strm_sess(const struct stream *strm)
61{
62 return strm->sess;
63}
64
Willy Tarreaud0d8da92015-04-04 02:10:38 +020065/* returns the frontend this stream was initiated from */
66static inline struct proxy *strm_fe(const struct stream *strm)
67{
68 return strm->sess->fe;
69}
70
71/* returns the listener this stream was initiated from */
72static inline struct listener *strm_li(const struct stream *strm)
73{
74 return strm->sess->listener;
75}
76
77/* returns a pointer to the origin of the session which created this stream */
78static inline enum obj_type *strm_orig(const struct stream *strm)
79{
80 return strm->sess->origin;
81}
82
Willy Tarreau87b09662015-04-03 00:22:06 +020083/* Remove the refcount from the stream to the tracked counters, and clear the
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020084 * pointer to ensure this is only performed once. The caller is responsible for
Willy Tarreaua68f7622015-09-21 17:48:24 +020085 * ensuring that the pointer is valid first. We must be extremely careful not
86 * to touch the entries we inherited from the session.
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020087 */
Willy Tarreau87b09662015-04-03 00:22:06 +020088static inline void stream_store_counters(struct stream *s)
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +020089{
Willy Tarreauf059a0f2010-08-03 16:29:52 +020090 void *ptr;
Willy Tarreau20d46a52012-12-09 15:55:40 +010091 int i;
Willy Tarreauf059a0f2010-08-03 16:29:52 +020092
Willy Tarreaub4c84932013-07-23 19:15:30 +020093 for (i = 0; i < MAX_SESS_STKCTR; i++) {
Willy Tarreaucc08d2c2014-01-28 23:18:23 +010094 if (!stkctr_entry(&s->stkctr[i]))
Willy Tarreau20d46a52012-12-09 15:55:40 +010095 continue;
Willy Tarreaua68f7622015-09-21 17:48:24 +020096
97 if (stkctr_entry(&s->sess->stkctr[i]))
98 continue;
99
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100100 ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_CONN_CUR);
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200101 if (ptr)
102 stktable_data_cast(ptr, conn_cur)--;
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100103 stkctr_entry(&s->stkctr[i])->ref_cnt--;
104 stksess_kill_if_expired(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]));
105 stkctr_set_entry(&s->stkctr[i], NULL);
Willy Tarreau38285c12010-06-18 16:35:43 +0200106 }
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +0200107}
108
Willy Tarreau87b09662015-04-03 00:22:06 +0200109/* Remove the refcount from the stream counters tracked at the content level if
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200110 * any, and clear the pointer to ensure this is only performed once. The caller
Willy Tarreaua68f7622015-09-21 17:48:24 +0200111 * is responsible for ensuring that the pointer is valid first. We must be
112 * extremely careful not to touch the entries we inherited from the session.
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +0200113 */
Willy Tarreau87b09662015-04-03 00:22:06 +0200114static inline void stream_stop_content_counters(struct stream *s)
Willy Tarreau9ba2dcc2010-06-14 21:04:55 +0200115{
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200116 void *ptr;
Willy Tarreau20d46a52012-12-09 15:55:40 +0100117 int i;
Willy Tarreaue3487932010-06-18 21:03:20 +0200118
Willy Tarreaub4c84932013-07-23 19:15:30 +0200119 for (i = 0; i < MAX_SESS_STKCTR; i++) {
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100120 if (!stkctr_entry(&s->stkctr[i]))
Willy Tarreau20d46a52012-12-09 15:55:40 +0100121 continue;
Willy Tarreau0a4838c2010-08-06 20:11:05 +0200122
Willy Tarreaua68f7622015-09-21 17:48:24 +0200123 if (stkctr_entry(&s->sess->stkctr[i]))
124 continue;
125
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100126 if (!(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_CONTENT))
Willy Tarreau20d46a52012-12-09 15:55:40 +0100127 continue;
128
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100129 ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_CONN_CUR);
Willy Tarreau0a4838c2010-08-06 20:11:05 +0200130 if (ptr)
131 stktable_data_cast(ptr, conn_cur)--;
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100132 stkctr_entry(&s->stkctr[i])->ref_cnt--;
133 stksess_kill_if_expired(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]));
134 stkctr_set_entry(&s->stkctr[i], NULL);
Willy Tarreau0a4838c2010-08-06 20:11:05 +0200135 }
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200136}
Willy Tarreaue3487932010-06-18 21:03:20 +0200137
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200138/* Increase total and concurrent connection count for stick entry <ts> of table
139 * <t>. The caller is responsible for ensuring that <t> and <ts> are valid
140 * pointers, and for calling this only once per connection.
141 */
Willy Tarreau87b09662015-04-03 00:22:06 +0200142static inline void stream_start_counters(struct stktable *t, struct stksess *ts)
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200143{
144 void *ptr;
Willy Tarreau91c43d72010-06-20 11:19:22 +0200145
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200146 ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CUR);
147 if (ptr)
148 stktable_data_cast(ptr, conn_cur)++;
149
150 ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_CNT);
151 if (ptr)
152 stktable_data_cast(ptr, conn_cnt)++;
153
154 ptr = stktable_data_ptr(t, ts, STKTABLE_DT_CONN_RATE);
155 if (ptr)
156 update_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
157 t->data_arg[STKTABLE_DT_CONN_RATE].u, 1);
158 if (tick_isset(t->expire))
159 ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire));
160}
161
Willy Tarreau87b09662015-04-03 00:22:06 +0200162/* Enable tracking of stream counters as <stkctr> on stksess <ts>. The caller is
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200163 * responsible for ensuring that <t> and <ts> are valid pointers. Some controls
164 * are performed to ensure the state can still change.
165 */
Willy Tarreau87b09662015-04-03 00:22:06 +0200166static inline void stream_track_stkctr(struct stkctr *ctr, struct stktable *t, struct stksess *ts)
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200167{
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100168 if (stkctr_entry(ctr))
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200169 return;
170
171 ts->ref_cnt++;
Willy Tarreau20d46a52012-12-09 15:55:40 +0100172 ctr->table = t;
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100173 stkctr_set_entry(ctr, ts);
Willy Tarreau87b09662015-04-03 00:22:06 +0200174 stream_start_counters(t, ts);
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200175}
176
Willy Tarreauda7ff642010-06-23 11:44:09 +0200177/* Increase the number of cumulated HTTP requests in the tracked counters */
Willy Tarreau87b09662015-04-03 00:22:06 +0200178static void inline stream_inc_http_req_ctr(struct stream *s)
Willy Tarreauda7ff642010-06-23 11:44:09 +0200179{
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200180 void *ptr;
Willy Tarreau20d46a52012-12-09 15:55:40 +0100181 int i;
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200182
Willy Tarreaub4c84932013-07-23 19:15:30 +0200183 for (i = 0; i < MAX_SESS_STKCTR; i++) {
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200184 struct stkctr *stkctr = &s->stkctr[i];
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200185
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200186 if (!stkctr_entry(stkctr)) {
187 stkctr = &s->sess->stkctr[i];
188 if (!stkctr_entry(stkctr))
189 continue;
190 }
191
192 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200193 if (ptr)
194 stktable_data_cast(ptr, http_req_cnt)++;
195
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200196 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200197 if (ptr)
198 update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200199 stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200200 }
201}
202
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200203/* Increase the number of cumulated HTTP requests in the backend's tracked
204 * counters. We don't look up the session since it cannot happen in the bakcend.
205 */
Willy Tarreau87b09662015-04-03 00:22:06 +0200206static void inline stream_inc_be_http_req_ctr(struct stream *s)
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100207{
208 void *ptr;
Willy Tarreau20d46a52012-12-09 15:55:40 +0100209 int i;
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100210
Willy Tarreaub4c84932013-07-23 19:15:30 +0200211 for (i = 0; i < MAX_SESS_STKCTR; i++) {
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200212 struct stkctr *stkctr = &s->stkctr[i];
213
214 if (!stkctr_entry(stkctr))
Willy Tarreau20d46a52012-12-09 15:55:40 +0100215 continue;
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100216
Willy Tarreaucc08d2c2014-01-28 23:18:23 +0100217 if (!(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_BACKEND))
Willy Tarreau20d46a52012-12-09 15:55:40 +0100218 continue;
219
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200220 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100221 if (ptr)
222 stktable_data_cast(ptr, http_req_cnt)++;
223
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200224 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100225 if (ptr)
226 update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200227 stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
Willy Tarreau5d5b5d82012-12-09 12:00:04 +0100228 }
229}
230
Willy Tarreauda7ff642010-06-23 11:44:09 +0200231/* Increase the number of cumulated failed HTTP requests in the tracked
232 * counters. Only 4xx requests should be counted here so that we can
233 * distinguish between errors caused by client behaviour and other ones.
234 * Note that even 404 are interesting because they're generally caused by
235 * vulnerability scans.
236 */
Willy Tarreau87b09662015-04-03 00:22:06 +0200237static void inline stream_inc_http_err_ctr(struct stream *s)
Willy Tarreauda7ff642010-06-23 11:44:09 +0200238{
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200239 void *ptr;
Willy Tarreau20d46a52012-12-09 15:55:40 +0100240 int i;
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200241
Willy Tarreaub4c84932013-07-23 19:15:30 +0200242 for (i = 0; i < MAX_SESS_STKCTR; i++) {
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200243 struct stkctr *stkctr = &s->stkctr[i];
Willy Tarreauf059a0f2010-08-03 16:29:52 +0200244
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200245 if (!stkctr_entry(stkctr)) {
246 stkctr = &s->sess->stkctr[i];
247 if (!stkctr_entry(stkctr))
248 continue;
249 }
250
251 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200252 if (ptr)
253 stktable_data_cast(ptr, http_err_cnt)++;
254
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200255 ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200256 if (ptr)
257 update_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
Willy Tarreau8b7f8682015-04-04 16:29:12 +0200258 stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
Willy Tarreauda7ff642010-06-23 11:44:09 +0200259 }
260}
261
Willy Tarreau87b09662015-04-03 00:22:06 +0200262static void inline stream_add_srv_conn(struct stream *sess, struct server *srv)
Simon Hormanaf514952011-06-21 14:34:57 +0900263{
264 sess->srv_conn = srv;
265 LIST_ADD(&srv->actconns, &sess->by_srv);
266}
267
Willy Tarreau87b09662015-04-03 00:22:06 +0200268static void inline stream_del_srv_conn(struct stream *sess)
Simon Hormanaf514952011-06-21 14:34:57 +0900269{
270 if (!sess->srv_conn)
271 return;
272
273 sess->srv_conn = NULL;
274 LIST_DEL(&sess->by_srv);
275}
276
Willy Tarreau87b09662015-04-03 00:22:06 +0200277static void inline stream_init_srv_conn(struct stream *sess)
Willy Tarreau9bd0d742011-07-20 00:17:39 +0200278{
279 sess->srv_conn = NULL;
280 LIST_INIT(&sess->by_srv);
281}
282
Christopher Fauleta73e59b2016-12-09 17:30:18 +0100283/* Callback used to wake up a stream when a buffer is available. The stream <s>
284 * is woken up is if it is not already running and if it is not already in the
285 * task run queue. This functions returns 1 is the stream is woken up, otherwise
286 * it returns 0. */
287static int inline stream_res_wakeup(struct stream *s)
Willy Tarreaua24adf02014-11-27 01:11:56 +0100288{
Emeric Brunff449172017-03-31 12:04:09 +0200289 if (s->task->state & TASK_RUNNING)
Christopher Fauleta73e59b2016-12-09 17:30:18 +0100290 return 0;
291 task_wakeup(s->task, TASK_WOKEN_RES);
292 return 1;
Willy Tarreaua24adf02014-11-27 01:11:56 +0100293}
294
Thierry FOURNIER5a363e72015-09-27 19:29:33 +0200295void service_keywords_register(struct action_kw_list *kw_list);
296
Willy Tarreau87b09662015-04-03 00:22:06 +0200297#endif /* _PROTO_STREAM_H */
Willy TARREAU3dc06442006-06-15 21:48:13 +0200298
Willy Tarreaubaaee002006-06-26 02:48:02 +0200299/*
300 * Local variables:
301 * c-indent-level: 8
302 * c-basic-offset: 8
303 * End:
304 */