blob: 108bc980ac875f26f398ee688ed9ee24e2cb47ef [file] [log] [blame]
Christopher Faulet1f40b912017-02-17 09:32:19 +01001/*
2 * include/types/spoe.h
3 * Macros, variables and structures for the SPOE filter.
4 *
5 * Copyright (C) 2017 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com>
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 */
21
22#ifndef _TYPES_SPOE_H
23#define _TYPES_SPOE_H
24
25#include <common/buffer.h>
26#include <common/mini-clist.h>
27
28#include <types/filters.h>
29#include <types/freq_ctr.h>
30#include <types/proxy.h>
31#include <types/sample.h>
32#include <types/stream.h>
33#include <types/task.h>
34
Christopher Fauletc718b822017-09-21 16:50:56 +020035/* Type of list of messages */
36#define SPOE_MSGS_BY_EVENT 0x01
37#define SPOE_MSGS_BY_GROUP 0x02
38
Christopher Faulet1f40b912017-02-17 09:32:19 +010039/* Flags set on the SPOE agent */
40#define SPOE_FL_CONT_ON_ERR 0x00000001 /* Do not stop events processing when an error occurred */
Christopher Faulet305c6072017-02-23 16:17:53 +010041#define SPOE_FL_PIPELINING 0x00000002 /* Set when SPOE agent supports pipelining (set by default) */
42#define SPOE_FL_ASYNC 0x00000004 /* Set when SPOE agent supports async (set by default) */
Christopher Fauletcecd8522017-02-24 22:11:21 +010043#define SPOE_FL_SND_FRAGMENTATION 0x00000008 /* Set when SPOE agent supports sending fragmented payload */
44#define SPOE_FL_RCV_FRAGMENTATION 0x00000010 /* Set when SPOE agent supports receiving fragmented payload */
Christopher Faulet1f40b912017-02-17 09:32:19 +010045
46/* Flags set on the SPOE context */
47#define SPOE_CTX_FL_CLI_CONNECTED 0x00000001 /* Set after that on-client-session event was processed */
48#define SPOE_CTX_FL_SRV_CONNECTED 0x00000002 /* Set after that on-server-session event was processed */
49#define SPOE_CTX_FL_REQ_PROCESS 0x00000004 /* Set when SPOE is processing the request */
50#define SPOE_CTX_FL_RSP_PROCESS 0x00000008 /* Set when SPOE is processing the response */
51#define SPOE_CTX_FL_FRAGMENTED 0x00000010 /* Set when a fragmented frame is processing */
52
53#define SPOE_CTX_FL_PROCESS (SPOE_CTX_FL_REQ_PROCESS|SPOE_CTX_FL_RSP_PROCESS)
54
55/* Flags set on the SPOE applet */
56#define SPOE_APPCTX_FL_PIPELINING 0x00000001 /* Set if pipelining is supported */
57#define SPOE_APPCTX_FL_ASYNC 0x00000002 /* Set if asynchronus frames is supported */
58#define SPOE_APPCTX_FL_FRAGMENTATION 0x00000004 /* Set if fragmentation is supported */
59#define SPOE_APPCTX_FL_PERSIST 0x00000008 /* Set if the applet is persistent */
60
61#define SPOE_APPCTX_ERR_NONE 0x00000000 /* no error yet, leave it to zero */
62#define SPOE_APPCTX_ERR_TOUT 0x00000001 /* SPOE applet timeout */
63
64/* Flags set on the SPOE frame */
65#define SPOE_FRM_FL_FIN 0x00000001
66#define SPOE_FRM_FL_ABRT 0x00000002
67
68/* All possible states for a SPOE context */
69enum spoe_ctx_state {
70 SPOE_CTX_ST_NONE = 0,
71 SPOE_CTX_ST_READY,
72 SPOE_CTX_ST_ENCODING_MSGS,
73 SPOE_CTX_ST_SENDING_MSGS,
74 SPOE_CTX_ST_WAITING_ACK,
75 SPOE_CTX_ST_DONE,
76 SPOE_CTX_ST_ERROR,
77};
78
79/* All possible states for a SPOE applet */
80enum spoe_appctx_state {
81 SPOE_APPCTX_ST_CONNECT = 0,
82 SPOE_APPCTX_ST_CONNECTING,
83 SPOE_APPCTX_ST_IDLE,
84 SPOE_APPCTX_ST_PROCESSING,
85 SPOE_APPCTX_ST_SENDING_FRAG_NOTIFY,
86 SPOE_APPCTX_ST_WAITING_SYNC_ACK,
87 SPOE_APPCTX_ST_DISCONNECT,
88 SPOE_APPCTX_ST_DISCONNECTING,
89 SPOE_APPCTX_ST_EXIT,
90 SPOE_APPCTX_ST_END,
91};
92
93/* All supported SPOE actions */
94enum spoe_action_type {
95 SPOE_ACT_T_SET_VAR = 1,
96 SPOE_ACT_T_UNSET_VAR,
97 SPOE_ACT_TYPES,
98};
99
100/* All supported SPOE events */
101enum spoe_event {
102 SPOE_EV_NONE = 0,
103
104 /* Request events */
105 SPOE_EV_ON_CLIENT_SESS = 1,
106 SPOE_EV_ON_TCP_REQ_FE,
107 SPOE_EV_ON_TCP_REQ_BE,
108 SPOE_EV_ON_HTTP_REQ_FE,
109 SPOE_EV_ON_HTTP_REQ_BE,
110
111 /* Response events */
112 SPOE_EV_ON_SERVER_SESS,
113 SPOE_EV_ON_TCP_RSP,
114 SPOE_EV_ON_HTTP_RSP,
115
116 SPOE_EV_EVENTS
117};
118
119/* Errors triggered by streams */
120enum spoe_context_error {
121 SPOE_CTX_ERR_NONE = 0,
122 SPOE_CTX_ERR_TOUT,
123 SPOE_CTX_ERR_RES,
124 SPOE_CTX_ERR_TOO_BIG,
125 SPOE_CTX_ERR_FRAG_FRAME_ABRT,
Christopher Faulet344c4ab2017-09-22 10:20:13 +0200126 SPOE_CTX_ERR_INTERRUPT,
Christopher Faulet1f40b912017-02-17 09:32:19 +0100127 SPOE_CTX_ERR_UNKNOWN = 255,
128 SPOE_CTX_ERRS,
129};
130
131/* Errors triggerd by SPOE applet */
132enum spoe_frame_error {
133 SPOE_FRM_ERR_NONE = 0,
134 SPOE_FRM_ERR_IO,
135 SPOE_FRM_ERR_TOUT,
136 SPOE_FRM_ERR_TOO_BIG,
137 SPOE_FRM_ERR_INVALID,
138 SPOE_FRM_ERR_NO_VSN,
139 SPOE_FRM_ERR_NO_FRAME_SIZE,
140 SPOE_FRM_ERR_NO_CAP,
141 SPOE_FRM_ERR_BAD_VSN,
142 SPOE_FRM_ERR_BAD_FRAME_SIZE,
143 SPOE_FRM_ERR_FRAG_NOT_SUPPORTED,
144 SPOE_FRM_ERR_INTERLACED_FRAMES,
145 SPOE_FRM_ERR_FRAMEID_NOTFOUND,
146 SPOE_FRM_ERR_RES,
147 SPOE_FRM_ERR_UNKNOWN = 99,
148 SPOE_FRM_ERRS,
149};
150
151/* Scopes used for variables set by agents. It is a way to be agnotic to vars
152 * scope. */
153enum spoe_vars_scope {
154 SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC */
155 SPOE_SCOPE_SESS, /* <=> SCOPE_SESS */
156 SPOE_SCOPE_TXN, /* <=> SCOPE_TXN */
157 SPOE_SCOPE_REQ, /* <=> SCOPE_REQ */
158 SPOE_SCOPE_RES, /* <=> SCOPE_RES */
159};
160
161
162/* Describe an argument that will be linked to a message. It is a sample fetch,
163 * with an optional name. */
164struct spoe_arg {
165 char *name; /* Name of the argument, may be NULL */
166 unsigned int name_len; /* The name length, 0 if NULL */
167 struct sample_expr *expr; /* Sample expression */
168 struct list list; /* Used to chain SPOE args */
169};
170
171/* Used during the config parsing only because, when a SPOE agent section is
Christopher Faulet11610f32017-09-21 10:23:10 +0200172 * parsed, messages/groups can be undefined. */
173struct spoe_placeholder {
174 char *id; /* SPOE placeholder id */
175 struct list list; /* Use to chain SPOE placeholders */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100176};
177
178/* Describe a message that will be sent in a NOTIFY frame. A message has a name,
179 * an argument list (see above) and it is linked to a specific event. */
180struct spoe_message {
Christopher Faulet11610f32017-09-21 10:23:10 +0200181 char *id; /* SPOE message id */
182 unsigned int id_len; /* The message id length */
183 struct spoe_agent *agent; /* SPOE agent owning this SPOE message */
184 struct spoe_group *group; /* SPOE group owning this SPOE message (can be NULL) */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100185 struct {
Christopher Faulet11610f32017-09-21 10:23:10 +0200186 char *file; /* file where the SPOE message appears */
187 int line; /* line where the SPOE message appears */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100188 } conf; /* config information */
Christopher Faulet11610f32017-09-21 10:23:10 +0200189 unsigned int nargs; /* # of arguments */
190 struct list args; /* Arguments added when the SPOE messages is sent */
191 struct list list; /* Used to chain SPOE messages */
192 struct list by_evt; /* By event list */
193 struct list by_grp; /* By group list */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100194
Christopher Faulet11610f32017-09-21 10:23:10 +0200195 struct list acls; /* ACL declared on this message */
196 struct acl_cond *cond; /* acl condition to meet */
197 enum spoe_event event; /* SPOE_EV_* */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100198};
199
Christopher Faulet11610f32017-09-21 10:23:10 +0200200/* Describe a group of messages that will be sent in a NOTIFY frame. A group has
201 * a name and a list of messages. It can be used by HAProxy, outside events
202 * processing, mainly in (tcp|http) rules. */
203struct spoe_group {
204 char *id; /* SPOE group id */
205 struct spoe_agent *agent; /* SPOE agent owning this SPOE group */
206 struct {
207 char *file; /* file where the SPOE group appears */
208 int line; /* line where the SPOE group appears */
209 } conf; /* config information */
210
211 struct list phs; /* List of placeholders used during conf parsing */
212 struct list messages; /* List of SPOE messages that will be sent by this
213 * group */
214
215 struct list list; /* Used to chain SPOE groups */
216};
217
Christopher Faulet1f40b912017-02-17 09:32:19 +0100218/* Describe a SPOE agent. */
219struct spoe_agent {
220 char *id; /* SPOE agent id (name) */
221 struct {
222 char *file; /* file where the SPOE agent appears */
223 int line; /* line where the SPOE agent appears */
224 } conf; /* config information */
225 union {
226 struct proxy *be; /* Backend used by this agent */
227 char *name; /* Backend name used during conf parsing */
228 } b;
229 struct {
230 unsigned int hello; /* Max time to receive AGENT-HELLO frame (in SPOE applet) */
231 unsigned int idle; /* Max Idle timeout (in SPOE applet) */
232 unsigned int processing; /* Max time to process an event (in the main stream) */
233 } timeout;
234
235 /* Config info */
236 char *engine_id; /* engine-id string */
237 char *var_pfx; /* Prefix used for vars set by the agent */
238 char *var_on_error; /* Variable to set when an error occurred, in the TXN scope */
239 unsigned int flags; /* SPOE_FL_* */
240 unsigned int cps_max; /* Maximum # of connections per second */
241 unsigned int eps_max; /* Maximum # of errors per second */
242 unsigned int max_frame_size; /* Maximum frame size for this agent, before any negotiation */
243 unsigned int min_applets; /* Minimum # applets alive at a time */
244 unsigned int max_fpa; /* Maximum # of frames handled per applet at once */
245
Christopher Faulet11610f32017-09-21 10:23:10 +0200246 struct list events[SPOE_EV_EVENTS]; /* List of SPOE messages that will be sent
Christopher Faulet1f40b912017-02-17 09:32:19 +0100247 * for each supported events */
248
Christopher Faulet11610f32017-09-21 10:23:10 +0200249 struct list groups; /* List of available SPOE groups */
250
251 struct list messages; /* list of all messages attached to this SPOE agent */
252
Christopher Faulet1f40b912017-02-17 09:32:19 +0100253 /* running info */
254 unsigned int frame_size; /* current maximum frame size, only used to encode messages */
255 unsigned int applets_act; /* # of applets alive at a time */
256 unsigned int applets_idle; /* # of applets in the state SPOE_APPCTX_ST_IDLE */
257 unsigned int sending_rate; /* the global sending rate */
258
259 struct freq_ctr conn_per_sec; /* connections per second */
260 struct freq_ctr err_per_sec; /* connetion errors per second */
261
262 struct list applets; /* List of available SPOE applets */
263 struct list sending_queue; /* Queue of streams waiting to send data */
264 struct list waiting_queue; /* Queue of streams waiting for a ack, in async mode */
265
266};
267
268/* SPOE filter configuration */
269struct spoe_config {
Christopher Faulet7ee86672017-09-19 11:08:28 +0200270 char *id; /* The SPOE engine name. If undefined in HAProxy config,
271 * it will be set with the SPOE agent name */
Christopher Faulet1f40b912017-02-17 09:32:19 +0100272 struct proxy *proxy; /* Proxy owning the filter */
273 struct spoe_agent *agent; /* Agent used by this filter */
274 struct proxy agent_fe; /* Agent frontend */
275};
276
277/* SPOE context attached to a stream. It is the main structure that handles the
278 * processing offload */
279struct spoe_context {
280 struct filter *filter; /* The SPOE filter */
281 struct stream *strm; /* The stream that should be offloaded */
282
Christopher Faulet11610f32017-09-21 10:23:10 +0200283 struct list *events; /* List of messages that will be sent during the stream processing */
Christopher Faulet76c09ef2017-09-21 11:03:52 +0200284 struct list *groups; /* List of available SPOE group */
Christopher Faulet11610f32017-09-21 10:23:10 +0200285
Christopher Faulet1f40b912017-02-17 09:32:19 +0100286 struct buffer *buffer; /* Buffer used to store a encoded messages */
287 struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
288 struct list list;
289
290 enum spoe_ctx_state state; /* SPOE_CTX_ST_* */
291 unsigned int flags; /* SPOE_CTX_FL_* */
292 unsigned int status_code; /* SPOE_CTX_ERR_* */
293
294 unsigned int stream_id; /* stream_id and frame_id are used */
295 unsigned int frame_id; /* to map NOTIFY and ACK frames */
296 unsigned int process_exp; /* expiration date to process an event */
297
298 struct {
299 struct spoe_appctx *spoe_appctx; /* SPOE appctx sending the fragmented frame */
300 struct spoe_message *curmsg; /* SPOE message from which to resume encoding */
301 struct spoe_arg *curarg; /* SPOE arg in <curmsg> from which to resume encoding */
302 unsigned int curoff; /* offset in <curarg> from which to resume encoding */
303 unsigned int flags; /* SPOE_FRM_FL_* */
304 } frag_ctx; /* Info about fragmented frames, valid on if SPOE_CTX_FL_FRAGMENTED is set */
305};
306
307/* SPOE context inside a appctx */
308struct spoe_appctx {
309 struct appctx *owner; /* the owner */
310 struct task *task; /* task to handle applet timeouts */
311 struct spoe_agent *agent; /* agent on which the applet is attached */
312
313 unsigned int version; /* the negotiated version */
314 unsigned int max_frame_size; /* the negotiated max-frame-size value */
315 unsigned int flags; /* SPOE_APPCTX_FL_* */
316
317 unsigned int status_code; /* SPOE_FRM_ERR_* */
318#if defined(DEBUG_SPOE) || defined(DEBUG_FULL)
319 char *reason; /* Error message, used for debugging only */
320 int rlen; /* reason length */
321#endif
322
323 struct buffer *buffer; /* Buffer used to store a encoded messages */
324 struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
325 struct list waiting_queue; /* list of streams waiting for a ACK frame, in sync and pipelining mode */
326 struct list list; /* next spoe appctx for the same agent */
327
328 struct {
329 struct spoe_context *ctx; /* SPOE context owning the fragmented frame */
330 unsigned int cursid; /* stream-id of the fragmented frame. used if the processing is aborted */
331 unsigned int curfid; /* frame-id of the fragmented frame. used if the processing is aborted */
332 } frag_ctx; /* Info about fragmented frames, unused for unfragmented frames */
333};
334
335/* Frame Types sent by HAProxy and by agents */
336enum spoe_frame_type {
Christopher Fauletf032c3e2017-02-17 15:18:35 +0100337 SPOE_FRM_T_UNSET = 0,
338
Christopher Faulet1f40b912017-02-17 09:32:19 +0100339 /* Frames sent by HAProxy */
340 SPOE_FRM_T_HAPROXY_HELLO = 1,
341 SPOE_FRM_T_HAPROXY_DISCON,
342 SPOE_FRM_T_HAPROXY_NOTIFY,
343
344 /* Frames sent by the agents */
345 SPOE_FRM_T_AGENT_HELLO = 101,
346 SPOE_FRM_T_AGENT_DISCON,
347 SPOE_FRM_T_AGENT_ACK
348};
349
350/* All supported data types */
351enum spoe_data_type {
352 SPOE_DATA_T_NULL = 0,
353 SPOE_DATA_T_BOOL,
354 SPOE_DATA_T_INT32,
355 SPOE_DATA_T_UINT32,
356 SPOE_DATA_T_INT64,
357 SPOE_DATA_T_UINT64,
358 SPOE_DATA_T_IPV4,
359 SPOE_DATA_T_IPV6,
360 SPOE_DATA_T_STR,
361 SPOE_DATA_T_BIN,
362 SPOE_DATA_TYPES
363};
364
365/* Masks to get data type or flags value */
366#define SPOE_DATA_T_MASK 0x0F
367#define SPOE_DATA_FL_MASK 0xF0
368
369/* Flags to set Boolean values */
370#define SPOE_DATA_FL_FALSE 0x00
371#define SPOE_DATA_FL_TRUE 0x10
372
373
374#endif /* _TYPES_SPOE_H */