blob: 1ad4f3792f5b674d05933fd8d5b424719aea35a4 [file] [log] [blame]
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02001 -----------------------------------------------
2 Stream Processing Offload Engine (SPOE)
3 Version 1.0
4 ( Last update: 2016-11-07 )
5 -----------------------------------------------
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
19 2.4. Example
20 3. SPOP specification
21 3.1. Data types
22 3.2. Frames
23 3.2.1. Frame capabilities
24 3.2.2. Frame types overview
25 3.2.3. Workflow
26 3.2.4. Frame: HAPROXY-HELLO
27 3.2.5. Frame: AGENT-HELLO
28 3.2.6. Frame: NOTIFY
29 3.2.7. Frame: ACK
30 3.2.8. Frame: HAPROXY-DISCONNECT
31 3.2.9. Frame: AGENT-DISCONNECT
32 3.3. Events & messages
33 3.4. Actions
34 3.5. Error & timeouts
35
36
370. Terms
38---------
39
40* SPOE : Stream Processing Offload Engine.
41
42 A SPOE is a filter talking to servers managed ba a SPOA to offload the
43 stream processing. An engine is attached to a proxy. A proxy can have
44 several engine. Each engine is linked to an agent and only one.
45
46* SPOA : Stream Processing Offload Agent.
47
48 A SPOA is a service that will receive info from a SPOE to offload the
49 stream processing. An agent manages several servers. It uses a backend to
50 reference all of them. By extension, these servers can also be called
51 agents.
52
53* SPOP : Stream Processing Offload Protocol, used by SPOEs to talk to SPOA
54 servers.
55
56 This protocol is used by engines to talk to agents. It is an in-house
57 binary protocol described in this documentation.
58
59
601. Introduction
61----------------
62
63SPOE is a feature introduced in HAProxy 1.7. It makes possible the
64communication with external components to retrieve some info. The idea started
65with the problems caused by most ldap libs not working fine in event-driven
66systems (often at least the connect() is blocking). So, it is hard to properly
67implement Single Sign On solution (SSO) in HAProxy. The SPOE will ease this
68kind of processing, or we hope so.
69
70Now, the aim of SPOE is to allow any kind of offloading on the streams. First
71releases, besides being experimental, won't do lot of things. As we will see,
72there are few handled events and even less actions supported. Actually, for
73now, the SPOE can offload the processing before "tcp-request content",
74"tcp-response content", "http-request" and "http-response" rules. And it only
75supports variables definition. But, in spite of these limited features, we can
76easily imagine to implement SSO solution, ip reputation or ip geolocation
77services.
78
79
802. SPOE configuration
81----------------------
82
83Because SPOE is implemented as a filter, To use it, you must declare a "filter
84spoe" line in a proxy section (frontend/backend/listen) :
85
86 frontend my-front
87 ...
88 filter spoe [engine <name>] config <file>
89 ...
90
91The "config" parameter is mandatory. It specififies the SPOE configuration
92file. The engine name is optional. It can be set to declare the scope to use in
93the SPOE configuration. So it is possible to use the same SPOE configuration
94for several engines. If no name is provided, the SPOE configuration must not
95contain any scope directive.
96
97We use a separate configuration file on purpose. By commenting SPOE filter
98line, you completly disable the feature, including the parsing of sections
99reserved to SPOE. This is also a way to keep the HAProxy configuration clean.
100
101A SPOE configuration file must contains, at least, the SPOA configuration
102("spoe-agent" section) and SPOE messages ("spoe-message" section) attached to
103this agent. Unused messages (not reference in "spoe-agent" section) will be
104ignored.
105
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
117"spoe-message" sections to describe messages sent to servers mananger by your
118SPOA.
119
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 ...
135
136 [my-second-engine]
137 ...
138
139If no engine name is provided on the SPOE filter line, no SPOE scope must be
140found in the SPOE configuration file. All the file is considered to be in the
141same anonymous and implicit scope.
142
1432.2. "spoe-agent" section
144--------------------------
145
146For each engine, you must define one and only one "spoe-agent" section. In this
147section, you will declare SPOE messages and the backend you will use. You will
148also set timeouts and options to customize your agent's behaviour.
149
150
151spoe-agent <name>
152 Create a new SPOA with the name <name>. It must have one and only one
153 "spoe-agent" definition by SPOE scope.
154
155 Arguments :
156 <name> is the name of the agent section.
157
158 following keywords are supported :
159 - messages
160 - option var-prefix
Christopher Faulet03a34492016-11-19 16:47:56 +0100161 - timeout hello|idle|processing
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200162 - use-backend
163
164
165messages <msg-name> ...
166 Declare the list of SPOE messages that an agent will handle.
167
168 Arguments :
169 <msg-name> is the name of a SPOE message.
170
171 Messages declared here must be found in the same engine scope, else an error
172 is triggered during the configuration parsing. You can have many "messages"
173 lines.
174
175 See also: "spoe-message" section.
176
177
178option var-prefix <prefix>
179 Define the prefix used when variables are set by an agent.
180
181 Arguments :
182
183 <prefix> is the prefix used to limit the scope of variables set by an
184 agent.
185
186 To avoid conflict with other variables defined by HAProxy, all variables
187 names will be prefixed. By default, the "spoe-agent" name is used. This
188 option can be used to customize it.
189
190 The prefix will be added between the variable scope and its name, separated
191 by a '.'. It may only contain characters 'a-z', 'A-Z', '0-9', '.' and '_', as
192 for variables name. In HAProxy configuration, you need to use this prefix as
193 a part of the variables name. For example, if an agent define the variable
194 "myvar" in the "txn" scope, with the prefix "my_spoe_pfx", then you should
195 use "txn.my_spoe_pfx.myvar" name in your HAProxy configuration.
196
197 An agent will never set new variables at runtime. It can only set new value
198 for existing ones.
199
200
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200201timeout hello <timeout>
202 Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
Christopher Fauletf7a30922016-11-10 15:04:51 +0100203 It is applied on the stream that handle the connection with the agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200204
205 Arguments :
206 <timeout> is the timeout value specified in milliseconds by default, but
207 can be in any other unit if the number is suffixed by the unit,
208 as explained at the top of this document.
209
210 This timeout is an applicative timeout. It differ from "timeout connect"
211 defined on backends.
212
213
214timeout idle <timeout>
Christopher Fauletf7a30922016-11-10 15:04:51 +0100215 Set the maximum time to wait for an agent to close an idle connection. It is
216 applied on the stream that handle the connection with the agent.
217
218 Arguments :
219 <timeout> is the timeout value specified in milliseconds by default, but
220 can be in any other unit if the number is suffixed by the unit,
221 as explained at the top of this document.
222
223
224timeout processing <timeout>
225 Set the maximum time to wait for a stream to process an event, i.e to acquire
226 a stream to talk with an agent, to encode all messages, to send the NOTIFY
227 frame, to receive the corrsponding acknowledgement and to process all
228 actions. It is applied on the stream that handle the client and the server
229 sessions.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200230
231 Arguments :
232 <timeout> is the timeout value specified in milliseconds by default, but
233 can be in any other unit if the number is suffixed by the unit,
234 as explained at the top of this document.
235
236
237use-backend <backend>
238 Specify the backend to use. It must be defined.
239
240 Arguments :
241 <backend> is the name of a valid "backend" section.
242
243
2442.3. "spoe-message" section
245----------------------------
246
247To offload the stream processing, SPOE will send messages with specific
248information at a specific moment in the stream life and will wait for
249corresponding replies to know what to do.
250
251
252spoe-message <name>
253 Create a new SPOE message with the name <name>.
254
255 Arguments :
256 <name> is the name of the SPOE message.
257
258 Here you define a message that can be referenced in a "spoe-agent"
259 section. Following keywords are supported :
260 - args
261 - event
262
263 See also: "spoe-agent" section.
264
265
266args [name=]<sample> ...
267 Define arguments passed into the SPOE message.
268
269 Arguments :
270 <sample> is a sample expression.
271
272 When the message is processed, if a sample expression is not available, it is
273 set to NULL. Arguments are processed in their declaration order and added in
274 the message in that order. It is possible to declare named arguements.
275
276 For example:
277 args frontend=fe_id src dst
278
279
280event <name>
281 Set the event that triggers sending of the message.
282
283 Argument :
284 <name> is the event name.
285
286 Supported events are:
287 - on-client-session
288 - on-server-connectiob
289 - on-frontend-tcp-request
290 - on-backend-tcp-request
291 - on-tcp-response
292 - on-frontend-http-request
293 - on-backend-http-request
294 - on-http-response
295
296 See section 3.5 about Events.
297
2982.4. Example
299-------------
300
301Here is a simple but complete example that sends client-ip address to a ip
302reputation service. This service can set the variable "ip_score" which is an
303integer between 0 and 100, indicating its reputation (100 means totally safe
304and 0 a blacklisted IP with no doubt).
305
306 ###
307 ### HAProxy configuration
308 frontend www
309 mode http
310 bind *:80
311
312 filter spoe engine ip-reputation config spoe-ip-reputation.conf
313
314 # Reject connection if the IP reputation is under 20
315 tcp-request content reject if { var(sess.iprep.ip_score) -m int lt 20 }
316
317 default_backend http-servers
318
319 backend http-servers
320 mode http
321 server http A.B.C.D:80
322
323 backend iprep-servers
324 mode tcp
325 balance roundrobin
326
327 timeout connect 5s # greater than hello timeout
328 timeout server 3m # greater than idle timeout
329
330 server iprep1 A1.B1.C1.D1:12345
331 server iprep2 A2.B2.C2.D2:12345
332
333 ####
334 ### spoe-ip-reputation.conf
335 [ip-reputation]
336
337 spoe-agent iprep-agent
338 messages get-ip-reputation
339
340 option var-prefix iprep
341
Christopher Faulet03a34492016-11-19 16:47:56 +0100342 timeout hello 2s
343 timeout idle 2m
344 timeout processing 10ms
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200345
346 use-backend iprep-servers
347
348 spoe-message get-ip-reputation
349 args ip=src
350 event on-client-session
351
352
3533. SPOP specification
354----------------------
355
3563.1. Data types
357----------------
358
359Here is the bytewise representation of typed data:
360
361 TYPED-DATA : <TYPE:4 bits><FLAGS:4 bits><DATA>
362
363Supported types and their representation are:
364
365 TYPE | ID | DESCRIPTION
366 -----------------------------+-----+----------------------------------
367 NULL | 0 | NULL : <0>
368 Boolean | 1 | BOOL : <1+FLAG>
369 32bits signed integer | 2 | INT32 : <2><VALUE:varint>
370 32bits unsigned integer | 3 | UINT32 : <3><VALUE:varint>
371 64bits signed integer | 4 | INT64 : <4><VALUE:varint>
372 32bits unsigned integer | 5 | UNIT64 : <5><VALUE:varint>
373 IPV4 | 6 | IPV4 : <6><STRUCT IN_ADDR:4 bytes>
374 IPV6 | 7 | IPV6 : <7><STRUCT IN_ADDR6:16 bytes>
375 String | 8 | STRING : <8><LENGTH:varint><BYTES>
376 Binary | 9 | BINARY : <9><LENGTH:varint><BYTES>
377 10 -> 15 unused/reserved | - | -
378 -----------------------------+-----+----------------------------------
379
380Variable-length integer (varint) are encoded using Peers encoding:
381
382
383 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
384 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
385 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
386 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
387 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
388 ...
389
390For booleans, the value (true or false) is the first bit in the FLAGS
391bitfield. if this bit is set to 0, then the boolean is evaluated as false,
392otherwise, the boolean is evaluated as true.
393
3943.2. Frames
395------------
396
397Exchange between HAProxy and agents are made using FRAME packets. All frames
398must be prefixed with their size encoded on 4 bytes in network byte order:
399
400 <FRAME-LENGTH:4 bytes> <FRAME>
401
402A frame always starts with its type, on one byte, followed by metadata
403containing flags, on 4 bytes and a two variable-length integer representing the
404stream identifier and the frame identifier inside the stream:
405
406 FRAME : <FRAME-TYPE:1 byte> <METADATA> <FRAME-PAYLOAD>
407 METADATA : <FLAGS:4 bytes> <STREAM-ID:varint> <FRAME-ID:varint>
408
409Then comes the frame payload. Depending on the frame type, the payload can be
410of three types: a simple key/value list, a list of messages or a list of
411actions.
412
413 FRAME-PAYLOAD : <LIST-OF-MESSAGES> | <LIST-OF-ACTIONS> | <KV-LIST>
414
415 LIST-OF-MESSAGES : [ <MESSAGE-NAME> <NB-ARGS:1 byte> <KV-LIST> ... ]
416 MESSAGE-NAME : <STRING>
417
418 LIST-OF-ACTIONS : [ <ACTION-TYPE:1 byte> <NB-ARGS:1 byte> <ACTION-ARGS> ... ]
419 ACTION-ARGS : [ <TYPED-DATA>... ]
420
421 KV-LIST : [ <KV-NAME> <KV-VALUE> ... ]
422 KV-NAME : <STRING>
423 KV-VALUE : <TYPED-DATA>
424
425 FLAGS : 0 1-31
426 +---+-----------+
427 | F| |
428 | I| RESERVED |
429 | N| |
430 +--+------------+
431
432 FIN: Indicates that this is the final payload fragment. The first fragment
433 may also be the final fragment.
434
435Frames cannot exceed a maximum size negociated between HAProxy and agents
436during the HELLO handshake. Most of time, payload will be small enough to send
437it in one frame. But when supported by the peer, it will be possible to
438fragment huge payload on many frames. This ability is announced during the
439HELLO handshake and it can be asynmetric (supported by agents but not by
440HAProxy or the opposite). The following rules apply to fragmentation:
441
442 * An unfragemnted payload consists of a single frame with the FIN bit set.
443
444 * A fragemented payload consists of several frames with the FIN bit clear and
445 terminated by a single frame with the FIN bit set. All these frames must
446 share the same STREAM-ID and FRAME-ID. And, of course, the FRAME-TYPE must
447 be the same.
448
449Beside the support of fragmented payload by a peer, some payload must not be
450fragmented. See below for details.
451
452IMPORTANT : The maximum size supported by peers for a frame must be greater or
453equal to 256 bytes.
454
4553.2.1. Frame capabilities
456--------------------------
457
458Here are the list of official capabilities that HAProxy and agents can support:
459
460 * fragmentation: This is the abaility for a peer to support fragmented
461 payload in received frames.
462
463Unsupported or unknown capabilities are silently ignored, when possible.
464
4653.2.2. Frame types overview
466----------------------------
467
468Here are types of frame supported by SPOE. Frames sent by HAProxy come first,
469then frames sent by agents :
470
471 TYPE | ID | DESCRIPTION
472 -----------------------------+-----+-------------------------------------
473 HAPROXY-HELLO | 1 | Sent by HAProxy when it opens a
474 | | connection on an agent.
475 | |
476 HAPROXY-DISCONNECT | 2 | Sent by HAProxy when it want to close
477 | | the connection or in reply to an
478 | | AGENT-DISCONNECT frame
479 | |
480 NOTIFY | 3 | Sent by HAProxy to pass information
481 | | to an agent
482 -----------------------------+-----+-------------------------------------
483 AGENT-HELLO | 101 | Reply to a HAPROXY-HELLO frame, when
484 | | the connection is established
485 | |
486 AGENT-DISCONNECT | 102 | Sent by an agent just before closing
487 | | the connection
488 | |
489 ACK | 103 | Sent to acknowledge a NOTIFY frame
490 -----------------------------+-----+-------------------------------------
491
492Unknown frames may be silently skipped.
493
4943.2.3. Workflow
495----------------
496
497 * Successful HELLO handshake:
498
499 HAPROXY AGENT SRV
500 | HAPROXY-HELLO |
Christopher Fauletba7bc162016-11-07 21:07:38 +0100501 | (healthcheck: false) |
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200502 | --------------------------> |
503 | |
504 | AGENT-HELLO |
505 | <-------------------------- |
506 | |
507
Christopher Fauletba7bc162016-11-07 21:07:38 +0100508 * Successful HELLO healthcheck:
509
510 HAPROXY AGENT SRV
511 | HAPROXY-HELLO |
512 | (healthcheck: true) |
513 | --------------------------> |
514 | |
515 | AGENT-HELLO + close() |
516 | <-------------------------- |
517 | |
518
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200519
520 * Error encountered by agent during the HELLO handshake:
521
522 HAPROXY AGENT SRV
523 | HAPROXY-HELLO |
524 | --------------------------> |
525 | |
526 | DISCONNECT + close() |
527 | <-------------------------- |
528 | |
529
530 * Error encountered by HAProxy during the HELLO handshake:
531
532 HAPROXY AGENT SRV
533 | HAPROXY-HELLO |
534 | --------------------------> |
535 | |
536 | AGENT-HELLO |
537 | <-------------------------- |
538 | |
539 | DISCONNECT |
540 | --------------------------> |
541 | |
542 | DISCONNECT + close() |
543 | <-------------------------- |
544 | |
545
546 * Notify / Ack exchange:
547
548 HAPROXY AGENT SRV
549 | NOTIFY |
550 | --------------------------> |
551 | |
552 | ACK |
553 | <-------------------------- |
554 | |
555
556 * Connection closed by haproxy:
557
558 HAPROXY AGENT SRV
559 | DISCONNECT |
560 | --------------------------> |
561 | |
562 | DISCONNECT + close() |
563 | <-------------------------- |
564 | |
565
566 * Connection closed by agent:
567
568 HAPROXY AGENT SRV
569 | DISCONNECT + close() |
570 | <-------------------------- |
571 | |
572
5733.2.4. Frame: HAPROXY-HELLO
574----------------------------
575
576This frame is the first one exchanged between HAProxy and an agent, when the
577connection is established. The payload of this frame is a KV-LIST. It cannot be
578fragmented. STREAM-ID and FRAME-ID are must be set 0.
579
580Following items are mandatory in the KV-LIST:
581
582 * "supported-versions" <STRING>
583
584 Last SPOP major versions supported by HAProxy. It is a comma-separated list
585 of versions, following the format "Major.Minor". Spaces must be ignored, if
586 any. When a major version is announced by HAProxy, it means it also support
587 all previous minor versions.
588
589 Example: "2.0, 1.5" means HAProxy supports SPOP 2.0 and 1.0 to 1.5
590
591 * "max-frame-size" <UINT32>
592
593 This is the maximum size allowed for a frame. The HAPROXY-HELLO frame must
594 be lower or equal to this value.
595
596 * "capabilities" <STRING>
597
598 This a comma-separated list of capabilities supported by HAProxy. Spaces
599 must be ignored, if any.
600
Christopher Fauletba7bc162016-11-07 21:07:38 +0100601Following optional items can be added in the KV-LIST:
602
603 * "healthcheck" <BOOLEAN>
604
605 If this item is set to TRUE, then the HAPROXY-HELLO frame is sent during a
606 SPOE health check. When set to FALSE, this item can be ignored.
607
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200608To finish the HELLO handshake, the agent must return an AGENT-HELLO frame with
609its supported SPOP version, the lower value between its maximum size allowed
610for a frame and the HAProxy one and capabilities it supports. If an error
611occurs or if an incompatibility is detected with the agent configuration, an
612AGENT-DISCONNECT frame must be returned.
613
6143.2.5. Frame: AGENT-HELLO
615--------------------------
616
617This frame is sent in reply to a HAPROXY-HELLO frame to finish a HELLO
618handshake. As for HAPROXY-HELLO frame, STREAM-ID and FRAME-ID are also set
6190. The payload of this frame is a KV-LIST and it cannot be fragmented.
620
621Following items are mandatory in the KV-LIST:
622
623 * "version" <STRING>
624
625 This is the SPOP version the agent supports. It must follow the format
626 "Major.Minor" and it must be lower or equal than one of major versions
627 announced by HAProxy.
628
629 * "max-frame-size" <UINT32>
630
631 This is the maximum size allowed for a frame. It must be lower or equal to
632 the value in the HAPROXY-HELLO frame. This value will be used for all
633 subsequent frames.
634
635 * "capabilities" <STRING>
636
637 This a comma-separated list of capabilities supported by agent. Spaces must
638 be ignored, if any.
639
640At this time, if everything is ok for HAProxy (supported version and valid
641max-frame-size value), the HELLO handshake is successfully completed. Else,
642HAProxy sends a HAPROXY-DISCONNECT frame with the corresponding error.
643
Christopher Fauletba7bc162016-11-07 21:07:38 +0100644If "healthcheck" item was set to TRUE in the HAPROXY-HELLO frame, the agent can
645safely close the connection without DISCONNECT frame. In all cases, HAProxy
646will close the connexion at the end of the health check.
647
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02006483.2.6. Frame: NOTIFY
649---------------------
650
651Information are sent to the agents inside NOTIFY frames. These frames are
652attached to a stream, so STREAM-ID and FRAME-ID must be set. The payload of
653NOTIFY frames is a LIST-OF-MESSAGES and, if supported by agents, it can be
654fragmented.
655
656NOTIFY frames must be acknowledge by agents sending an ACK frame, repeating
657right STREAM-ID and FRAME-ID.
658
6593.2.7. Frame: ACK
660------------------
661
662ACK frames must be sent by agents to reply to NOTIFY frames. STREAM-ID and
663FRAME-ID found in a NOTIFY frame must be reuse in the corresponding ACK
664frame. The payload of ACK frames is a LIST-OF-ACTIONS and, if supported by
665HAProxy, it can be fragmented.
666
6673.2.8. Frame: HAPROXY-DISCONNECT
668---------------------------------
669
670If an error occurs, at anytime, from the HAProxy side, a HAPROXY-DISCONNECT
671frame is sent with information describing the error. HAProxy will wait an
672AGENT-DISCONNECT frame in reply. All other frames will be ignored. The agent
673must then close the socket.
674
675The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
676FRAME-ID are must be set 0.
677
678Following items are mandatory in the KV-LIST:
679
680 * "status-code" <UINT32>
681
682 This is the code corresponding to the error.
683
684 * "message" <STRING>
685
686 This is a textual message describing the error.
687
688For more information about known errors, see section "Errors & timeouts"
689
6903.2.9. Frame: AGENT-DISCONNECT
691-------------------------------
692
693If an error occurs, at anytime, from the agent size, a AGENT-DISCONNECT frame
694is sent, with information desribing the error. such frame is also sent in reply
695to a HAPROXY-DISCONNECT. The agent must close the socket just after sending
696this frame.
697
698The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
699FRAME-ID are must be set 0.
700
701Following items are mandatory in the KV-LIST:
702
703 * "status-code" <UINT32>
704
705 This is the code corresponding to the error.
706
707 * "message" <STRING>
708
709 This is a textual message describing the error.
710
711For more information about known errors, see section "Errors & timeouts"
712
7133.3. Events & Messages
714-----------------------
715
716Information about streams are sent in NOTIFY frames. You can specify which kind
717of information to send by defining "spoe-message" sections in your SPOE
718configuration file. for each "spoe-message" there will be a message in a NOTIFY
719frame when the right event is triggered.
720
721A NOTIFY frame is sent for an specific event when there is at least one
722"spoe-message" attached to this event. All messages for an event will be added
723in the same NOTIFY frame.
724
725Here is the list of supported events:
726
727 * on-client-session is triggered when a new client session is created.
728 This event is only available for SPOE filters
729 declared in a frontend or a listen section.
730
731 * on-frontend-tcp-request is triggered just before the evaluation of
732 "tcp-request content" rules on the frontend side.
733 This event is only available for SPOE filters
734 declared in a frontend or a listen section.
735
736 * on-backend-tcp-request is triggered just before the evaluation of
737 "tcp-request content" rules on the backend side.
738 This event is skipped for SPOE filters declared
739 in a listen section.
740
741 * on-frontend-http-request is triggered just before the evaluation of
742 "http-request" rules on the frontend side. This
743 event is only available for SPOE filters declared
744 in a frontend or a listen section.
745
746 * on-backend-http-request is triggered just before the evaluation of
747 "http-request" rules on the backend side. This
748 event is skipped for SPOE filters declared in a
749 listen section.
750
751 * on-server-session is triggered when the session with the server is
752 established.
753
754 * on-tcp-response is triggered just before the evaluation of
755 "tcp-response content" rules.
756
757 * on-http-response is triggered just before the evaluation of
758 "http-response" rules.
759
760
761The stream processing will loop on these events, when triggered, waiting the
762agent reply.
763
7643.4. Actions
765-------------
766
767An agent must acknowledge each NOTIFY frame by sending the corresponding ACK
768frame. Actions can be added in these frames to dynamically take action on the
769processing of a stream.
770
771Here is the list of supported actions:
772
773 * set-var set the value for an existing variable. 3 arguments must be
774 attached to this action: the variable scope (proc, sess, txn,
775 req or req), the variable name (a string) and its value.
776
777 ACTION-SET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME><VAR-VALUE>
778
779 SET-VAR : <1>
780 NB-ARGS : <3>
781 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
782 VAR-NAME : <STRING>
783 VAR-VALUE : <TYPED-DATA>
784
785 PROCESS : <0>
786 SESSION : <1>
787 TRANSACTION : <2>
788 REQUEST : <3>
789 RESERVED : <4>
790
791 * unset-var unset the value for an existing variable. 2 arguments must be
792 attached to this action: the variable scope (proc, sess, txn,
793 req or req) and the variable name (a string).
794
795 ACTION-UNSET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME>
796
797 SET-VAR : <1>
798 NB-ARGS : <3>
799 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
800 VAR-NAME : <STRING>
801
802 PROCESS : <0>
803 SESSION : <1>
804 TRANSACTION : <2>
805 REQUEST : <3>
806 RESERVED : <4>
807
808
809NOTE: Name of the variables will be automatically prefixed by HAProxy to avoid
810 name clashes with other variables used in HAProxy. Moreover, unknown
811 variable will be silently ignored.
812
8133.5. Error & timeouts
814----------------------
815
816Here is the list of all known errors:
817
818 STATUS CODE | DESCRIPTION
819 ----------------+--------------------------------------------------------
820 0 | normal (no error occurred)
821 1 | I/O error
822 2 | A timeout occurred
823 3 | frame is too big
824 4 | invalid frame received
825 5 | version value not found
826 6 | max-frame-size value not found
827 7 | capabilities value not found
828 8 | unsupported version
829 9 | max-frame-size too big or too small
830 99 | an unknown error occurrde
831 ----------------+--------------------------------------------------------
832
833An agent can define its own errors using a not yet assigned status code.
834
835IMPORTANT NOTE: For a specific stream, when an abnormal/unexpected error
836 occurs, the SPOE is disabled for all the transaction. So if you
837 have several events configured, such error on an event will
838 disabled all followings. For TCP streams, this will disable the
839 SPOE for the whole session. For HTTP streams, this will disable
840 it for the transaction (request and response).
841
842To avoid a stream to wait infinitly, you must carefully choose the
843acknowledgement timeout. In most of cases, it will be quiet low. But it depends
844on the responsivness of your service.
845
846You must also choose idle timeout carefully. Because connection with your
847service depends on the backend configuration used by the SPOA, it is important
848to use a lower value for idle timeout than the server timeout. Else the
849connection will be closed by HAProxy. The same is true for hello timeout. You
850should choose a lower value than the connect timeout.
851
852
853/*
854 * Local variables:
855 * fill-column: 79
856 * End:
857 */