blob: f9aac7108ea814c76d899c488b32fd6f1bc56da4 [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 Fauletf7a30922016-11-10 15:04:51 +0100161 - timeout hello|idle|ack|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
201timeout ack <timeout>
202 Set the maximum time to wait for an agent to receive the acknowledgement to a
Christopher Fauletf7a30922016-11-10 15:04:51 +0100203 NOTIFY frame. It is applied on the stream that handle the connection with the
204 agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200205
206 Arguments :
207 <timeout> is the timeout value specified in milliseconds by default, but
208 can be in any other unit if the number is suffixed by the unit,
209 as explained at the top of this document.
210
211
212timeout hello <timeout>
213 Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
Christopher Fauletf7a30922016-11-10 15:04:51 +0100214 It is applied on the stream that handle the connection with the agent.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200215
216 Arguments :
217 <timeout> is the timeout value specified in milliseconds by default, but
218 can be in any other unit if the number is suffixed by the unit,
219 as explained at the top of this document.
220
221 This timeout is an applicative timeout. It differ from "timeout connect"
222 defined on backends.
223
224
225timeout idle <timeout>
Christopher Fauletf7a30922016-11-10 15:04:51 +0100226 Set the maximum time to wait for an agent to close an idle connection. It is
227 applied on the stream that handle the connection with the agent.
228
229 Arguments :
230 <timeout> is the timeout value specified in milliseconds by default, but
231 can be in any other unit if the number is suffixed by the unit,
232 as explained at the top of this document.
233
234
235timeout processing <timeout>
236 Set the maximum time to wait for a stream to process an event, i.e to acquire
237 a stream to talk with an agent, to encode all messages, to send the NOTIFY
238 frame, to receive the corrsponding acknowledgement and to process all
239 actions. It is applied on the stream that handle the client and the server
240 sessions.
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200241
242 Arguments :
243 <timeout> is the timeout value specified in milliseconds by default, but
244 can be in any other unit if the number is suffixed by the unit,
245 as explained at the top of this document.
246
247
248use-backend <backend>
249 Specify the backend to use. It must be defined.
250
251 Arguments :
252 <backend> is the name of a valid "backend" section.
253
254
2552.3. "spoe-message" section
256----------------------------
257
258To offload the stream processing, SPOE will send messages with specific
259information at a specific moment in the stream life and will wait for
260corresponding replies to know what to do.
261
262
263spoe-message <name>
264 Create a new SPOE message with the name <name>.
265
266 Arguments :
267 <name> is the name of the SPOE message.
268
269 Here you define a message that can be referenced in a "spoe-agent"
270 section. Following keywords are supported :
271 - args
272 - event
273
274 See also: "spoe-agent" section.
275
276
277args [name=]<sample> ...
278 Define arguments passed into the SPOE message.
279
280 Arguments :
281 <sample> is a sample expression.
282
283 When the message is processed, if a sample expression is not available, it is
284 set to NULL. Arguments are processed in their declaration order and added in
285 the message in that order. It is possible to declare named arguements.
286
287 For example:
288 args frontend=fe_id src dst
289
290
291event <name>
292 Set the event that triggers sending of the message.
293
294 Argument :
295 <name> is the event name.
296
297 Supported events are:
298 - on-client-session
299 - on-server-connectiob
300 - on-frontend-tcp-request
301 - on-backend-tcp-request
302 - on-tcp-response
303 - on-frontend-http-request
304 - on-backend-http-request
305 - on-http-response
306
307 See section 3.5 about Events.
308
3092.4. Example
310-------------
311
312Here is a simple but complete example that sends client-ip address to a ip
313reputation service. This service can set the variable "ip_score" which is an
314integer between 0 and 100, indicating its reputation (100 means totally safe
315and 0 a blacklisted IP with no doubt).
316
317 ###
318 ### HAProxy configuration
319 frontend www
320 mode http
321 bind *:80
322
323 filter spoe engine ip-reputation config spoe-ip-reputation.conf
324
325 # Reject connection if the IP reputation is under 20
326 tcp-request content reject if { var(sess.iprep.ip_score) -m int lt 20 }
327
328 default_backend http-servers
329
330 backend http-servers
331 mode http
332 server http A.B.C.D:80
333
334 backend iprep-servers
335 mode tcp
336 balance roundrobin
337
338 timeout connect 5s # greater than hello timeout
339 timeout server 3m # greater than idle timeout
340
341 server iprep1 A1.B1.C1.D1:12345
342 server iprep2 A2.B2.C2.D2:12345
343
344 ####
345 ### spoe-ip-reputation.conf
346 [ip-reputation]
347
348 spoe-agent iprep-agent
349 messages get-ip-reputation
350
351 option var-prefix iprep
352
353 timeout hello 2s
354 timeout ack 10ms
355 timeout idle 2m
356
357 use-backend iprep-servers
358
359 spoe-message get-ip-reputation
360 args ip=src
361 event on-client-session
362
363
3643. SPOP specification
365----------------------
366
3673.1. Data types
368----------------
369
370Here is the bytewise representation of typed data:
371
372 TYPED-DATA : <TYPE:4 bits><FLAGS:4 bits><DATA>
373
374Supported types and their representation are:
375
376 TYPE | ID | DESCRIPTION
377 -----------------------------+-----+----------------------------------
378 NULL | 0 | NULL : <0>
379 Boolean | 1 | BOOL : <1+FLAG>
380 32bits signed integer | 2 | INT32 : <2><VALUE:varint>
381 32bits unsigned integer | 3 | UINT32 : <3><VALUE:varint>
382 64bits signed integer | 4 | INT64 : <4><VALUE:varint>
383 32bits unsigned integer | 5 | UNIT64 : <5><VALUE:varint>
384 IPV4 | 6 | IPV4 : <6><STRUCT IN_ADDR:4 bytes>
385 IPV6 | 7 | IPV6 : <7><STRUCT IN_ADDR6:16 bytes>
386 String | 8 | STRING : <8><LENGTH:varint><BYTES>
387 Binary | 9 | BINARY : <9><LENGTH:varint><BYTES>
388 10 -> 15 unused/reserved | - | -
389 -----------------------------+-----+----------------------------------
390
391Variable-length integer (varint) are encoded using Peers encoding:
392
393
394 0 <= X < 240 : 1 byte (7.875 bits) [ XXXX XXXX ]
395 240 <= X < 2288 : 2 bytes (11 bits) [ 1111 XXXX ] [ 0XXX XXXX ]
396 2288 <= X < 264432 : 3 bytes (18 bits) [ 1111 XXXX ] [ 1XXX XXXX ] [ 0XXX XXXX ]
397 264432 <= X < 33818864 : 4 bytes (25 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*2 [ 0XXX XXXX ]
398 33818864 <= X < 4328786160 : 5 bytes (32 bits) [ 1111 XXXX ] [ 1XXX XXXX ]*3 [ 0XXX XXXX ]
399 ...
400
401For booleans, the value (true or false) is the first bit in the FLAGS
402bitfield. if this bit is set to 0, then the boolean is evaluated as false,
403otherwise, the boolean is evaluated as true.
404
4053.2. Frames
406------------
407
408Exchange between HAProxy and agents are made using FRAME packets. All frames
409must be prefixed with their size encoded on 4 bytes in network byte order:
410
411 <FRAME-LENGTH:4 bytes> <FRAME>
412
413A frame always starts with its type, on one byte, followed by metadata
414containing flags, on 4 bytes and a two variable-length integer representing the
415stream identifier and the frame identifier inside the stream:
416
417 FRAME : <FRAME-TYPE:1 byte> <METADATA> <FRAME-PAYLOAD>
418 METADATA : <FLAGS:4 bytes> <STREAM-ID:varint> <FRAME-ID:varint>
419
420Then comes the frame payload. Depending on the frame type, the payload can be
421of three types: a simple key/value list, a list of messages or a list of
422actions.
423
424 FRAME-PAYLOAD : <LIST-OF-MESSAGES> | <LIST-OF-ACTIONS> | <KV-LIST>
425
426 LIST-OF-MESSAGES : [ <MESSAGE-NAME> <NB-ARGS:1 byte> <KV-LIST> ... ]
427 MESSAGE-NAME : <STRING>
428
429 LIST-OF-ACTIONS : [ <ACTION-TYPE:1 byte> <NB-ARGS:1 byte> <ACTION-ARGS> ... ]
430 ACTION-ARGS : [ <TYPED-DATA>... ]
431
432 KV-LIST : [ <KV-NAME> <KV-VALUE> ... ]
433 KV-NAME : <STRING>
434 KV-VALUE : <TYPED-DATA>
435
436 FLAGS : 0 1-31
437 +---+-----------+
438 | F| |
439 | I| RESERVED |
440 | N| |
441 +--+------------+
442
443 FIN: Indicates that this is the final payload fragment. The first fragment
444 may also be the final fragment.
445
446Frames cannot exceed a maximum size negociated between HAProxy and agents
447during the HELLO handshake. Most of time, payload will be small enough to send
448it in one frame. But when supported by the peer, it will be possible to
449fragment huge payload on many frames. This ability is announced during the
450HELLO handshake and it can be asynmetric (supported by agents but not by
451HAProxy or the opposite). The following rules apply to fragmentation:
452
453 * An unfragemnted payload consists of a single frame with the FIN bit set.
454
455 * A fragemented payload consists of several frames with the FIN bit clear and
456 terminated by a single frame with the FIN bit set. All these frames must
457 share the same STREAM-ID and FRAME-ID. And, of course, the FRAME-TYPE must
458 be the same.
459
460Beside the support of fragmented payload by a peer, some payload must not be
461fragmented. See below for details.
462
463IMPORTANT : The maximum size supported by peers for a frame must be greater or
464equal to 256 bytes.
465
4663.2.1. Frame capabilities
467--------------------------
468
469Here are the list of official capabilities that HAProxy and agents can support:
470
471 * fragmentation: This is the abaility for a peer to support fragmented
472 payload in received frames.
473
474Unsupported or unknown capabilities are silently ignored, when possible.
475
4763.2.2. Frame types overview
477----------------------------
478
479Here are types of frame supported by SPOE. Frames sent by HAProxy come first,
480then frames sent by agents :
481
482 TYPE | ID | DESCRIPTION
483 -----------------------------+-----+-------------------------------------
484 HAPROXY-HELLO | 1 | Sent by HAProxy when it opens a
485 | | connection on an agent.
486 | |
487 HAPROXY-DISCONNECT | 2 | Sent by HAProxy when it want to close
488 | | the connection or in reply to an
489 | | AGENT-DISCONNECT frame
490 | |
491 NOTIFY | 3 | Sent by HAProxy to pass information
492 | | to an agent
493 -----------------------------+-----+-------------------------------------
494 AGENT-HELLO | 101 | Reply to a HAPROXY-HELLO frame, when
495 | | the connection is established
496 | |
497 AGENT-DISCONNECT | 102 | Sent by an agent just before closing
498 | | the connection
499 | |
500 ACK | 103 | Sent to acknowledge a NOTIFY frame
501 -----------------------------+-----+-------------------------------------
502
503Unknown frames may be silently skipped.
504
5053.2.3. Workflow
506----------------
507
508 * Successful HELLO handshake:
509
510 HAPROXY AGENT SRV
511 | HAPROXY-HELLO |
Christopher Fauletba7bc162016-11-07 21:07:38 +0100512 | (healthcheck: false) |
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200513 | --------------------------> |
514 | |
515 | AGENT-HELLO |
516 | <-------------------------- |
517 | |
518
Christopher Fauletba7bc162016-11-07 21:07:38 +0100519 * Successful HELLO healthcheck:
520
521 HAPROXY AGENT SRV
522 | HAPROXY-HELLO |
523 | (healthcheck: true) |
524 | --------------------------> |
525 | |
526 | AGENT-HELLO + close() |
527 | <-------------------------- |
528 | |
529
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200530
531 * Error encountered by agent during the HELLO handshake:
532
533 HAPROXY AGENT SRV
534 | HAPROXY-HELLO |
535 | --------------------------> |
536 | |
537 | DISCONNECT + close() |
538 | <-------------------------- |
539 | |
540
541 * Error encountered by HAProxy during the HELLO handshake:
542
543 HAPROXY AGENT SRV
544 | HAPROXY-HELLO |
545 | --------------------------> |
546 | |
547 | AGENT-HELLO |
548 | <-------------------------- |
549 | |
550 | DISCONNECT |
551 | --------------------------> |
552 | |
553 | DISCONNECT + close() |
554 | <-------------------------- |
555 | |
556
557 * Notify / Ack exchange:
558
559 HAPROXY AGENT SRV
560 | NOTIFY |
561 | --------------------------> |
562 | |
563 | ACK |
564 | <-------------------------- |
565 | |
566
567 * Connection closed by haproxy:
568
569 HAPROXY AGENT SRV
570 | DISCONNECT |
571 | --------------------------> |
572 | |
573 | DISCONNECT + close() |
574 | <-------------------------- |
575 | |
576
577 * Connection closed by agent:
578
579 HAPROXY AGENT SRV
580 | DISCONNECT + close() |
581 | <-------------------------- |
582 | |
583
5843.2.4. Frame: HAPROXY-HELLO
585----------------------------
586
587This frame is the first one exchanged between HAProxy and an agent, when the
588connection is established. The payload of this frame is a KV-LIST. It cannot be
589fragmented. STREAM-ID and FRAME-ID are must be set 0.
590
591Following items are mandatory in the KV-LIST:
592
593 * "supported-versions" <STRING>
594
595 Last SPOP major versions supported by HAProxy. It is a comma-separated list
596 of versions, following the format "Major.Minor". Spaces must be ignored, if
597 any. When a major version is announced by HAProxy, it means it also support
598 all previous minor versions.
599
600 Example: "2.0, 1.5" means HAProxy supports SPOP 2.0 and 1.0 to 1.5
601
602 * "max-frame-size" <UINT32>
603
604 This is the maximum size allowed for a frame. The HAPROXY-HELLO frame must
605 be lower or equal to this value.
606
607 * "capabilities" <STRING>
608
609 This a comma-separated list of capabilities supported by HAProxy. Spaces
610 must be ignored, if any.
611
Christopher Fauletba7bc162016-11-07 21:07:38 +0100612Following optional items can be added in the KV-LIST:
613
614 * "healthcheck" <BOOLEAN>
615
616 If this item is set to TRUE, then the HAPROXY-HELLO frame is sent during a
617 SPOE health check. When set to FALSE, this item can be ignored.
618
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +0200619To finish the HELLO handshake, the agent must return an AGENT-HELLO frame with
620its supported SPOP version, the lower value between its maximum size allowed
621for a frame and the HAProxy one and capabilities it supports. If an error
622occurs or if an incompatibility is detected with the agent configuration, an
623AGENT-DISCONNECT frame must be returned.
624
6253.2.5. Frame: AGENT-HELLO
626--------------------------
627
628This frame is sent in reply to a HAPROXY-HELLO frame to finish a HELLO
629handshake. As for HAPROXY-HELLO frame, STREAM-ID and FRAME-ID are also set
6300. The payload of this frame is a KV-LIST and it cannot be fragmented.
631
632Following items are mandatory in the KV-LIST:
633
634 * "version" <STRING>
635
636 This is the SPOP version the agent supports. It must follow the format
637 "Major.Minor" and it must be lower or equal than one of major versions
638 announced by HAProxy.
639
640 * "max-frame-size" <UINT32>
641
642 This is the maximum size allowed for a frame. It must be lower or equal to
643 the value in the HAPROXY-HELLO frame. This value will be used for all
644 subsequent frames.
645
646 * "capabilities" <STRING>
647
648 This a comma-separated list of capabilities supported by agent. Spaces must
649 be ignored, if any.
650
651At this time, if everything is ok for HAProxy (supported version and valid
652max-frame-size value), the HELLO handshake is successfully completed. Else,
653HAProxy sends a HAPROXY-DISCONNECT frame with the corresponding error.
654
Christopher Fauletba7bc162016-11-07 21:07:38 +0100655If "healthcheck" item was set to TRUE in the HAPROXY-HELLO frame, the agent can
656safely close the connection without DISCONNECT frame. In all cases, HAProxy
657will close the connexion at the end of the health check.
658
Christopher Fauletf7e4e7e2016-10-27 22:29:49 +02006593.2.6. Frame: NOTIFY
660---------------------
661
662Information are sent to the agents inside NOTIFY frames. These frames are
663attached to a stream, so STREAM-ID and FRAME-ID must be set. The payload of
664NOTIFY frames is a LIST-OF-MESSAGES and, if supported by agents, it can be
665fragmented.
666
667NOTIFY frames must be acknowledge by agents sending an ACK frame, repeating
668right STREAM-ID and FRAME-ID.
669
6703.2.7. Frame: ACK
671------------------
672
673ACK frames must be sent by agents to reply to NOTIFY frames. STREAM-ID and
674FRAME-ID found in a NOTIFY frame must be reuse in the corresponding ACK
675frame. The payload of ACK frames is a LIST-OF-ACTIONS and, if supported by
676HAProxy, it can be fragmented.
677
6783.2.8. Frame: HAPROXY-DISCONNECT
679---------------------------------
680
681If an error occurs, at anytime, from the HAProxy side, a HAPROXY-DISCONNECT
682frame is sent with information describing the error. HAProxy will wait an
683AGENT-DISCONNECT frame in reply. All other frames will be ignored. The agent
684must then close the socket.
685
686The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
687FRAME-ID are must be set 0.
688
689Following items are mandatory in the KV-LIST:
690
691 * "status-code" <UINT32>
692
693 This is the code corresponding to the error.
694
695 * "message" <STRING>
696
697 This is a textual message describing the error.
698
699For more information about known errors, see section "Errors & timeouts"
700
7013.2.9. Frame: AGENT-DISCONNECT
702-------------------------------
703
704If an error occurs, at anytime, from the agent size, a AGENT-DISCONNECT frame
705is sent, with information desribing the error. such frame is also sent in reply
706to a HAPROXY-DISCONNECT. The agent must close the socket just after sending
707this frame.
708
709The payload of this frame is a KV-LIST. It cannot be fragmented. STREAM-ID and
710FRAME-ID are must be set 0.
711
712Following items are mandatory in the KV-LIST:
713
714 * "status-code" <UINT32>
715
716 This is the code corresponding to the error.
717
718 * "message" <STRING>
719
720 This is a textual message describing the error.
721
722For more information about known errors, see section "Errors & timeouts"
723
7243.3. Events & Messages
725-----------------------
726
727Information about streams are sent in NOTIFY frames. You can specify which kind
728of information to send by defining "spoe-message" sections in your SPOE
729configuration file. for each "spoe-message" there will be a message in a NOTIFY
730frame when the right event is triggered.
731
732A NOTIFY frame is sent for an specific event when there is at least one
733"spoe-message" attached to this event. All messages for an event will be added
734in the same NOTIFY frame.
735
736Here is the list of supported events:
737
738 * on-client-session is triggered when a new client session is created.
739 This event is only available for SPOE filters
740 declared in a frontend or a listen section.
741
742 * on-frontend-tcp-request is triggered just before the evaluation of
743 "tcp-request content" rules on the frontend side.
744 This event is only available for SPOE filters
745 declared in a frontend or a listen section.
746
747 * on-backend-tcp-request is triggered just before the evaluation of
748 "tcp-request content" rules on the backend side.
749 This event is skipped for SPOE filters declared
750 in a listen section.
751
752 * on-frontend-http-request is triggered just before the evaluation of
753 "http-request" rules on the frontend side. This
754 event is only available for SPOE filters declared
755 in a frontend or a listen section.
756
757 * on-backend-http-request is triggered just before the evaluation of
758 "http-request" rules on the backend side. This
759 event is skipped for SPOE filters declared in a
760 listen section.
761
762 * on-server-session is triggered when the session with the server is
763 established.
764
765 * on-tcp-response is triggered just before the evaluation of
766 "tcp-response content" rules.
767
768 * on-http-response is triggered just before the evaluation of
769 "http-response" rules.
770
771
772The stream processing will loop on these events, when triggered, waiting the
773agent reply.
774
7753.4. Actions
776-------------
777
778An agent must acknowledge each NOTIFY frame by sending the corresponding ACK
779frame. Actions can be added in these frames to dynamically take action on the
780processing of a stream.
781
782Here is the list of supported actions:
783
784 * set-var set the value for an existing variable. 3 arguments must be
785 attached to this action: the variable scope (proc, sess, txn,
786 req or req), the variable name (a string) and its value.
787
788 ACTION-SET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME><VAR-VALUE>
789
790 SET-VAR : <1>
791 NB-ARGS : <3>
792 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
793 VAR-NAME : <STRING>
794 VAR-VALUE : <TYPED-DATA>
795
796 PROCESS : <0>
797 SESSION : <1>
798 TRANSACTION : <2>
799 REQUEST : <3>
800 RESERVED : <4>
801
802 * unset-var unset the value for an existing variable. 2 arguments must be
803 attached to this action: the variable scope (proc, sess, txn,
804 req or req) and the variable name (a string).
805
806 ACTION-UNSET-VAR : <SET-VAR:1 byte><NB-ARGS:1 byte><VAR-SCOPE:1 byte><VAR-NAME>
807
808 SET-VAR : <1>
809 NB-ARGS : <3>
810 VAR-SCOPE : <PROCESS> | <SESSION> | <TRANSACTION> | <REQUEST> | <RESPONSE>
811 VAR-NAME : <STRING>
812
813 PROCESS : <0>
814 SESSION : <1>
815 TRANSACTION : <2>
816 REQUEST : <3>
817 RESERVED : <4>
818
819
820NOTE: Name of the variables will be automatically prefixed by HAProxy to avoid
821 name clashes with other variables used in HAProxy. Moreover, unknown
822 variable will be silently ignored.
823
8243.5. Error & timeouts
825----------------------
826
827Here is the list of all known errors:
828
829 STATUS CODE | DESCRIPTION
830 ----------------+--------------------------------------------------------
831 0 | normal (no error occurred)
832 1 | I/O error
833 2 | A timeout occurred
834 3 | frame is too big
835 4 | invalid frame received
836 5 | version value not found
837 6 | max-frame-size value not found
838 7 | capabilities value not found
839 8 | unsupported version
840 9 | max-frame-size too big or too small
841 99 | an unknown error occurrde
842 ----------------+--------------------------------------------------------
843
844An agent can define its own errors using a not yet assigned status code.
845
846IMPORTANT NOTE: For a specific stream, when an abnormal/unexpected error
847 occurs, the SPOE is disabled for all the transaction. So if you
848 have several events configured, such error on an event will
849 disabled all followings. For TCP streams, this will disable the
850 SPOE for the whole session. For HTTP streams, this will disable
851 it for the transaction (request and response).
852
853To avoid a stream to wait infinitly, you must carefully choose the
854acknowledgement timeout. In most of cases, it will be quiet low. But it depends
855on the responsivness of your service.
856
857You must also choose idle timeout carefully. Because connection with your
858service depends on the backend configuration used by the SPOA, it is important
859to use a lower value for idle timeout than the server timeout. Else the
860connection will be closed by HAProxy. The same is true for hello timeout. You
861should choose a lower value than the connect timeout.
862
863
864/*
865 * Local variables:
866 * fill-column: 79
867 * End:
868 */