1 /*
2  * include/types/stick_table.h
3  * Macros, variables and structures for stick tables management.
4  *
5  * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6  * Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation, version 2.1
11  * exclusively.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #ifndef _TYPES_STICK_TABLE_H
24 #define _TYPES_STICK_TABLE_H
25 
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 
29 #include <ebtree.h>
30 #include <ebmbtree.h>
31 #include <eb32tree.h>
32 #include <common/memory.h>
33 #include <types/dict.h>
34 #include <types/freq_ctr.h>
35 #include <types/peers.h>
36 #include <types/sample.h>
37 
38 /* The types of extra data we can store in a stick table */
39 enum {
40 	STKTABLE_DT_SERVER_ID,    /* the server ID to use with this stream if > 0 */
41 	STKTABLE_DT_GPT0,         /* General Purpose Flag 0. */
42 	STKTABLE_DT_GPC0,         /* General Purpose Counter 0 (unsigned 32-bit integer) */
43 	STKTABLE_DT_GPC0_RATE,    /* General Purpose Counter 0's event rate */
44 	STKTABLE_DT_CONN_CNT,     /* cumulated number of connections */
45 	STKTABLE_DT_CONN_RATE,    /* incoming connection rate */
46 	STKTABLE_DT_CONN_CUR,     /* concurrent number of connections */
47 	STKTABLE_DT_SESS_CNT,     /* cumulated number of sessions (accepted connections) */
48 	STKTABLE_DT_SESS_RATE,    /* accepted sessions rate */
49 	STKTABLE_DT_HTTP_REQ_CNT, /* cumulated number of incoming HTTP requests */
50 	STKTABLE_DT_HTTP_REQ_RATE,/* incoming HTTP request rate */
51 	STKTABLE_DT_HTTP_ERR_CNT, /* cumulated number of HTTP requests errors (4xx) */
52 	STKTABLE_DT_HTTP_ERR_RATE,/* HTTP request error rate */
53 	STKTABLE_DT_BYTES_IN_CNT, /* cumulated bytes count from client to servers */
54 	STKTABLE_DT_BYTES_IN_RATE,/* bytes rate from client to servers */
55 	STKTABLE_DT_BYTES_OUT_CNT,/* cumulated bytes count from servers to client */
56 	STKTABLE_DT_BYTES_OUT_RATE,/* bytes rate from servers to client */
57 	STKTABLE_DT_GPC1,         /* General Purpose Counter 1 (unsigned 32-bit integer) */
58 	STKTABLE_DT_GPC1_RATE,    /* General Purpose Counter 1's event rate */
59 	STKTABLE_DT_SERVER_NAME,  /* The server name */
60 	STKTABLE_STATIC_DATA_TYPES,/* number of types above */
61 	/* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always
62 	 * followed by the number of data types, must always be last.
63 	 */
64 	STKTABLE_DATA_TYPES = STKTABLE_STATIC_DATA_TYPES + STKTABLE_EXTRA_DATA_TYPES
65 };
66 
67 /* The equivalent standard types of the stored data */
68 enum {
69 	STD_T_SINT = 0,           /* data is of type signed int */
70 	STD_T_UINT,               /* data is of type unsigned int */
71 	STD_T_ULL,                /* data is of type unsigned long long */
72 	STD_T_FRQP,               /* data is of type freq_ctr_period */
73 	STD_T_DICT,               /* data is of type key of dictionary entry */
74 };
75 
76 /* The types of optional arguments to stored data */
77 enum {
78 	ARG_T_NONE = 0,           /* data type takes no argument (default) */
79 	ARG_T_INT,                /* signed integer */
80 	ARG_T_DELAY,              /* a delay which supports time units */
81 };
82 
83 /* stick_table extra data. This is mainly used for casting or size computation */
84 union stktable_data {
85 	/* standard types for easy casting */
86 	int std_t_sint;
87 	unsigned int std_t_uint;
88 	unsigned long long std_t_ull;
89 	struct freq_ctr_period std_t_frqp;
90 	struct dict_entry *std_t_dict;
91 
92 	/* types of each storable data */
93 	int server_id;
94 	struct dict_entry *server_name;
95 	unsigned int gpt0;
96 	unsigned int gpc0;
97 	struct freq_ctr_period gpc0_rate;
98 	unsigned int gpc1;
99 	struct freq_ctr_period gpc1_rate;
100 	unsigned int conn_cnt;
101 	struct freq_ctr_period conn_rate;
102 	unsigned int conn_cur;
103 	unsigned int sess_cnt;
104 	struct freq_ctr_period sess_rate;
105 	unsigned int http_req_cnt;
106 	struct freq_ctr_period http_req_rate;
107 	unsigned int http_err_cnt;
108 	struct freq_ctr_period http_err_rate;
109 	unsigned long long bytes_in_cnt;
110 	struct freq_ctr_period bytes_in_rate;
111 	unsigned long long bytes_out_cnt;
112 	struct freq_ctr_period bytes_out_rate;
113 };
114 
115 /* known data types */
116 struct stktable_data_type {
117 	const char *name; /* name of the data type */
118 	int std_type;     /* standard type we can use for this data, STD_T_* */
119 	int arg_type;     /* type of optional argument, ARG_T_* */
120 };
121 
122 /* stick table key type flags */
123 #define STK_F_CUSTOM_KEYSIZE      0x00000001   /* this table's key size is configurable */
124 
125 /* stick table keyword type */
126 struct stktable_type {
127 	const char *kw;           /* keyword string */
128 	int flags;                /* type flags */
129 	size_t default_size;      /* default key size */
130 };
131 
132 extern struct stktable_type stktable_types[];
133 
134 /* Sticky session.
135  * Any additional data related to the stuck session is installed *before*
136  * stksess (with negative offsets). This allows us to run variable-sized
137  * keys and variable-sized data without making use of intermediate pointers.
138  */
139 struct stksess {
140 	unsigned int expire;      /* session expiration date */
141 	unsigned int ref_cnt;     /* reference count, can only purge when zero */
142 	__decl_hathreads(HA_RWLOCK_T lock); /* lock related to the table entry */
143 	struct eb32_node exp;     /* ebtree node used to hold the session in expiration tree */
144 	struct eb32_node upd;     /* ebtree node used to hold the update sequence tree */
145 	struct ebmb_node key;     /* ebtree node used to hold the session in table */
146 	/* WARNING! do not put anything after <keys>, it's used by the key */
147 };
148 
149 
150 /* stick table */
151 struct stktable {
152 	char *id;		  /* local table id name. */
153 	char *nid;		  /* table id name sent over the network with peers protocol. */
154 	struct stktable *next;    /* The stick-table may be linked when belonging to
155 	                           * the same configuration section.
156 	                           */
157 	struct {
158 		const char *file;     /* The file where the stick-table is declared. */
159 		int line;             /* The line in this <file> the stick-table is declared. */
160 	} conf;
161 	struct ebpt_node name;    /* Stick-table are lookup by name here. */
162 	struct eb_root keys;      /* head of sticky session tree */
163 	struct eb_root exps;      /* head of sticky session expiration tree */
164 	struct eb_root updates;   /* head of sticky updates sequence tree */
165 	struct pool_head *pool;   /* pool used to allocate sticky sessions */
166 	__decl_hathreads(HA_SPINLOCK_T lock); /* spin lock related to the table */
167 	struct task *exp_task;    /* expiration task */
168 	struct task *sync_task;   /* sync task */
169 	unsigned int update;
170 	unsigned int localupdate;
171 	unsigned int commitupdate;/* used to identify the latest local updates
172 				     pending for sync */
173 	unsigned int refcnt;     /* number of local peer over all peers sections
174 				    attached to this table */
175 	union {
176 		struct peers *p; /* sync peers */
177 		char *name;
178 	} peers;
179 
180 	unsigned long type;       /* type of table (determines key format) */
181 	size_t key_size;          /* size of a key, maximum size in case of string */
182 	unsigned int size;        /* maximum number of sticky sessions in table */
183 	unsigned int current;     /* number of sticky sessions currently in table */
184 	int nopurge;              /* if non-zero, don't purge sticky sessions when full */
185 	int exp_next;             /* next expiration date (ticks) */
186 	int expire;               /* time to live for sticky sessions (milliseconds) */
187 	int data_size;            /* the size of the data that is prepended *before* stksess */
188 	int data_ofs[STKTABLE_DATA_TYPES]; /* negative offsets of present data types, or 0 if absent */
189 	union {
190 		int i;
191 		unsigned int u;
192 		void *p;
193 	} data_arg[STKTABLE_DATA_TYPES]; /* optional argument of each data type */
194 	struct proxy *proxy;      /* The proxy this stick-table is attached to, if any.*/
195 	struct proxy *proxies_list; /* The list of proxies which reference this stick-table. */
196 };
197 
198 extern struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
199 
200 /* stick table key */
201 struct stktable_key {
202 	void *key;                      /* pointer on key buffer */
203 	size_t key_len;                 /* data len to read in buff in case of null terminated string */
204 };
205 
206 /* WARNING: if new fields are added, they must be initialized in stream_accept()
207  * and freed in stream_free() !
208  *
209  * What's the purpose of there two macro:
210  *   - STKCTR_TRACK_BACKEND indicates that a tracking pointer was set from the backend
211  *    and thus that when a keep-alive request goes to another backend, the track
212  *    must cease.
213  *
214  *   - STKCTR_TRACK_CONTENT indicates that the tracking pointer was set in a
215  *    content-aware rule (tcp-request content or http-request) and that the
216  *    tracking has to be performed in the stream and not in the session, and
217  *    will cease for a new keep-alive request over the same connection.
218  */
219 #define STKCTR_TRACK_BACKEND 1
220 #define STKCTR_TRACK_CONTENT 2
221 
222 /* stick counter. The <entry> member is a composite address (caddr) made of a
223  * pointer to an stksess struct, and two flags among STKCTR_TRACK_* above.
224  */
225 struct stkctr {
226 	unsigned long   entry;          /* entry containing counters currently being tracked by this stream  */
227 	struct stktable *table;         /* table the counters above belong to (undefined if counters are null) */
228 };
229 
230 /* parameters to configure tracked counters */
231 struct track_ctr_prm {
232 	struct sample_expr *expr;		/* expression used as the key */
233 	union {
234 		struct stktable *t;		/* a pointer to the table */
235 		char *n;			/* or its name during parsing. */
236 	} table;
237 };
238 
239 #endif /* _TYPES_STICK_TABLE_H */
240