blob: 71c7fde90ff56342beb4c7a3fb741ce57f349371 [file] [log] [blame]
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001 -----------------------------------------------
2 Stream Processing Offload Engine (SPOE)
Christopher Faulet57583e42017-09-04 15:41:09 +02003 Version 1.2
Christopher Faulet3b788092020-05-13 08:25:12 +02004 ( Last update: 2020-06-13 )
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02005 -----------------------------------------------
6 Author : Christopher Faulet
7 Contact : cfaulet at haproxy dot com
8
9
10SUMMARY
11--------
12
13 0. Terms
14 1. Introduction
15 2. SPOE configuration
16 2.1. SPOE scope
17 2.2. "spoe-agent" section
18 2.3. "spoe-message" section
Christopher Faulet11610f32017-09-21 10:23:10 +020019 2.4. "spoe-group" section
20 2.5. Example
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020021 3. SPOP specification
22 3.1. Data types
23 3.2. Frames
24 3.2.1. Frame capabilities
25 3.2.2. Frame types overview
26 3.2.3. Workflow
27 3.2.4. Frame: HAPROXY-HELLO
28 3.2.5. Frame: AGENT-HELLO
29 3.2.6. Frame: NOTIFY
30 3.2.7. Frame: ACK
31 3.2.8. Frame: HAPROXY-DISCONNECT
32 3.2.9. Frame: AGENT-DISCONNECT
33 3.3. Events & messages
34 3.4. Actions
Christopher Fauletd1307ce2017-02-27 21:59:39 +010035 3.5. Errors & timeouts
Christopher Fauletb2dd1e02018-03-22 09:07:41 +010036 4. Logging
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020037
38
390. Terms
40---------
41
42* SPOE : Stream Processing Offload Engine.
43
Ilya Shipitsin11057a32020-06-21 21:18:27 +050044 A SPOE is a filter talking to servers managed by a SPOA to offload the
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020045 stream processing. An engine is attached to a proxy. A proxy can have
Christopher Fauletd1307ce2017-02-27 21:59:39 +010046 several engines. Each engine is linked to an agent and only one.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020047
48* SPOA : Stream Processing Offload Agent.
49
50 A SPOA is a service that will receive info from a SPOE to offload the
51 stream processing. An agent manages several servers. It uses a backend to
52 reference all of them. By extension, these servers can also be called
53 agents.
54
55* SPOP : Stream Processing Offload Protocol, used by SPOEs to talk to SPOA
56 servers.
57
58 This protocol is used by engines to talk to agents. It is an in-house
59 binary protocol described in this documentation.
60
61
621. Introduction
63----------------
64
65SPOE is a feature introduced in HAProxy 1.7. It makes possible the
66communication with external components to retrieve some info. The idea started
67with the problems caused by most ldap libs not working fine in event-driven
68systems (often at least the connect() is blocking). So, it is hard to properly
69implement Single Sign On solution (SSO) in HAProxy. The SPOE will ease this
70kind of processing, or we hope so.
71
72Now, the aim of SPOE is to allow any kind of offloading on the streams. First
Christopher Faulet3b788092020-05-13 08:25:12 +020073releases won't do lot of things. As we will see, there are few handled events
74and even less actions supported. Actually, for now, the SPOE can offload the
75processing before "tcp-request content", "tcp-response content", "http-request"
76and "http-response" rules. And it only supports variables definition. But, in
77spite of these limited features, we can easily imagine to implement SSO
78solution, ip reputation or ip geolocation services.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +020079
80
812. SPOE configuration
82----------------------
83
84Because SPOE is implemented as a filter, To use it, you must declare a "filter
85spoe" line in a proxy section (frontend/backend/listen) :
86
87 frontend my-front
88 ...
89 filter spoe [engine <name>] config <file>
90 ...
91
92The "config" parameter is mandatory. It specififies the SPOE configuration
93file. The engine name is optional. It can be set to declare the scope to use in
94the SPOE configuration. So it is possible to use the same SPOE configuration
95for several engines. If no name is provided, the SPOE configuration must not
96contain any scope directive.
97
98We use a separate configuration file on purpose. By commenting SPOE filter
Michael Prokop4438c602019-05-24 10:25:45 +020099line, you completely disable the feature, including the parsing of sections
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200100reserved to SPOE. This is also a way to keep the HAProxy configuration clean.
101
102A SPOE configuration file must contains, at least, the SPOA configuration
Christopher Faulet11610f32017-09-21 10:23:10 +0200103("spoe-agent" section) and SPOE messages/groups ("spoe-message" or "spoe-group"
104sections) attached to this agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200105
106IMPORTANT : The configuration of a SPOE filter must be located in a dedicated
107file. But the backend used by a SPOA must be declared in HAProxy configuration
108file.
109
1102.1. SPOE scope
111-------------------------
112
113If you specify an engine name on the SPOE filter line, then you need to define
114scope in the SPOE configuration with the same name. You can have several SPOE
115scope in the same file. In each scope, you must define one and only one
116"spoe-agent" section to configure the SPOA linked to your SPOE and several
Ilya Shipitsin2a950d02020-03-06 13:07:38 +0500117"spoe-message" and "spoe-group" sections to describe, respectively, messages and
Christopher Faulet11610f32017-09-21 10:23:10 +0200118group of messages sent to servers mananged by your SPOA.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200119
120A SPOE scope starts with this kind of line :
121
122 [<name>]
123
124where <name> is the same engine name specified on the SPOE filter line. The
125scope ends when the file ends or when another scope is found.
126
127 Example :
128 [my-first-engine]
129 spoe-agent my-agent
130 ...
131 spoe-message msg1
132 ...
133 spoe-message msg2
134 ...
Christopher Fauletb2dd1e02018-03-22 09:07:41 +0100135 spoe-group grp1
Christopher Faulet11610f32017-09-21 10:23:10 +0200136 ...
Christopher Fauletb2dd1e02018-03-22 09:07:41 +0100137 spoe-group grp2
138 ...
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200139
140 [my-second-engine]
141 ...
142
143If no engine name is provided on the SPOE filter line, no SPOE scope must be
144found in the SPOE configuration file. All the file is considered to be in the
145same anonymous and implicit scope.
146
Christopher Faulet7ee86672017-09-19 11:08:28 +0200147The engine name must be uniq for a proxy. If no engine name is provided on the
Joseph Herlant71b4b152018-11-13 16:55:16 -0800148SPOE filter line, the SPOE agent name is used by default.
Christopher Faulet7ee86672017-09-19 11:08:28 +0200149
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001502.2. "spoe-agent" section
151--------------------------
152
153For each engine, you must define one and only one "spoe-agent" section. In this
154section, you will declare SPOE messages and the backend you will use. You will
155also set timeouts and options to customize your agent's behaviour.
156
157
158spoe-agent <name>
159 Create a new SPOA with the name <name>. It must have one and only one
160 "spoe-agent" definition by SPOE scope.
161
162 Arguments :
163 <name> is the name of the agent section.
164
165 following keywords are supported :
Christopher Faulet11610f32017-09-21 10:23:10 +0200166 - groups
Christopher Faulet7250b8f2018-03-26 17:19:01 +0200167 - log
Christopher Faulet48026722016-11-16 15:01:12 +0100168 - maxconnrate
169 - maxerrrate
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100170 - max-frame-size
Christopher Faulete8ade382018-01-25 15:32:22 +0100171 - max-waiting-frames
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200172 - messages
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100173 - [no] option async
Christopher Faulet0e0f0852018-03-26 17:20:36 +0200174 - [no] option dontlog-normal
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100175 - [no] option pipelining
176 - [no] option send-frag-payload
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100177 - option continue-on-error
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100178 - option force-set-var
Christopher Faulet985532d2016-11-16 15:36:19 +0100179 - option set-on-error
Christopher Faulet36bda1c2018-03-22 09:08:20 +0100180 - option set-process-time
181 - option set-total-time
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200182 - option var-prefix
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100183 - register-var-names
Christopher Faulet03a34492016-11-19 16:47:56 +0100184 - timeout hello|idle|processing
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200185 - use-backend
186
187
Christopher Faulet11610f32017-09-21 10:23:10 +0200188groups <grp-name> ...
189 Declare the list of SPOE groups that an agent will handle.
190
191 Arguments :
192 <grp-name> is the name of a SPOE group.
193
Joseph Herlant71b4b152018-11-13 16:55:16 -0800194 Groups declared here must be found in the same engine scope, else an error is
Christopher Faulet11610f32017-09-21 10:23:10 +0200195 triggered during the configuration parsing. You can have many "groups" lines.
196
197 See also: "spoe-group" section.
198
199
Christopher Faulet7250b8f2018-03-26 17:19:01 +0200200log global
201log <address> [len <length>] [format <format>] <facility> [<level> [<minlevel>]]
202no log
203 Enable per-instance logging of events and traffic.
204
205 Prefix :
206 no should be used when the logger list must be flushed.
207
208 See the HAProxy Configuration Manual for details about this option.
209
Christopher Faulet48026722016-11-16 15:01:12 +0100210maxconnrate <number>
211 Set the maximum number of connections per second to <number>. The SPOE will
212 stop to open new connections if the maximum is reached and will wait to
213 acquire an existing one. So it is important to set "timeout hello" to a
214 relatively small value.
215
216
217maxerrrate <number>
218 Set the maximum number of errors per second to <number>. The SPOE will stop
219 its processing if the maximum is reached.
220
221
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100222max-frame-size <number>
223 Set the maximum allowed size for frames exchanged between HAProxy and SPOA.
224 It must be in the range [256, tune.bufsize-4] (4 bytes are reserved for the
225 frame length). By default, it is set to (tune.bufsize-4).
226
Christopher Faulete8ade382018-01-25 15:32:22 +0100227max-waiting-frames <number>
228 Set the maximum number of frames waiting for an acknowledgement on the same
229 connection. This value is only used when the pipelinied or asynchronus
230 exchanges between HAProxy and SPOA are enabled. By default, it is set to 20.
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100231
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200232messages <msg-name> ...
233 Declare the list of SPOE messages that an agent will handle.
234
235 Arguments :
236 <msg-name> is the name of a SPOE message.
237
238 Messages declared here must be found in the same engine scope, else an error
239 is triggered during the configuration parsing. You can have many "messages"
240 lines.
241
242 See also: "spoe-message" section.
243
244
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100245option async
246no option async
247 Enable or disable the support of asynchronus exchanges between HAProxy and
248 SPOA. By default, this option is enabled.
249
250
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100251option continue-on-error
252 Do not stop the events processing when an error occurred on a stream.
253
254 By default, for a specific stream, when an abnormal/unexpected error occurs,
255 the SPOE is disabled for all the transaction. So if you have several events
Ilya Shipitsin11057a32020-06-21 21:18:27 +0500256 configured, such error on an event will disabled all following. For TCP
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100257 streams, this will disable the SPOE for the whole session. For HTTP streams,
258 this will disable it for the transaction (request and response).
259
260 When set, this option bypass this behaviour and only the current event will
261 be ignored.
262
Christopher Faulet0e0f0852018-03-26 17:20:36 +0200263
264option dontlog-normal
265no option dontlog-normal
266 Enable or disable logging of normal, successful processing.
267
268 Arguments : none
269
270 See also: "log" and section 4 about logging.
271
272
Etienne Carriereaec89892017-12-14 09:36:40 +0000273option force-set-var
274 By default, SPOE filter only register already known variables (mainly from
275 parsing of the configuration). If you want that haproxy trusts the agent and
276 registers all variables (ex: can be useful for LUA workload), activate this
277 option.
278
279 Caution : this option opens to a variety of attacks such as a rogue SPOA that
280 asks to register too many variables.
281
Christopher Fauletea62c2a2016-11-14 10:54:21 +0100282
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100283option pipelining
284no option pipelining
285 Enable or disable the support of pipelined exchanges between HAProxy and
286 SPOA. By default, this option is enabled.
287
288
289option send-frag-payload
290no option send-frag-payload
291 Enable or disable the sending of fragmented payload to SPOA. By default, this
292 option is enabled.
293
294
Christopher Faulet985532d2016-11-16 15:36:19 +0100295option set-on-error <var name>
296 Define the variable to set when an error occurred during an event processing.
297
298 Arguments :
299
300 <var name> is the variable name, without the scope. The name may only
301 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
302
303 This variable will only be set when an error occurred in the scope of the
304 transaction. As for all other variables define by the SPOE, it will be
305 prefixed. So, if your variable name is "error" and your prefix is
306 "my_spoe_pfx", the variable will be "txn.my_spoe_pfx.error".
307
Christopher Fauletb067b062017-01-04 16:39:11 +0100308 When set, the variable is an integer representing the error reason. For values
309 under 256, it represents an error coming from the engine. Below 256, it
310 reports a SPOP error. In this case, to retrieve the right SPOP status code,
311 you must remove 256 to this value. Here are possible values:
312
313 * 1 a timeout occurred during the event processing.
314
Michael Prokop4438c602019-05-24 10:25:45 +0200315 * 2 an error was triggered during the resources allocation.
Christopher Fauletb067b062017-01-04 16:39:11 +0100316
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100317 * 3 the frame payload exceeds the frame size and it cannot be
318 fragmented.
319
320 * 4 the fragmentation of a payload is aborted.
321
Christopher Faulet344c4ab2017-09-22 10:20:13 +0200322 * 5 The frame processing has been interrupted by HAProxy.
323
Christopher Fauletb067b062017-01-04 16:39:11 +0100324 * 255 an unknown error occurred during the event processing.
325
326 * 256+N a SPOP error occurred during the event processing (see section
327 "Errors & timeouts").
328
329 Note that if "option continue-on-error" is set, the variable is not
330 automatically removed between events processing.
Christopher Faulet985532d2016-11-16 15:36:19 +0100331
332 See also: "option continue-on-error", "option var-prefix".
333
Christopher Faulet36bda1c2018-03-22 09:08:20 +0100334
335option set-process-time <var name>
336 Define the variable to set to report the processing time of the last event or
337 group.
338
339 Arguments :
340
341 <var name> is the variable name, without the scope. The name may only
342 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
343
344 This variable will be set in the scope of the transaction. As for all other
345 variables define by the SPOE, it will be prefixed. So, if your variable name
346 is "process_time" and your prefix is "my_spoe_pfx", the variable will be
347 "txn.my_spoe_pfx.process_time".
348
349 When set, the variable is an integer representing the delay to process the
350 event or the group, in milliseconds. From the stream point of view, it is the
351 latency added by the SPOE processing for the last handled event or group.
352
353 If several events or groups are processed for the same stream, this value
354 will be overrideen.
355
356 See also: "option set-total-time".
357
358
359option set-total-time <var name>
360 Define the variable to set to report the total processing time SPOE for a
361 stream.
362
363 Arguments :
364
365 <var name> is the variable name, without the scope. The name may only
366 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
367
368 This variable will be set in the scope of the transaction. As for all other
369 variables define by the SPOE, it will be prefixed. So, if your variable name
370 is "total_time" and your prefix is "my_spoe_pfx", the variable will be
371 "txn.my_spoe_pfx.total_time".
372
373 When set, the variable is an integer representing the sum of processing times
374 for a stream, in milliseconds. From the stream point of view, it is the
375 latency added by the SPOE processing.
376
377 If several events or groups are processed for the same stream, this value
378 will be updated.
379
380 See also: "option set-process-time".
381
382
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200383option var-prefix <prefix>
384 Define the prefix used when variables are set by an agent.
385
386 Arguments :
387
388 <prefix> is the prefix used to limit the scope of variables set by an
389 agent.
390
391 To avoid conflict with other variables defined by HAProxy, all variables
392 names will be prefixed. By default, the "spoe-agent" name is used. This
393 option can be used to customize it.
394
395 The prefix will be added between the variable scope and its name, separated
396 by a '.'. It may only contain characters 'a-z', 'A-Z', '0-9', '.' and '_', as
397 for variables name. In HAProxy configuration, you need to use this prefix as
398 a part of the variables name. For example, if an agent define the variable
399 "myvar" in the "txn" scope, with the prefix "my_spoe_pfx", then you should
400 use "txn.my_spoe_pfx.myvar" name in your HAProxy configuration.
401
Etienne Carriereaec89892017-12-14 09:36:40 +0000402 By default, an agent will never set new variables at runtime: It can only set
403 new value for existing ones. If you want a different behaviour, see
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100404 force-set-var option and register-var-names directive.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200405
Christopher Faulet336d3ef2017-12-22 10:00:55 +0100406register-var-names <var name> ...
407 Register some variable names. By default, an agent will not be allowed to set
408 new variables at runtime. This rule can be totally relaxed by setting the
409 option "force-set-var". If you know all the variables you will need, this
410 directive is a good way to register them without letting an agent doing what
411 it want. This is only required if these variables are not referenced anywhere
412 in the HAProxy configuration or the SPOE one.
413
414 Arguments:
415 <var name> is a variable name without the scope. The name may only
416 contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
417
418 The prefix will be automatically added during the registration. You can have
419 many "register-var-names" lines.
420
421 See also: "option force-set-var", "option var-prefix".
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200422
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200423timeout hello <timeout>
424 Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
Christopher Fauletf7a30922016-11-10 15:04:51 +0100425 It is applied on the stream that handle the connection with the agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200426
427 Arguments :
428 <timeout> is the timeout value specified in milliseconds by default, but
429 can be in any other unit if the number is suffixed by the unit,
430 as explained at the top of this document.
431
432 This timeout is an applicative timeout. It differ from "timeout connect"
433 defined on backends.
434
435
436timeout idle <timeout>
Christopher Fauletf7a30922016-11-10 15:04:51 +0100437 Set the maximum time to wait for an agent to close an idle connection. It is
438 applied on the stream that handle the connection with the agent.
439
440 Arguments :
441 <timeout> is the timeout value specified in milliseconds by default, but
442 can be in any other unit if the number is suffixed by the unit,
443 as explained at the top of this document.
444
445
446timeout processing <timeout>
447 Set the maximum time to wait for a stream to process an event, i.e to acquire
448 a stream to talk with an agent, to encode all messages, to send the NOTIFY
449 frame, to receive the corrsponding acknowledgement and to process all
450 actions. It is applied on the stream that handle the client and the server
451 sessions.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200452
453 Arguments :
454 <timeout> is the timeout value specified in milliseconds by default, but
455 can be in any other unit if the number is suffixed by the unit,
456 as explained at the top of this document.
457
458
459use-backend <backend>
460 Specify the backend to use. It must be defined.
461
462 Arguments :
463 <backend> is the name of a valid "backend" section.
464
465
4662.3. "spoe-message" section
467----------------------------
468
469To offload the stream processing, SPOE will send messages with specific
470information at a specific moment in the stream life and will wait for
471corresponding replies to know what to do.
472
473
474spoe-message <name>
475 Create a new SPOE message with the name <name>.
476
477 Arguments :
478 <name> is the name of the SPOE message.
479
480 Here you define a message that can be referenced in a "spoe-agent"
481 section. Following keywords are supported :
Christopher Faulet57583e42017-09-04 15:41:09 +0200482 - acl
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200483 - args
484 - event
485
486 See also: "spoe-agent" section.
487
488
Christopher Faulet57583e42017-09-04 15:41:09 +0200489acl <aclname> <criterion> [flags] [operator] <value> ...
Christopher Faulet57583e42017-09-04 15:41:09 +0200490 Declare or complete an access list.
491
492 See section 7 about ACL usage in the HAProxy Configuration Manual.
493
494
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200495args [name=]<sample> ...
496 Define arguments passed into the SPOE message.
497
498 Arguments :
499 <sample> is a sample expression.
500
501 When the message is processed, if a sample expression is not available, it is
502 set to NULL. Arguments are processed in their declaration order and added in
Joseph Herlant71b4b152018-11-13 16:55:16 -0800503 the message in that order. It is possible to declare named arguments.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200504
505 For example:
506 args frontend=fe_id src dst
507
508
Christopher Faulet57583e42017-09-04 15:41:09 +0200509event <name> [ { if | unless } <condition> ]
510 Set the event that triggers sending of the message. It may optionally be
511 followed by an ACL-based condition, in which case it will only be evaluated
512 if the condition is true.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200513
Christopher Faulet57583e42017-09-04 15:41:09 +0200514 ACL-based conditions are executed in the context of the stream that handle
515 the client and the server connections.
516
517 Arguments :
518 <name> is the event name.
519 <condition> is a standard ACL-based condition.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200520
521 Supported events are:
522 - on-client-session
Christopher Faulet1002aac2016-12-09 17:41:54 +0100523 - on-server-session
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200524 - on-frontend-tcp-request
525 - on-backend-tcp-request
526 - on-tcp-response
527 - on-frontend-http-request
528 - on-backend-http-request
529 - on-http-response
530
Christopher Faulet57583e42017-09-04 15:41:09 +0200531 See section "Events & Messages" for more details about supported events.
532 See section 7 about ACL usage in the HAProxy Configuration Manual.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200533
Christopher Faulet11610f32017-09-21 10:23:10 +02005342.4. "spoe-group" section
535--------------------------
536
537This section can be used to declare a group of SPOE messages. Unlike messages
538referenced in a "spoe-agent" section, messages inside a group are not sent on a
539specific event. The sending must be triggered by TCP or HTTP rules, from the
540HAProxy configuration.
541
542
543spoe-group <name>
544 Create a new SPOE group with the name <name>.
545
546 Arguments :
547 <name> is the name of the SPOE group.
548
549 Here you define a group of SPOE messages that can be referenced in a
550 "spoe-agent" section. Following keywords are supported :
551 - messages
552
553 See also: "spoe-agent" and "spoe-message" sections.
554
555
556messages <msg-name> ...
557 Declare the list of SPOE messages belonging to the group.
558
559 Arguments :
560 <msg-name> is the name of a SPOE message.
561
562 Messages declared here must be found in the same engine scope, else an error
563 is triggered during the configuration parsing. Furthermore, a message belongs
564 at most to a group. You can have many "messages" lines.
565
566 See also: "spoe-message" section.
567
568
5692.5. Example
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200570-------------
571
572Here is a simple but complete example that sends client-ip address to a ip
573reputation service. This service can set the variable "ip_score" which is an
574integer between 0 and 100, indicating its reputation (100 means totally safe
575and 0 a blacklisted IP with no doubt).
576
577 ###
578 ### HAProxy configuration
579 frontend www
580 mode http
581 bind *:80
582
583 filter spoe engine ip-reputation config spoe-ip-reputation.conf
584
585 # Reject connection if the IP reputation is under 20
586 tcp-request content reject if { var(sess.iprep.ip_score) -m int lt 20 }
587
588 default_backend http-servers
589
590 backend http-servers
591 mode http
592 server http A.B.C.D:80
593
594 backend iprep-servers
595 mode tcp
596 balance roundrobin
597
598 timeout connect 5s # greater than hello timeout
599 timeout server 3m # greater than idle timeout
600
601 server iprep1 A1.B1.C1.D1:12345
602 server iprep2 A2.B2.C2.D2:12345
603
604 ####
605 ### spoe-ip-reputation.conf
606 [ip-reputation]
607
608 spoe-agent iprep-agent
609 messages get-ip-reputation
610
611 option var-prefix iprep
612
Christopher Faulet03a34492016-11-19 16:47:56 +0100613 timeout hello 2s
614 timeout idle 2m
615 timeout processing 10ms
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200616
617 use-backend iprep-servers
618
619 spoe-message get-ip-reputation
620 args ip=src
Christopher Faulet57583e42017-09-04 15:41:09 +0200621 event on-client-session if ! { src -f /etc/haproxy/whitelist.lst }
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200622
623
6243. SPOP specification
625----------------------
626
6273.1. Data types
628----------------
629
630Here is the bytewise representation of typed data:
631
632 TYPED-DATA : <TYPE:4 bits><FLAGS:4 bits><DATA>
633
634Supported types and their representation are:
635
636 TYPE | ID | DESCRIPTION
637 -----------------------------+-----+----------------------------------
638 NULL | 0 | NULL : <0>
639 Boolean | 1 | BOOL : <1+FLAG>
640 32bits signed integer | 2 | INT32 : <2><VALUE:varint>
641 32bits unsigned integer | 3 | UINT32 : <3><VALUE:varint>
642 64bits signed integer | 4 | INT64 : <4><VALUE:varint>
643 32bits unsigned integer | 5 | UNIT64 : <5><VALUE:varint>
644 IPV4 | 6 | IPV4 : <6><STRUCT IN_ADDR:4 bytes>
645 IPV6 | 7 | IPV6 : <7><STRUCT IN_ADDR6:16 bytes>
646 String | 8 | STRING : <8><LENGTH:varint><BYTES>
647 Binary | 9 | BINARY : <9><LENGTH:varint><BYTES>
648 10 -> 15 unused/reserved | - | -
649 -----------------------------+-----+----------------------------------
650
651Variable-length integer (varint) are encoded using Peers encoding:
652
653
654 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
655 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
656 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
657 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
658 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
659 ...
660
661For booleans, the value (true or false) is the first bit in the FLAGS
662bitfield. if this bit is set to 0, then the boolean is evaluated as false,
663otherwise, the boolean is evaluated as true.
664
6653.2. Frames
666------------
667
668Exchange between HAProxy and agents are made using FRAME packets. All frames
669must be prefixed with their size encoded on 4 bytes in network byte order:
670
671 <FRAME-LENGTH:4 bytes> <FRAME>
672
673A frame always starts with its type, on one byte, followed by metadata
674containing flags, on 4 bytes and a two variable-length integer representing the
675stream identifier and the frame identifier inside the stream:
676
677 FRAME : <FRAME-TYPE:1 byte> <METADATA> <FRAME-PAYLOAD>
678 METADATA : <FLAGS:4 bytes> <STREAM-ID:varint> <FRAME-ID:varint>
679
680Then comes the frame payload. Depending on the frame type, the payload can be
681of three types: a simple key/value list, a list of messages or a list of
682actions.
683
684 FRAME-PAYLOAD : <LIST-OF-MESSAGES> | <LIST-OF-ACTIONS> | <KV-LIST>
685
686 LIST-OF-MESSAGES : [ <MESSAGE-NAME> <NB-ARGS:1 byte> <KV-LIST> ... ]
687 MESSAGE-NAME : <STRING>
688
689 LIST-OF-ACTIONS : [ <ACTION-TYPE:1 byte> <NB-ARGS:1 byte> <ACTION-ARGS> ... ]
690 ACTION-ARGS : [ <TYPED-DATA>... ]
691
692 KV-LIST : [ <KV-NAME> <KV-VALUE> ... ]
693 KV-NAME : <STRING>
694 KV-VALUE : <TYPED-DATA>
695
Thierry FOURNIERc4dcaff2018-05-18 12:25:39 +0200696 FLAGS :
697
698 Flags are a 32 bits field. They are encoded on 4 bytes in network byte
699 order, where the bit 0 is the LSB.
700
701 0 1 2-31
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100702 +---+---+----------+
703 | | A | |
704 | F | B | |
705 | I | O | RESERVED |
706 | N | R | |
707 | | T | |
708 +---+---+----------+
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200709
710 FIN: Indicates that this is the final payload fragment. The first fragment
711 may also be the final fragment.
712
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100713 ABORT: Indicates that the processing of the current frame must be
714 cancelled. This bit should be set on frames with a fragmented
715 payload. It can be ignore for frames with an unfragemnted
716 payload. When it is set, the FIN bit must also be set.
717
718
Joseph Herlant71b4b152018-11-13 16:55:16 -0800719Frames cannot exceed a maximum size negotiated between HAProxy and agents
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200720during the HELLO handshake. Most of time, payload will be small enough to send
721it in one frame. But when supported by the peer, it will be possible to
722fragment huge payload on many frames. This ability is announced during the
723HELLO handshake and it can be asynmetric (supported by agents but not by
724HAProxy or the opposite). The following rules apply to fragmentation:
725
726 * An unfragemnted payload consists of a single frame with the FIN bit set.
727
728 * A fragemented payload consists of several frames with the FIN bit clear and
729 terminated by a single frame with the FIN bit set. All these frames must
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100730 share the same STREAM-ID and FRAME-ID. The first frame must set the right
731 FRAME-TYPE (e.g, NOTIFY). The following frames must have an unset type (0).
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200732
733Beside the support of fragmented payload by a peer, some payload must not be
734fragmented. See below for details.
735
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100736IMPORTANT : The maximum size supported by peers for a frame must be greater
737than or equal to 256 bytes.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200738
7393.2.1. Frame capabilities
740--------------------------
741
742Here are the list of official capabilities that HAProxy and agents can support:
743
Christopher Fauleta1cda022016-12-21 08:58:06 +0100744 * fragmentation: This is the ability for a peer to support fragmented
745 payload in received frames. This is an asymmectical
746 capability, it only concerns the peer that announces
747 it. This is the responsibility to the other peer to use it
748 or not.
749
750 * pipelining: This is the ability for a peer to decouple NOTIFY and ACK
751 frames. This is a symmectical capability. To be used, it must
752 be supported by HAproxy and agents. Unlike HTTP pipelining, the
753 ACK frames can be send in any order, but always on the same TCP
754 connection used for the corresponding NOTIFY frame.
755
756 * async: This ability is similar to the pipelining, but here any TCP
757 connection established between HAProxy and the agent can be used to
758 send ACK frames. if an agent accepts connections from multiple
759 HAProxy, it can use the "engine-id" value to group TCP
760 connections. See details about HAPROXY-HELLO frame.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200761
762Unsupported or unknown capabilities are silently ignored, when possible.
763
Christopher Faulet9536ad72021-03-02 10:05:03 +0100764NOTE: HAProxy does not support the fragmentation for now. This means it is not
765 able to handle fragmented frames. However, if an agent announces the
766 fragmentation support, HAProxy may choose to send fragemented frames.
767
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02007683.2.2. Frame types overview
769----------------------------
770
771Here are types of frame supported by SPOE. Frames sent by HAProxy come first,
772then frames sent by agents :
773
774 TYPE | ID | DESCRIPTION
775 -----------------------------+-----+-------------------------------------
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100776 UNSET | 0 | Used for all frames but the first when a
777 | | payload is fragmented.
778 -----------------------------+-----+-------------------------------------
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200779 HAPROXY-HELLO | 1 | Sent by HAProxy when it opens a
780 | | connection on an agent.
781 | |
782 HAPROXY-DISCONNECT | 2 | Sent by HAProxy when it want to close
783 | | the connection or in reply to an
784 | | AGENT-DISCONNECT frame
785 | |
786 NOTIFY | 3 | Sent by HAProxy to pass information
787 | | to an agent
788 -----------------------------+-----+-------------------------------------
789 AGENT-HELLO | 101 | Reply to a HAPROXY-HELLO frame, when
790 | | the connection is established
791 | |
792 AGENT-DISCONNECT | 102 | Sent by an agent just before closing
793 | | the connection
794 | |
795 ACK | 103 | Sent to acknowledge a NOTIFY frame
796 -----------------------------+-----+-------------------------------------
797
798Unknown frames may be silently skipped.
799
8003.2.3. Workflow
801----------------
802
803 * Successful HELLO handshake:
804
805 HAPROXY AGENT SRV
806 | HAPROXY-HELLO |
Christopher Fauletba7bc162016-11-07 21:07:38 +0100807 | (healthcheck: false) |
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200808 | --------------------------> |
809 | |
810 | AGENT-HELLO |
811 | <-------------------------- |
812 | |
813
Christopher Fauletba7bc162016-11-07 21:07:38 +0100814 * Successful HELLO healthcheck:
815
816 HAPROXY AGENT SRV
817 | HAPROXY-HELLO |
818 | (healthcheck: true) |
819 | --------------------------> |
820 | |
821 | AGENT-HELLO + close() |
822 | <-------------------------- |
823 | |
824
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200825
826 * Error encountered by agent during the HELLO handshake:
827
828 HAPROXY AGENT SRV
829 | HAPROXY-HELLO |
830 | --------------------------> |
831 | |
832 | DISCONNECT + close() |
833 | <-------------------------- |
834 | |
835
836 * Error encountered by HAProxy during the HELLO handshake:
837
838 HAPROXY AGENT SRV
839 | HAPROXY-HELLO |
840 | --------------------------> |
841 | |
842 | AGENT-HELLO |
843 | <-------------------------- |
844 | |
845 | DISCONNECT |
846 | --------------------------> |
847 | |
848 | DISCONNECT + close() |
849 | <-------------------------- |
850 | |
851
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100852 * Notify / Ack exchange (unfragmented payload):
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200853
854 HAPROXY AGENT SRV
855 | NOTIFY |
856 | --------------------------> |
857 | |
858 | ACK |
859 | <-------------------------- |
860 | |
861
Christopher Fauletd1307ce2017-02-27 21:59:39 +0100862 * Notify / Ack exchange (fragmented payload):
863
864 HAPROXY AGENT SRV
865 | NOTIFY (frag 1) |
866 | --------------------------> |
867 | |
868 | UNSET (frag 2) |
869 | --------------------------> |
870 | ... |
871 | UNSET (frag N) |
872 | --------------------------> |
873 | |
874 | ACK |
875 | <-------------------------- |
876 | |
877
878 * Aborted fragmentation of a NOTIFY frame:
879
880 HAPROXY AGENT SRV
881 | ... |
882 | UNSET (frag X) |
883 | --------------------------> |
884 | |
885 | ACK/ABORT |
886 | <-------------------------- |
887 | |
888 | UNSET (frag X+1) |
889 | -----------X |
890 | |
891 | |
892
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200893 * Connection closed by haproxy:
894
895 HAPROXY AGENT SRV
896 | DISCONNECT |
897 | --------------------------> |
898 | |
899 | DISCONNECT + close() |
900 | <-------------------------- |
901 | |
902
903 * Connection closed by agent:
904
905 HAPROXY AGENT SRV
906 | DISCONNECT + close() |
907 | <-------------------------- |
908 | |
909
9103.2.4. Frame: HAPROXY-HELLO
911----------------------------
912
913This frame is the first one exchanged between HAProxy and an agent, when the
914connection is established. The payload of this frame is a KV-LIST. It cannot be
915fragmented. STREAM-ID and FRAME-ID are must be set 0.
916
917Following items are mandatory in the KV-LIST:
918
919 * "supported-versions" <STRING>
920
921 Last SPOP major versions supported by HAProxy. It is a comma-separated list
922 of versions, following the format "Major.Minor". Spaces must be ignored, if
923 any. When a major version is announced by HAProxy, it means it also support
924 all previous minor versions.
925
926 Example: "2.0, 1.5" means HAProxy supports SPOP 2.0 and 1.0 to 1.5
927
928 * "max-frame-size" <UINT32>
929
930 This is the maximum size allowed for a frame. The HAPROXY-HELLO frame must
931 be lower or equal to this value.
932
933 * "capabilities" <STRING>
934
935 This a comma-separated list of capabilities supported by HAProxy. Spaces
936 must be ignored, if any.
937
Christopher Fauletba7bc162016-11-07 21:07:38 +0100938Following optional items can be added in the KV-LIST:
939
940 * "healthcheck" <BOOLEAN>
941
942 If this item is set to TRUE, then the HAPROXY-HELLO frame is sent during a
943 SPOE health check. When set to FALSE, this item can be ignored.
944
Christopher Fauleta1cda022016-12-21 08:58:06 +0100945 * "engine-id" <STRING>
946
947 This is a uniq string that identify a SPOE engine.
948
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200949To finish the HELLO handshake, the agent must return an AGENT-HELLO frame with
950its supported SPOP version, the lower value between its maximum size allowed
951for a frame and the HAProxy one and capabilities it supports. If an error
952occurs or if an incompatibility is detected with the agent configuration, an
953AGENT-DISCONNECT frame must be returned.
954
9553.2.5. Frame: AGENT-HELLO
956--------------------------
957
958This frame is sent in reply to a HAPROXY-HELLO frame to finish a HELLO
959handshake. As for HAPROXY-HELLO frame, STREAM-ID and FRAME-ID are also set
9600. The payload of this frame is a KV-LIST and it cannot be fragmented.
961
962Following items are mandatory in the KV-LIST:
963
964 * "version" <STRING>
965
966 This is the SPOP version the agent supports. It must follow the format
967 "Major.Minor" and it must be lower or equal than one of major versions
968 announced by HAProxy.
969
970 * "max-frame-size" <UINT32>
971
972 This is the maximum size allowed for a frame. It must be lower or equal to
973 the value in the HAPROXY-HELLO frame. This value will be used for all
974 subsequent frames.
975
976 * "capabilities" <STRING>
977
978 This a comma-separated list of capabilities supported by agent. Spaces must
979 be ignored, if any.
980
981At this time, if everything is ok for HAProxy (supported version and valid
982max-frame-size value), the HELLO handshake is successfully completed. Else,
983HAProxy sends a HAPROXY-DISCONNECT frame with the corresponding error.
984
Christopher Fauletba7bc162016-11-07 21:07:38 +0100985If "healthcheck" item was set to TRUE in the HAPROXY-HELLO frame, the agent can
986safely close the connection without DISCONNECT frame. In all cases, HAProxy
Ilya Shipitsin11057a32020-06-21 21:18:27 +0500987will close the connection at the end of the health check.
Christopher Fauletba7bc162016-11-07 21:07:38 +0100988
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02009893.2.6. Frame: NOTIFY
990---------------------
991
992Information are sent to the agents inside NOTIFY frames. These frames are
993attached to a stream, so STREAM-ID and FRAME-ID must be set. The payload of
994NOTIFY frames is a LIST-OF-MESSAGES and, if supported by agents, it can be
995fragmented.
996
997NOTIFY frames must be acknowledge by agents sending an ACK frame, repeating
998right STREAM-ID and FRAME-ID.
999
10003.2.7. Frame: ACK
1001------------------
1002
1003ACK frames must be sent by agents to reply to NOTIFY frames. STREAM-ID and
1004FRAME-ID found in a NOTIFY frame must be reuse in the corresponding ACK
1005frame. The payload of ACK frames is a LIST-OF-ACTIONS and, if supported by
1006HAProxy, it can be fragmented.
1007
10083.2.8. Frame: HAPROXY-DISCONNECT
1009---------------------------------
1010
1011If an error occurs, at anytime, from the HAProxy side, a HAPROXY-DISCONNECT
1012frame is sent with information describing the error. HAProxy will wait an
1013AGENT-DISCONNECT frame in reply. All other frames will be ignored. The agent
1014must then close the socket.
1015
1016The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
1017FRAME-ID are must be set 0.
1018
1019Following items are mandatory in the KV-LIST:
1020
1021 * "status-code" <UINT32>
1022
1023 This is the code corresponding to the error.
1024
1025 * "message" <STRING>
1026
1027 This is a textual message describing the error.
1028
1029For more information about known errors, see section "Errors & timeouts"
1030
10313.2.9. Frame: AGENT-DISCONNECT
1032-------------------------------
1033
1034If an error occurs, at anytime, from the agent size, a AGENT-DISCONNECT frame
Michael Prokop4438c602019-05-24 10:25:45 +02001035is sent, with information describing the error. such frame is also sent in reply
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001036to a HAPROXY-DISCONNECT. The agent must close the socket just after sending
1037this frame.
1038
1039The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
1040FRAME-ID are must be set 0.
1041
1042Following items are mandatory in the KV-LIST:
1043
1044 * "status-code" <UINT32>
1045
1046 This is the code corresponding to the error.
1047
1048 * "message" <STRING>
1049
1050 This is a textual message describing the error.
1051
1052For more information about known errors, see section "Errors & timeouts"
1053
10543.3. Events & Messages
1055-----------------------
1056
1057Information about streams are sent in NOTIFY frames. You can specify which kind
1058of information to send by defining "spoe-message" sections in your SPOE
1059configuration file. for each "spoe-message" there will be a message in a NOTIFY
1060frame when the right event is triggered.
1061
1062A NOTIFY frame is sent for an specific event when there is at least one
1063"spoe-message" attached to this event. All messages for an event will be added
1064in the same NOTIFY frame.
1065
1066Here is the list of supported events:
1067
1068 * on-client-session is triggered when a new client session is created.
1069 This event is only available for SPOE filters
1070 declared in a frontend or a listen section.
1071
1072 * on-frontend-tcp-request is triggered just before the evaluation of
1073 "tcp-request content" rules on the frontend side.
1074 This event is only available for SPOE filters
1075 declared in a frontend or a listen section.
1076
1077 * on-backend-tcp-request is triggered just before the evaluation of
1078 "tcp-request content" rules on the backend side.
1079 This event is skipped for SPOE filters declared
1080 in a listen section.
1081
1082 * on-frontend-http-request is triggered just before the evaluation of
1083 "http-request" rules on the frontend side. This
1084 event is only available for SPOE filters declared
1085 in a frontend or a listen section.
1086
1087 * on-backend-http-request is triggered just before the evaluation of
1088 "http-request" rules on the backend side. This
1089 event is skipped for SPOE filters declared in a
1090 listen section.
1091
1092 * on-server-session is triggered when the session with the server is
1093 established.
1094
1095 * on-tcp-response is triggered just before the evaluation of
1096 "tcp-response content" rules.
1097
1098 * on-http-response is triggered just before the evaluation of
1099 "http-response" rules.
1100
1101
1102The stream processing will loop on these events, when triggered, waiting the
1103agent reply.
1104
11053.4. Actions
1106-------------
1107
1108An agent must acknowledge each NOTIFY frame by sending the corresponding ACK
1109frame. Actions can be added in these frames to dynamically take action on the
1110processing of a stream.
1111
1112Here is the list of supported actions:
1113
1114 * set-var set the value for an existing variable. 3 arguments must be
1115 attached to this action: the variable scope (proc, sess, txn,
Kevin Zhu730323e2018-06-01 05:38:00 +02001116 req or res), the variable name (a string) and its value.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001117
1118 ACTION-SET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME><VAR-VALUE>
1119
1120 SET-VAR : <1>
1121 NB-ARGS : <3>
1122 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
1123 VAR-NAME : <STRING>
1124 VAR-VALUE : <TYPED-DATA>
1125
1126 PROCESS : <0>
1127 SESSION : <1>
1128 TRANSACTION : <2>
1129 REQUEST : <3>
Christopher Fauleta1cda022016-12-21 08:58:06 +01001130 RESPONSE : <4>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001131
1132 * unset-var unset the value for an existing variable. 2 arguments must be
1133 attached to this action: the variable scope (proc, sess, txn,
Kevin Zhu730323e2018-06-01 05:38:00 +02001134 req or res) and the variable name (a string).
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001135
Christopher Faulet1002aac2016-12-09 17:41:54 +01001136 ACTION-UNSET-VAR : <UNSET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001137
Christopher Faulet1002aac2016-12-09 17:41:54 +01001138 UNSET-VAR : <2>
1139 NB-ARGS : <2>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001140 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
1141 VAR-NAME : <STRING>
1142
1143 PROCESS : <0>
1144 SESSION : <1>
1145 TRANSACTION : <2>
1146 REQUEST : <3>
Christopher Fauleta1cda022016-12-21 08:58:06 +01001147 RESPONSE : <4>
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001148
1149
1150NOTE: Name of the variables will be automatically prefixed by HAProxy to avoid
1151 name clashes with other variables used in HAProxy. Moreover, unknown
1152 variable will be silently ignored.
1153
Christopher Fauletd1307ce2017-02-27 21:59:39 +010011543.5. Errors & timeouts
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001155----------------------
1156
1157Here is the list of all known errors:
1158
1159 STATUS CODE | DESCRIPTION
1160 ----------------+--------------------------------------------------------
1161 0 | normal (no error occurred)
1162 1 | I/O error
1163 2 | A timeout occurred
1164 3 | frame is too big
1165 4 | invalid frame received
1166 5 | version value not found
1167 6 | max-frame-size value not found
1168 7 | capabilities value not found
1169 8 | unsupported version
1170 9 | max-frame-size too big or too small
Christopher Fauletd1307ce2017-02-27 21:59:39 +01001171 10 | payload fragmentation is not supported
1172 11 | invalid interlaced frames
1173 12 | frame-id not found (it does not match any referenced frame)
1174 13 | resource allocation error
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001175 99 | an unknown error occurrde
1176 ----------------+--------------------------------------------------------
1177
1178An agent can define its own errors using a not yet assigned status code.
1179
Christopher Fauletea62c2a2016-11-14 10:54:21 +01001180IMPORTANT NOTE: By default, for a specific stream, when an abnormal/unexpected
1181 error occurs, the SPOE is disabled for all the transaction. So
1182 if you have several events configured, such error on an event
Ilya Shipitsin11057a32020-06-21 21:18:27 +05001183 will disabled all following. For TCP streams, this will
Christopher Fauletea62c2a2016-11-14 10:54:21 +01001184 disable the SPOE for the whole session. For HTTP streams, this
1185 will disable it for the transaction (request and response).
1186 See 'option continue-on-error' to bypass this limitation.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001187
Joseph Herlant71b4b152018-11-13 16:55:16 -08001188To avoid a stream to wait undefinetly, you must carefully choose the
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001189acknowledgement timeout. In most of cases, it will be quiet low. But it depends
1190on the responsivness of your service.
1191
1192You must also choose idle timeout carefully. Because connection with your
1193service depends on the backend configuration used by the SPOA, it is important
1194to use a lower value for idle timeout than the server timeout. Else the
1195connection will be closed by HAProxy. The same is true for hello timeout. You
1196should choose a lower value than the connect timeout.
1197
Christopher Fauletb2dd1e02018-03-22 09:07:41 +010011984. Logging
1199-----------
1200
1201Activity of an SPOE is logged using HAProxy's logger. The messages are logged
1202in the context of the streams that handle the client and the server
1203connections. A message is emitted for each event or group handled by an
1204SPOE. Depending on the status code, the log level will be different. In the
1205normal case, when no error occurred, the message is logged with the level
1206LOG_NOTICE. Otherwise, the message is logged with the level LOG_WARNING.
1207
Christopher Faulet3b8e3492018-03-26 17:20:58 +02001208The messages are logged using the agent's logger, if defined, and use the
1209following format:
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001210
Christopher Faulet6e0d5e72018-04-26 14:25:43 +02001211 SPOE: [AGENT] <TYPE:NAME> sid=STREAM-ID st=STATUS-CODE reqT/qT/wT/resT/pT \
Christopher Fauletcaf2fec2018-04-04 10:25:50 +02001212 <idles>/<applets> <nb_sending>/<nb_waiting> <nb_error>/<nb_processed>
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001213
1214 AGENT is the agent name
1215 TYPE is EVENT of GROUP
1216 NAME is the event or the group name
1217 STREAM-ID is an integer, the unique id of the stream
1218 STATUS_CODE is the processing's status code
1219 reqT/qT/wT/resT/pT are the following time events:
1220
1221 * reqT : the encoding time. It includes ACLs processing, if any. For
1222 fragmented frames, it is the sum of all fragments.
1223 * qT : the delay before the request gets out the sending queue. For
1224 fragmented frames, it is the sum of all fragments.
Joseph Herlant71b4b152018-11-13 16:55:16 -08001225 * wT : the delay before the response is received. No fragmentation
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001226 supported here.
1227 * resT : the delay to process the response. No fragmentation supported
Christopher Faulet36bda1c2018-03-22 09:08:20 +01001228 here.
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001229 * pT : the delay to process the event or the group. From the stream
Christopher Faulet36bda1c2018-03-22 09:08:20 +01001230 point of view, it is the latency added by the SPOE processing.
1231 It is more or less the sum of values above.
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001232
Christopher Fauletcaf2fec2018-04-04 10:25:50 +02001233 <idle> is the numbers of idle SPOE applets
1234 <applets> is the numbers of SPOE applets
1235 <nb_sending> is the numbers of streams waiting to send data
1236 <nb_waiting> is the numbers of streams waiting for a ack
1237 <nb_error> is the numbers of processing errors
1238 <nb_processed> is the numbers of events/groups processed
1239
1240
Christopher Fauletb2dd1e02018-03-22 09:07:41 +01001241For all these time events, -1 means the processing was interrupted before the
1242end. So -1 for the queue time means the request was never dequeued. For
1243fragmented frames it is harder to know when the interruption happened.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001244
1245/*
1246 * Local variables:
1247 * fill-column: 79
1248 * End:
1249 */