blob: a6b0ffc27c41d6d2f3f0777a55e86ca86f6d004f [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
35/* Flags set on the SPOE agent */
36#define SPOE_FL_CONT_ON_ERR 0x00000001 /* Do not stop events processing when an error occurred */
37
38/* Flags set on the SPOE context */
39#define SPOE_CTX_FL_CLI_CONNECTED 0x00000001 /* Set after that on-client-session event was processed */
40#define SPOE_CTX_FL_SRV_CONNECTED 0x00000002 /* Set after that on-server-session event was processed */
41#define SPOE_CTX_FL_REQ_PROCESS 0x00000004 /* Set when SPOE is processing the request */
42#define SPOE_CTX_FL_RSP_PROCESS 0x00000008 /* Set when SPOE is processing the response */
43#define SPOE_CTX_FL_FRAGMENTED 0x00000010 /* Set when a fragmented frame is processing */
44
45#define SPOE_CTX_FL_PROCESS (SPOE_CTX_FL_REQ_PROCESS|SPOE_CTX_FL_RSP_PROCESS)
46
47/* Flags set on the SPOE applet */
48#define SPOE_APPCTX_FL_PIPELINING 0x00000001 /* Set if pipelining is supported */
49#define SPOE_APPCTX_FL_ASYNC 0x00000002 /* Set if asynchronus frames is supported */
50#define SPOE_APPCTX_FL_FRAGMENTATION 0x00000004 /* Set if fragmentation is supported */
51#define SPOE_APPCTX_FL_PERSIST 0x00000008 /* Set if the applet is persistent */
52
53#define SPOE_APPCTX_ERR_NONE 0x00000000 /* no error yet, leave it to zero */
54#define SPOE_APPCTX_ERR_TOUT 0x00000001 /* SPOE applet timeout */
55
56/* Flags set on the SPOE frame */
57#define SPOE_FRM_FL_FIN 0x00000001
58#define SPOE_FRM_FL_ABRT 0x00000002
59
60/* All possible states for a SPOE context */
61enum spoe_ctx_state {
62 SPOE_CTX_ST_NONE = 0,
63 SPOE_CTX_ST_READY,
64 SPOE_CTX_ST_ENCODING_MSGS,
65 SPOE_CTX_ST_SENDING_MSGS,
66 SPOE_CTX_ST_WAITING_ACK,
67 SPOE_CTX_ST_DONE,
68 SPOE_CTX_ST_ERROR,
69};
70
71/* All possible states for a SPOE applet */
72enum spoe_appctx_state {
73 SPOE_APPCTX_ST_CONNECT = 0,
74 SPOE_APPCTX_ST_CONNECTING,
75 SPOE_APPCTX_ST_IDLE,
76 SPOE_APPCTX_ST_PROCESSING,
77 SPOE_APPCTX_ST_SENDING_FRAG_NOTIFY,
78 SPOE_APPCTX_ST_WAITING_SYNC_ACK,
79 SPOE_APPCTX_ST_DISCONNECT,
80 SPOE_APPCTX_ST_DISCONNECTING,
81 SPOE_APPCTX_ST_EXIT,
82 SPOE_APPCTX_ST_END,
83};
84
85/* All supported SPOE actions */
86enum spoe_action_type {
87 SPOE_ACT_T_SET_VAR = 1,
88 SPOE_ACT_T_UNSET_VAR,
89 SPOE_ACT_TYPES,
90};
91
92/* All supported SPOE events */
93enum spoe_event {
94 SPOE_EV_NONE = 0,
95
96 /* Request events */
97 SPOE_EV_ON_CLIENT_SESS = 1,
98 SPOE_EV_ON_TCP_REQ_FE,
99 SPOE_EV_ON_TCP_REQ_BE,
100 SPOE_EV_ON_HTTP_REQ_FE,
101 SPOE_EV_ON_HTTP_REQ_BE,
102
103 /* Response events */
104 SPOE_EV_ON_SERVER_SESS,
105 SPOE_EV_ON_TCP_RSP,
106 SPOE_EV_ON_HTTP_RSP,
107
108 SPOE_EV_EVENTS
109};
110
111/* Errors triggered by streams */
112enum spoe_context_error {
113 SPOE_CTX_ERR_NONE = 0,
114 SPOE_CTX_ERR_TOUT,
115 SPOE_CTX_ERR_RES,
116 SPOE_CTX_ERR_TOO_BIG,
117 SPOE_CTX_ERR_FRAG_FRAME_ABRT,
118 SPOE_CTX_ERR_UNKNOWN = 255,
119 SPOE_CTX_ERRS,
120};
121
122/* Errors triggerd by SPOE applet */
123enum spoe_frame_error {
124 SPOE_FRM_ERR_NONE = 0,
125 SPOE_FRM_ERR_IO,
126 SPOE_FRM_ERR_TOUT,
127 SPOE_FRM_ERR_TOO_BIG,
128 SPOE_FRM_ERR_INVALID,
129 SPOE_FRM_ERR_NO_VSN,
130 SPOE_FRM_ERR_NO_FRAME_SIZE,
131 SPOE_FRM_ERR_NO_CAP,
132 SPOE_FRM_ERR_BAD_VSN,
133 SPOE_FRM_ERR_BAD_FRAME_SIZE,
134 SPOE_FRM_ERR_FRAG_NOT_SUPPORTED,
135 SPOE_FRM_ERR_INTERLACED_FRAMES,
136 SPOE_FRM_ERR_FRAMEID_NOTFOUND,
137 SPOE_FRM_ERR_RES,
138 SPOE_FRM_ERR_UNKNOWN = 99,
139 SPOE_FRM_ERRS,
140};
141
142/* Scopes used for variables set by agents. It is a way to be agnotic to vars
143 * scope. */
144enum spoe_vars_scope {
145 SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC */
146 SPOE_SCOPE_SESS, /* <=> SCOPE_SESS */
147 SPOE_SCOPE_TXN, /* <=> SCOPE_TXN */
148 SPOE_SCOPE_REQ, /* <=> SCOPE_REQ */
149 SPOE_SCOPE_RES, /* <=> SCOPE_RES */
150};
151
152
153/* Describe an argument that will be linked to a message. It is a sample fetch,
154 * with an optional name. */
155struct spoe_arg {
156 char *name; /* Name of the argument, may be NULL */
157 unsigned int name_len; /* The name length, 0 if NULL */
158 struct sample_expr *expr; /* Sample expression */
159 struct list list; /* Used to chain SPOE args */
160};
161
162/* Used during the config parsing only because, when a SPOE agent section is
163 * parsed, messages can be undefined. */
164struct spoe_msg_placeholder {
165 char *id; /* SPOE message placeholder id */
166 struct list list; /* Use to chain SPOE message placeholders */
167};
168
169/* Describe a message that will be sent in a NOTIFY frame. A message has a name,
170 * an argument list (see above) and it is linked to a specific event. */
171struct spoe_message {
172 char *id; /* SPOE message id */
173 unsigned int id_len; /* The message id length */
174 struct spoe_agent *agent; /* SPOE agent owning this SPOE message */
175 struct {
176 char *file; /* file where the SPOE message appears */
177 int line; /* line where the SPOE message appears */
178 } conf; /* config information */
179 unsigned int nargs; /* # of arguments */
180 struct list args; /* Arguments added when the SPOE messages is sent */
181 struct list list; /* Used to chain SPOE messages */
182
183 enum spoe_event event; /* SPOE_EV_* */
184};
185
186/* Describe a SPOE agent. */
187struct spoe_agent {
188 char *id; /* SPOE agent id (name) */
189 struct {
190 char *file; /* file where the SPOE agent appears */
191 int line; /* line where the SPOE agent appears */
192 } conf; /* config information */
193 union {
194 struct proxy *be; /* Backend used by this agent */
195 char *name; /* Backend name used during conf parsing */
196 } b;
197 struct {
198 unsigned int hello; /* Max time to receive AGENT-HELLO frame (in SPOE applet) */
199 unsigned int idle; /* Max Idle timeout (in SPOE applet) */
200 unsigned int processing; /* Max time to process an event (in the main stream) */
201 } timeout;
202
203 /* Config info */
204 char *engine_id; /* engine-id string */
205 char *var_pfx; /* Prefix used for vars set by the agent */
206 char *var_on_error; /* Variable to set when an error occurred, in the TXN scope */
207 unsigned int flags; /* SPOE_FL_* */
208 unsigned int cps_max; /* Maximum # of connections per second */
209 unsigned int eps_max; /* Maximum # of errors per second */
210 unsigned int max_frame_size; /* Maximum frame size for this agent, before any negotiation */
211 unsigned int min_applets; /* Minimum # applets alive at a time */
212 unsigned int max_fpa; /* Maximum # of frames handled per applet at once */
213
214 struct list messages[SPOE_EV_EVENTS]; /* List of SPOE messages that will be sent
215 * for each supported events */
216
217 /* running info */
218 unsigned int frame_size; /* current maximum frame size, only used to encode messages */
219 unsigned int applets_act; /* # of applets alive at a time */
220 unsigned int applets_idle; /* # of applets in the state SPOE_APPCTX_ST_IDLE */
221 unsigned int sending_rate; /* the global sending rate */
222
223 struct freq_ctr conn_per_sec; /* connections per second */
224 struct freq_ctr err_per_sec; /* connetion errors per second */
225
226 struct list applets; /* List of available SPOE applets */
227 struct list sending_queue; /* Queue of streams waiting to send data */
228 struct list waiting_queue; /* Queue of streams waiting for a ack, in async mode */
229
230};
231
232/* SPOE filter configuration */
233struct spoe_config {
234 struct proxy *proxy; /* Proxy owning the filter */
235 struct spoe_agent *agent; /* Agent used by this filter */
236 struct proxy agent_fe; /* Agent frontend */
237};
238
239/* SPOE context attached to a stream. It is the main structure that handles the
240 * processing offload */
241struct spoe_context {
242 struct filter *filter; /* The SPOE filter */
243 struct stream *strm; /* The stream that should be offloaded */
244
245 struct list *messages; /* List of messages that will be sent during the stream processing */
246 struct buffer *buffer; /* Buffer used to store a encoded messages */
247 struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
248 struct list list;
249
250 enum spoe_ctx_state state; /* SPOE_CTX_ST_* */
251 unsigned int flags; /* SPOE_CTX_FL_* */
252 unsigned int status_code; /* SPOE_CTX_ERR_* */
253
254 unsigned int stream_id; /* stream_id and frame_id are used */
255 unsigned int frame_id; /* to map NOTIFY and ACK frames */
256 unsigned int process_exp; /* expiration date to process an event */
257
258 struct {
259 struct spoe_appctx *spoe_appctx; /* SPOE appctx sending the fragmented frame */
260 struct spoe_message *curmsg; /* SPOE message from which to resume encoding */
261 struct spoe_arg *curarg; /* SPOE arg in <curmsg> from which to resume encoding */
262 unsigned int curoff; /* offset in <curarg> from which to resume encoding */
263 unsigned int flags; /* SPOE_FRM_FL_* */
264 } frag_ctx; /* Info about fragmented frames, valid on if SPOE_CTX_FL_FRAGMENTED is set */
265};
266
267/* SPOE context inside a appctx */
268struct spoe_appctx {
269 struct appctx *owner; /* the owner */
270 struct task *task; /* task to handle applet timeouts */
271 struct spoe_agent *agent; /* agent on which the applet is attached */
272
273 unsigned int version; /* the negotiated version */
274 unsigned int max_frame_size; /* the negotiated max-frame-size value */
275 unsigned int flags; /* SPOE_APPCTX_FL_* */
276
277 unsigned int status_code; /* SPOE_FRM_ERR_* */
278#if defined(DEBUG_SPOE) || defined(DEBUG_FULL)
279 char *reason; /* Error message, used for debugging only */
280 int rlen; /* reason length */
281#endif
282
283 struct buffer *buffer; /* Buffer used to store a encoded messages */
284 struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */
285 struct list waiting_queue; /* list of streams waiting for a ACK frame, in sync and pipelining mode */
286 struct list list; /* next spoe appctx for the same agent */
287
288 struct {
289 struct spoe_context *ctx; /* SPOE context owning the fragmented frame */
290 unsigned int cursid; /* stream-id of the fragmented frame. used if the processing is aborted */
291 unsigned int curfid; /* frame-id of the fragmented frame. used if the processing is aborted */
292 } frag_ctx; /* Info about fragmented frames, unused for unfragmented frames */
293};
294
295/* Frame Types sent by HAProxy and by agents */
296enum spoe_frame_type {
297 /* Frames sent by HAProxy */
298 SPOE_FRM_T_HAPROXY_HELLO = 1,
299 SPOE_FRM_T_HAPROXY_DISCON,
300 SPOE_FRM_T_HAPROXY_NOTIFY,
301
302 /* Frames sent by the agents */
303 SPOE_FRM_T_AGENT_HELLO = 101,
304 SPOE_FRM_T_AGENT_DISCON,
305 SPOE_FRM_T_AGENT_ACK
306};
307
308/* All supported data types */
309enum spoe_data_type {
310 SPOE_DATA_T_NULL = 0,
311 SPOE_DATA_T_BOOL,
312 SPOE_DATA_T_INT32,
313 SPOE_DATA_T_UINT32,
314 SPOE_DATA_T_INT64,
315 SPOE_DATA_T_UINT64,
316 SPOE_DATA_T_IPV4,
317 SPOE_DATA_T_IPV6,
318 SPOE_DATA_T_STR,
319 SPOE_DATA_T_BIN,
320 SPOE_DATA_TYPES
321};
322
323/* Masks to get data type or flags value */
324#define SPOE_DATA_T_MASK 0x0F
325#define SPOE_DATA_FL_MASK 0xF0
326
327/* Flags to set Boolean values */
328#define SPOE_DATA_FL_FALSE 0x00
329#define SPOE_DATA_FL_TRUE 0x10
330
331
332#endif /* _TYPES_SPOE_H */