Commit Graph

6188 Commits

Author SHA1 Message Date
Willy Tarreau
d78c0fa0fb TESTS: add a test configuration to stress handshake combinations
This config tries to involve the various possible combinations of connection
handshakes, on the accept side and on the connect side. It also produces logs
indicating the handshake time.

May be tested with tcploop as the server, both for TCP and HTTP mode :
   - accept new connection
   - pause 100ms
   - send what looks like an HTTP response
   - wait 500ms and close

Starting log server (mainly to check timers) :
   $ socat udp-recvfrom:5514,fork -

Starting server :
   $ tcploop 8000 L N A W P100 S:"HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n" P500

Testing all combinations with server-speaks-first (tcp) :
   $ nc 0 8007

Testing all combinations with client-speaks-first (tcp) :
   $ (printf "GET / HTTP/1.0\r\n\r\n";sleep 1) | nc 0 8007

Testing all combinations with client-speaks-first after pause (tcp) :
   $ (usleep 0.05 ; printf "GET / HTTP/1.0\r\n\r\n";sleep 1) | nc 0 8007

Testing all combinations with client-speaks-first (http) :
   $ (printf "GET / HTTP/1.0\r\n\r\n";sleep 1) | nc 0 8017

Testing all combinations with client-speaks-first after pause (http) :
   $ (usleep 0.05 ; printf "GET / HTTP/1.0\r\n\r\n";sleep 1) | nc 0 8017

Same tests must be redone after surrounding connect() in tcp_connect_server()
with fcntl(fd, F_SETFL, 0) and fcntl(fd, F_SETFL, O_NONBLOCK) for sycnhronous
connect().
2017-03-19 11:59:47 +01:00
Christopher Faulet
e6006245de BUG/MEDIUM: filters: Fix channels synchronization in flt_end_analyze
When a filter is used, there are 2 channel's analyzers to surround all the
others, flt_start_analyze and flt_end_analyze. This is the good place to acquire
and release resources used by filters, when needed. In addition, the last one is
used to synchronize the both channels, especially for HTTP streams. We must wait
that the analyze is finished for the both channels for an HTTP transaction
before restarting it for the next one.

But this part was buggy, leading to unexpected behaviours. First, depending on
which channel ends first, the request or the response can be switch in a
"forward forever" mode. Then, the HTTP transaction can be cleaned up too early,
while a processing is still in progress on a channel.

To fix the bug, the flag CF_FLT_ANALYZE has been added. It is set on channels in
flt_start_analyze and is kept if at least one filter is still analyzing the
channel. So, we can trigger the channel syncrhonization if this flag was removed
on the both channels. In addition, the flag TX_WAIT_CLEANUP has been added on
the transaction to know if the transaction must be cleaned up or not during
channels syncrhonization. This way, we are sure to reset everything once all the
processings are finished.

This patch should be backported in 1.7.
2017-03-15 19:09:06 +01:00
Olivier Houchard
a5938f71e4 CLEANUP: config: Typo in comment.
This is for the recently merged dynamic cookie patch set.
2017-03-15 16:01:51 +01:00
Olivier Houchard
2cb49ebbc4 BUG/MEDIUM server: Fix crash when dynamic is defined, but not key is provided.
Wait until we're sure we have a key before trying to calculate its length.

[wt: no backport needed, was just merged]
2017-03-15 16:01:33 +01:00
Willy Tarreau
3569df3fcf BUG/MEDIUM: listener: do not try to rebind another process' socket
When the "process" setting of a bind line limits the processes a
listening socket is enabled on, a "disable frontend" operation followed
by an "enable frontend" triggers a bug because all declared listeners
are attempted to be bound again regardless of their assigned processes.
This can at minima create new sockets not receiving traffic, and at worst
prevent from re-enabling a frontend if it's bound to a privileged port.

This bug was introduced by commit 1c4b814 ("MEDIUM: listener: support
rebinding during resume()") merged in 1.6-dev1, trying to perform the
bind() before checking the process list instead of after.

Just move the process check before the bind() operation to fix this.
This fix must be backported to 1.7 and 1.6.

Thanks to Pavlos for reporting this one.
2017-03-15 12:47:46 +01:00
Willy Tarreau
a84a2dba94 CONTRIB: tcploop: use the trash instead of NULL for recv()
NULL is Linux-centric and we're not focused on performance here but
portability and reproducibility. Don't use NULL and use the trash
instead. It may lead to multiple recv() calls for large blocks but
as a benefit it will be possible to see the contents with strace.
2017-03-15 11:48:46 +01:00
Willy Tarreau
24d41b9b4d CONTRIB: tcploop: fix connect's address length
FreeBSD wants the address size to be correct, so let's pass the size
of a sockaddr_in struct, not the sockaddr_storage.
2017-03-15 11:48:46 +01:00
Willy Tarreau
bcd817e669 CONTRIB: tcploop: report action 'K' (kill) in usage message
It was missing from the initial import.
2017-03-15 11:48:46 +01:00
Willy Tarreau
752cc49728 CONTRIB: tcploop: fix time format to silence build warnings
timeval doesn't necessarily have ints for tv_sec/tv_usec, let's cast
them.
2017-03-15 11:48:46 +01:00
Willy Tarreau
0c0c0a6c26 CONTRIB: tcploop: make it build on FreeBSD
A few changes :
- SOL_TCP must be replaced with IPPROTO_TCP
- TCP_NOQUICKACK is not defined
- MSG_MORE can be ignored and replaced with 0
2017-03-15 11:48:46 +01:00
Steven Davidovitz
544d481516 BUG/MINOR: checks: attempt clean shutw for SSL check
Strict interpretation of TLS can cause SSL sessions to be thrown away
when the socket is shutdown without sending a "close notify", resulting
in each check to go through the complete handshake, eating more CPU on
the servers.

[wt: strictly speaking there's no guarantee that the close notify will
 be delivered, it's only best effort, but that may be enough to ensure
 that once at least one is received, next checks will be cheaper. This
 should be backported to 1.7 and possibly 1.6]
2017-03-15 11:41:25 +01:00
Olivier Houchard
614f8d7d56 MINOR: cli: Let configure the dynamic cookies from the cli.
This adds 3 new commands to the cli :
enable dynamic-cookie backend <backend> that enables dynamic cookies for a
specified backend
disable dynamic-cookie backend <backend> that disables dynamic cookies for a
specified backend
set dynamic-cookie-key backend <backend> that lets one change the dynamic
cookie secret key, for a specified backend.
2017-03-15 11:38:29 +01:00
Olivier Houchard
4e694049fa MINOR: server: Add dynamic session cookies.
This adds a new "dynamic" keyword for the cookie option. If set, a cookie
will be generated for each server (assuming one isn't already provided on
the "server" line), from the IP of the server, the TCP port, and a secret
key provided. To provide the secret key, a new keyword as been added,
"dynamic-cookie-key", for backends.

Example :
backend bk_web
  balance roundrobin
  dynamic-cookie-key "bla"
  cookie WEBSRV insert dynamic
  server s1 127.0.0.1:80 check
  server s2 192.168.56.1:80 check

This is a first step to be able to dynamically add and remove servers,
without modifying the configuration file, and still have all the load
balancers redirect the traffic to the right server.

Provide a way to generate session cookies, based on the IP address of the
server, the TCP port, and a secret key provided.
2017-03-15 11:37:30 +01:00
Willy Tarreau
7bf3fa3c23 BUG/MAJOR: connection: update CO_FL_CONNECTED before calling the data layer
Matthias Fechner reported a regression in 1.7.3 brought by the backport
of commit 819efbf ("BUG/MEDIUM: tcp: don't poll for write when connect()
succeeds"), causing some connections to fail to establish once in a while.
While this commit itself was a fix for a bad sequencing of connection
events, it in fact unveiled a much deeper bug going back to the connection
rework era in v1.5-dev12 : 8f8c92f ("MAJOR: connection: add a new
CO_FL_CONNECTED flag").

It's worth noting that in a lab reproducing a similar environment as
Matthias' about only 1 every 19000 connections exhibit this behaviour,
making the issue not so easy to observe. A trick to make the problem
more observable consists in disabling non-blocking mode on the socket
before calling connect() and re-enabling it later, so that connect()
always succeeds. Then it becomes 100% reproducible.

The problem is that this CO_FL_CONNECTED flag is tested after deciding to
call the data layer (typically the stream interface but might be a health
check as well), and that the decision to call the data layer relies on a
change of one of the flags covered by the CO_FL_CONN_STATE set, which is
made of CO_FL_CONNECTED among others.

Before the fix above, this bug couldn't appear with TCP but it could
appear with Unix sockets. Indeed, connect() was always considered
blocking so the CO_FL_WAIT_L4_CONN connection flag was always set, and
polling for write events was always enabled. This used to guarantee that
the conn_fd_handler() could detect a change among the CO_FL_CONN_STATE
flags.

Now with the fix above, if a connect() immediately succeeds for non-ssl
connection with send-proxy enabled, and no data in the buffer (thus TCP
mode only), the CO_FL_WAIT_L4_CONN flag is not set, the lack of data in
the buffer doesn't enable polling flags for the data layer, the
CO_FL_CONNECTED flag is not set due to send-proxy still being pending,
and once send-proxy is done, its completion doesn't cause the data layer
to be woken up due to the fact that CO_FL_CONNECT is still not present
and that the CO_FL_SEND_PROXY flag is not watched in CO_FL_CONN_STATE.

Then no progress is made when data are received from the client (and
attempted to be forwarded), because a CF_WRITE_NULL (or CF_WRITE_PARTIAL)
flag is needed for the stream-interface state to turn from SI_ST_CON to
SI_ST_EST, allowing ->chk_snd() to be called when new data arrive. And
the only way to set this flag is to call the data layer of course.

After the connect timeout, the connection gets killed and if in the mean
time some data have accumulated in the buffer, the retry will succeed.

This patch fixes this situation by simply placing the update of
CO_FL_CONNECTED where it should have been, before the check for a flag
change needed to wake up the data layer and not after.

This fix must be backported to 1.7, 1.6 and 1.5. Versions not having
the patch above are still affected for unix sockets.

Special thanks to Matthias Fechner who provided a very detailed bug
report with a bisection designating the faulty patch, and to Olivier
Houchard for providing full access to a pretty similar environment where
the issue could first be reproduced.
2017-03-14 22:04:06 +01:00
Simon Horman
6f6bb380ef MEDIUM: stats: Add show json schema
This may be used to output the JSON schema which describes the output of
show info json and show stats json.

The JSON output is without any extra whitespace in order to reduce the
volume of output. For human consumption passing the output through a
pretty printer may be helpful.

e.g.:
$ echo "show schema json" | socat /var/run/haproxy.stat stdio | \
     python -m json.tool

The implementation does not generate the schema. Some consideration could
be given to integrating the output of the schema with the output of
typed and json info and stats. In particular the types (u32, s64, etc...)
and tags.

A sample verification of show info json and show stats json using
the schema is as follows. It uses the jsonschema python module:

cat > jschema.py <<  __EOF__
import json

from jsonschema import validate
from jsonschema.validators import Draft3Validator

with open('schema.txt', 'r') as f:
    schema = json.load(f)
    Draft3Validator.check_schema(schema)

    with open('instance.txt', 'r') as f:
        instance = json.load(f)
	validate(instance, schema, Draft3Validator)
__EOF__

$ echo "show schema json" | socat /var/run/haproxy.stat stdio > schema.txt
$ echo "show info json" | socat /var/run/haproxy.stat stdio > instance.txt
python ./jschema.py
$ echo "show stats json" | socat /var/run/haproxy.stat stdio > instance.txt
python ./jschema.py

Signed-off-by: Simon Horman <horms@verge.net.au>
2017-03-14 11:14:03 +01:00
Simon Horman
05ee213f8b MEDIUM: stats: Add JSON output option to show (info|stat)
Add a json parameter to show (info|stat) which will output information
in JSON format. A follow-up patch will add a JSON schema which describes
the format of the JSON output of these commands.

The JSON output is without any extra whitespace in order to reduce the
volume of output. For human consumption passing the output through a
pretty printer may be helpful.

e.g.:
$ echo "show info json" | socat /var/run/haproxy.stat stdio | \
     python -m json.tool

STAT_STARTED has bee added in order to track if show output has begun or
not. This is used in order to allow the JSON output routines to only insert
a "," between elements when needed. I would value any feedback on how this
might be done better.

Signed-off-by: Simon Horman <horms@verge.net.au>
2017-03-14 11:14:03 +01:00
Willy Tarreau
2019f95997 CLEANUP: http: make http_server_error() not set the status anymore
Given that all call places except one had to set txn->status prior to
calling http_server_error(), it's simpler to make this function rely
on txn->status than have it store it from an argument.
2017-03-14 11:09:04 +01:00
Jarno Huuskonen
800d1761d0 MINOR: http-request tarpit deny_status.
Implements deny_status for http-request tarpit rule (allows setting
custom http status code). This commit depends on:
MEDIUM: http_error_message: txn->status / http_get_status_idx.
2017-03-14 10:41:54 +01:00
Jarno Huuskonen
9e6906b9ec MEDIUM: http_error_message: txn->status / http_get_status_idx.
This commit removes second argument(msgnum) from http_error_message and
changes http_error_message to use s->txn->status/http_get_status_idx for
mapping status code from 200..504 to HTTP_ERR_200..HTTP_ERR_504(enum).

This is needed for http-request tarpit deny_status commit.
2017-03-14 10:41:41 +01:00
Nenad Merdanovic
50c8044423 CLEANUP: Remove comment that's no longer valid
Code was deleted in ad63582eb, but the comment remained.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:26:05 +01:00
Nenad Merdanovic
807a6e7856 MINOR: Add hostname sample fetch
It adds "hostname" as a new sample fetch. It does exactly the same as
"%H" in a log format except that it can be used outside of log formats.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:26:05 +01:00
Nenad Merdanovic
2754fbcfd6 CLEANUP: Replace repeated code to count usable servers with be_usable_srv()
2 places were using an open-coded implementation of this function to count
available servers. Note that the avg_queue_size() fetch didn't check that
the proxy was in STOPPED state so it would possibly return a wrong server
count here but that wouldn't impact the returned value.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:26:05 +01:00
Nenad Merdanovic
b7e7c4720a MINOR: Add nbsrv sample converter
This is like the nbsrv() sample fetch function except that it works as
a converter so it can count the number of available servers of a backend
name retrieved using a sample fetch or an environment variable.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:26:05 +01:00
Nenad Merdanovic
96c1571943 BUG/MINOR: Fix "get map <map> <value>" CLI command
The said form of the CLI command didn't return anything since commit
ad8be61c7.

This fix needs to be backported to 1.7.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:25:53 +01:00
Nenad Merdanovic
24f45d8e34 BUG/MEDIUM: cli: Prevent double free in CLI ACL lookup
The memory is released by cli_release_mlook, which also properly sets the
pointer to NULL. This was introduced with a big code reorganization
involving moving to the new keyword registration form in commit ad8be61c7.

This fix needs to be backported to 1.7.

Signed-off-by: Nenad Merdanovic <nmerdan@haproxy.com>
2017-03-13 18:25:53 +01:00
Janusz Dziemidowicz
8d7104982e BUG/MEDIUM: ssl: Clear OpenSSL error stack after trying to parse OCSP file
Invalid OCSP file (for example empty one that can be used to enable
OCSP response to be set dynamically later) causes errors that are
placed on OpenSSL error stack. Those errors are not cleared so
anything that checks this stack later will fail.

Following configuration:
  bind :443 ssl crt crt1.pem crt crt2.pem

With following files:
  crt1.pem
  crt1.pem.ocsp - empty one
  crt2.pem.rsa
  crt2.pem.ecdsa

Will fail to load.

This patch should be backported to 1.7.
2017-03-10 18:53:22 +01:00
Willy Tarreau
de7dc88c51 MINOR: config: warn when some HTTP rules are used in a TCP proxy
Surprizingly, http-request, http-response, block, redirect, and capture
rules did not cause a warning to be emitted when used in a TCP proxy, so
let's fix this.

This patch may be backported to older versions as it helps spotting
configuration issues.
2017-03-10 11:49:21 +01:00
Christopher Faulet
d1307cea84 DOC: spoe: Update SPOE documentation to reflect recent changes 2017-03-09 15:32:56 +01:00
Christopher Faulet
2eca6b50a7 MINOR: spoe: Add "max-frame-size" statement in spoe-agent section
As its named said, this statement customize the maximum allowed size for frames
exchanged between HAProxy and SPOAs. It should be greater than or equal to 256
and less than or equal to (tune.bufsize - 4) (4 bytes are reserved to the frame
length).
2017-03-09 15:32:56 +01:00
Christopher Faulet
cecd8527b3 MINOR: spoe: Add "send-frag-payload" option in spoe-agent section
This option can be used to enable or to disable (prefixing the option line with
the "no" keyword) the sending of fragmented payload to agents. By default, this
option is enabled.
2017-03-09 15:32:55 +01:00
Christopher Faulet
ecc537a8b9 MINOR: spoe: Rely on alertif_too_many_arg during configuration parsing 2017-03-09 15:32:55 +01:00
Christopher Faulet
305c6079d4 MINOR: spoe: Add "pipelining" and "async" options in spoe-agent section
These options can be used to enable or to disable (prefixing the option line
with the "no" keyword), respectively, pipelined and asynchronous exchanged
between HAproxy and agents. By default, pipelining and async options are
enabled.
2017-03-09 15:32:55 +01:00
Christopher Faulet
6a2940c5f5 MINOR: spoe: Add support of negation for options in SPOE configuration file
For now, no options support negation (using "no" keyword). So it always returns
an error.
2017-03-09 15:32:55 +01:00
Christopher Faulet
f032c3ec09 MINOR: spoe: Improve implementation of the payload fragmentation
Now, when a payload is fragmented, the first frame must define the frame type
and the followings must use the special type SPOE_FRM_T_UNSET. This way, it is
easy to know if a fragment is the first one or not. Of course, all frames must
still share the same stream-id and frame-id.

Update SPOA example accordingly.
2017-03-09 15:32:55 +01:00
Christopher Faulet
4ff3e574ac REORG: spoe: Move low-level encoding/decoding functions in dedicated header file
So, it will be easier to anyone to develop external services using these
functions.

SPOA example has been updated accordingly.
2017-03-09 15:32:55 +01:00
Christopher Faulet
1f40b91a83 REORG: spoe: Move struct and enum definitions in dedicated header file
SPOA example has been Updated accordingly
2017-03-09 15:32:55 +01:00
Christopher Faulet
8eda93f30f MINOR: spoe: Handle NOTIFY frames cancellation using ABORT bit in ACK frames
If an agent want to abort the processing a fragmented NOTIFY frame before
receiving all fragments, it can send an ACK frame at any time with ABORT bit set
(and of course, the FIN bit too).

Beside this change, SPOE_FRM_ERR_FRAMEID_NOTFOUND error flag has been added. It
is set when a unknown ACK frame is received.
2017-03-09 15:32:55 +01:00
Christopher Faulet
8ef75251e3 MAJOR: spoe: refactor the filter to clean up the code
The SPOE code is now pretty big and it was the good time to clean it up. It is
not perfect, some parts remains a bit ugly. But it is far better now.
2017-03-09 15:32:55 +01:00
Christopher Faulet
850103546c MINOR: spoe: Add support for fragmentation capability in the SPOA example
This is just an example. So be careful to not send really huge payload because
it would eat all your memory.
2017-03-09 15:32:55 +01:00
Christopher Faulet
f51f5fa56c MAJOR: spoe: Add support of payload fragmentation in NOTIFY frames
Now, agents can announce the support for the "fragmentation" capability during
the HELLO handshake. HAProxy will never announce it because fragmented frame
decoding is not implemented yet. But it can send such kind of frames. So, if an
agent supports this capability, payloads exceeding the frame size will be
split. A fragemented payload consists of several frames with the FIN bit clear
and terminated by a single frame with the FIN bit set. All these frames must
share the same STREAM-ID and FRAME-ID.

Note that an unfragemnted payload consists of a single frame with the FIN bit
set. And HELLO and DISCONNECT frames cannot be fragmented. This means that only
NOTIFY frames can transport fragmented payload for now.
2017-03-09 15:32:55 +01:00
Christopher Faulet
7aa0b2b0dd MINOR: spoe: Use the min of all known max_frame_size to encode messages
The max_frame_size value is negociated between HAProxy and SPOE agents during
the HELLO handshake. It is a per-connection value. Different SPOE agents can
choose to use different max_frame_size values. So, now, we keep the minimum of
all known max_frame_size. This minimum is updated when a new connection to a
SPOE agent is opened and when a connection is closed. We use this value as a
limit to encode messages in NOTIFY frames.
2017-03-09 15:32:55 +01:00
Christopher Faulet
4596fb7056 MEDIUM: spoe: Be sure to wakeup the good entity waiting for a buffer
This happens when buffer allocation failed. In the SPOE context, buffers are
allocated by streams and SPOE applets at different time. First, by streams, when
messages need to be encoded before sending them in a NOTIFY frame. Then, by SPOE
applets, when a ACK frame is received.

The first case works as expected, we wake up the stream. But for the second one,
we must wake up the waiting SPOE applet.
2017-03-09 15:32:55 +01:00
Christopher Faulet
a21b064f81 MINOR: spoe: Check the scope of sample fetches used in SPOE messages
If an error is triggered, the corresponding message is ignored and a warning is
emitted.
2017-03-09 15:32:55 +01:00
Christopher Faulet
72bcc4724f MINOR: spoe: Send a log message when an error occurred during event processing 2017-03-09 15:32:55 +01:00
Christopher Faulet
b067b06fc7 MINOR: spoe: Add status code in error variable instead of hardcoded value
Now, when option "set-on-error" is enabled, we set a status code representing
the error occurred instead of "true". For values under 256, it represents an
error coming from the engine. Below 256, it reports a SPOP error. In this case,
to retrieve the right SPOP status code, you must remove 256 to this value. Here
are possible values:

  * 1:     a timeout occurred during the event processing.
  * 2:     an error was triggered during the ressources allocation.
  * 255:   an unknown error occurred during the event processing.
  * 256+N: a SPOP error occurred during the event processing.
2017-03-09 15:32:55 +01:00
Christopher Faulet
42bfa46234 MINOR: spoe: Remove SPOE details from the appctx structure
Now, as for peers, we use an opaque pointer to store information related to the
SPOE filter in appctx structure. These information are now stored in a dedicated
structure (spoe_appctx) and allocated, using a pool, when the applet is created.

This removes the dependency between applets and the SPOE filter and avoids to
eventually inflate the appctx structure.
2017-03-09 15:32:55 +01:00
Christopher Faulet
f95b111dde MINOR: spoe: Add support for pipelining/async capabilities in the SPOA example
Now, we can use the option '-c' to enable the support of a capability. By
default, all capabilities are disabled. For example:

  $> ./spoa -c async -c pipelining

In addition, it is also possible to set the maximum frame size supported by your
agent (-m) and to add a delay in frames processing (-t).
2017-03-09 15:32:55 +01:00
Christopher Faulet
a1cda02995 MAJOR: spoe: Add support of pipelined and asynchronous exchanges with agents
Now, HAProxy and agents can announce the support for "pipelining" and/or "async"
capabilities during the HELLO handshake. For now, HAProxy always announces the
support of both. In addition, in its HELLO frames. HAproxy adds the "engine-id"
key. It is a uniq string that identify a SPOE engine.

The "pipelining" capability is the ability for a peer to decouple NOTIFY and ACK
frames. This is a symmectical capability. To be used, it must be supported by
HAproxy and agents. Unlike HTTP pipelining, the ACK frames can be send in any
order, but always on the same TCP connection used for the corresponding NOTIFY
frame.

The "async" capability is similar to the pipelining, but here any TCP connection
established between HAProxy and the agent can be used to send ACK frames. if an
agent accepts connections from multiple HAProxy, it can use the "engine-id"
value to group TCP connections.
2017-03-09 15:32:55 +01:00
Christopher Faulet
b0b4238825 BUG/MINOR: spoe: Fix parsing of arguments in spoe-message section
The array of pointers passed to sample_parse_expr was not really an array but a
pointer to pointer. So it can easily lead to a segfault during the configuration
parsing.
2017-03-09 15:32:55 +01:00
Christopher Faulet
3b386a318f BUG/MINOR: spoe: Fix soft stop handler using a specific id for spoe filters
During a soft stop, we need to wakeup all SPOE applets to stop them. So we loop
on all proxies, and for each proxy, on all filters. But we must be sure to only
handle SPOE filters here. To do so, we use a specific id.
2017-03-09 15:32:55 +01:00