25 Commits

Author SHA1 Message Date
Christopher Faulet
2ccfebcebf BUG/MINOR: mux-spop: Use the right bitwise operator in spop_ctl()
Becaues of a typo, '||' was used instead of '|' to test the SPOP conneciton
flags and decide if the mux is ready or not. The regression was introduced
in the commit fd7ebf117 ("BUG/MEDIUM: mux-spop: Wait end of handshake to
declare a spop connection ready").

This patch must be backported to 3.1 with the commit above.
2025-04-30 16:01:36 +02:00
Christopher Faulet
53c3046898 BUG/MEDIUM: mux-spop: Handle CLOSING state and wait for AGENT DISCONNECT frame
In the SPOE specification, when an error occurred on the SPOP connection,
HAProxy must send a DISCONNECT frame and wait for the agent DISCONNECT frame
in return before trully closing the connection.

However, this part was not properly handled by the SPOP multiplexer. In this
case, the SPOP connection should be in the CLOSING state. But this state was
not used at all. Depending on when the error was encountered, the connection
could be closed immediately, without sending any DISCONNECT frame. It was
the case when an early error was detected during the AGENT-HELLO frame
parsing. Or it could be moved from ERROR to FRAME_H state, as if no error
were detected. This case was less dramatic than it seemed because some flags
were also set to prevent any problem. But it was not obvious.

So now, the SPOP connection is properly switch to CLOSING state when an
DISCONNECT is sent to the agent to be able to wait for its DISCONNECT in
reply. spop_process_demux() was updated to parse frames in that state and
some validity checks was added.

This patch must be backport to 3.1.
2025-04-30 14:44:42 +02:00
Christopher Faulet
fd7ebf117b BUG/MEDIUM: mux-spop: Wait end of handshake to declare a spop connection ready
A SPOP connection must not be considered as ready while the hello handshake
is not finished with success. In addition, no error or shutdown must have
been reported for the underlying connection. Otherwise a freshly openned
spop connexion may be reused while it is in fact dead, leading to a
connection retry.

This patch must be backported to 3.1.
2025-04-30 14:44:42 +02:00
Christopher Faulet
ce8c2d359b BUG/MEDIUM: mux-spop: Respect the negociated max-frame-size value to send frames
When a SPOP connection is opened, the maximum size for frames is negociated.
This negociated size is properly used when a frame is received and if a too
big frame is detected, an error is triggered. However, the same was not
performed on the sending path. No check was performed on frames sent to the
agent. So it was possible to send frames bigger than the maximum size
supported by the the SPOE agent.

Now, the size of NOTIFY and DISCONNECT frames is checked before sending them
to the agent.

Thanks to Miroslav to have reported the issue.

This patch must be backported to 3.1.
2025-04-22 16:14:47 +02:00
Christopher Faulet
851e52b551 BUG/MEDIUM: spoe/mux-spop: Introduce an NOOP action to deal with empty ACK
In the SPOP protocol, ACK frame with empty payload are allowed. However, in
that case, because only the payload is transferred, there is no data to
return to the SPOE applet. Only the end of input is reported. Thus the
applet is never woken up. It means that the SPOE filter will be blocked
during the processing timeout and will finally return an error.

To workaournd this issue, a NOOP action is introduced with the value 0. It
is only an internal action for now. It does not exist in the SPOP
protocol. When an ACK frame with an empy payload is received, this noop
action is transferred to the SPOE applet, instead of nothing. Thanks to this
trick, the applet is properly notified. This works because unknown actions
are ignored by the SPOE filter.

This patch must be backported to 3.1.
2025-02-20 11:56:27 +01:00
Christopher Faulet
0aa69e7865 MINOR: mux-spop/mux-fcgi: Add support of the debug string for logs
Now it is possible to have debug info about FCGI and SPOP multiplexers. To do
so, the support for the MUX_SCTL_DBG_STR command was implemented for these
muxes.

The have this log message, the log-format must be set to:

  log-format "$HAPROXY_HTTP_LOG_FMT bs=<%[bs.debug_str]>"
2025-02-06 11:19:32 +01:00
Christopher Faulet
7b638eb1a6 MINOR: mux-spop: Implement .show_sd callback function
The SPOP multiplexer now implements the .show_sd callback function called by
"show sess" CLI command.
2025-02-06 11:19:32 +01:00
Christopher Faulet
5aeb678762 MINOR: mux-spop: Dump info about connections and streams in dedicated functions
spop_show_fd() function was splitted to dump the info about the SPOP
connections and the SPOP streams in dedicated functions, duplicating this
way what is performed in other muxes.
2025-02-06 11:19:32 +01:00
Christopher Faulet
eb4e517489 CLEANUP: mux-spop: Remove useless comments
Just a small cleanup to remove some comments added during the development of
the mux.
2025-02-06 11:19:32 +01:00
Christopher Faulet
4f8ae5b1f6 MINOR: tevt/mux-spop: Report termination events for the SPOP connect/stream
Termination events are now reported for the SPOP connections and the SPOP
streams. In addition, all available termination events logs are reported in
the "show-fd" callback function. The .ctl and .sctl callback functions were
also update to support, respectively, MUX_CTL_TEVTS and MUX_SCTL_TEVTS
commands.
2025-02-06 11:19:32 +01:00
Christopher Faulet
514a912a4d MINOR: mux-spop: Set SPOP_CF_ERROR flag on connection error only
The SPOP_CF_ERROR flag is now set on connection error only. It was also set
on some demux failures. But it is not mandatory because the connection is
closed anyway. And it is handy to have a flag dedicated to tcp connection
error. It was the original purpose of this flag.

This patch could be backported to 3.1 to ease future backports.
2025-02-06 11:19:32 +01:00
Christopher Faulet
d16c534511 MINOR: mux-spop: Report EOI on the SE when a ACK is received for a stream
The spop stream now reports the end of input when the ACK is transferred to
the SPOE applet. To do so, the flag SPOP_SF_ACK_RCVD was added. It is set on
the SPOP stream when its ACK is received by the SPOP connection.

In addition when SPOP stream flags are propagated to the SE, the error is
now reported if end of input was not reached instead of testing the
connection error code. It is more accurate.

This patch should be backported to 3.1.
2025-02-06 11:19:32 +01:00
Amaury Denoyelle
1778284824 MINOR: mux-spop: use explicit __objt_server on idle conn reinsert
This commit is the counterpart of the previous one for SPOP mux. It
replaces objt_server() by unsafe __objt_server(), as conn target is
guarantee to point to a valid server instance, which can then be used as
_srv_add_idle() argument.

This should fix coverity report from github issue #2811.
2024-12-06 18:02:55 +01:00
Willy Tarreau
d288ddb575 CLEANUP: muxes: remove useless inclusion of ebmbtree.h
Since 2.7 with commit 8522348482 ("BUG/MAJOR: conn-idle: fix hash indexing
issues on idle conns"), we've been using eb64 trees and not ebmb trees
anymore, and later we dropped all that to centralize the operations in
the server. Let's remove the ebmbtree.h includes from the muxes that do
not use them.
2024-10-12 16:29:15 +02:00
Willy Tarreau
f8bff3b531 BUG/MINOR: mux-spop: always clear MUX_MFULL and DEM_MROOM when clearing the mbuf
That's the equivalent of the mux-h2 one, except that here there's no
real risk to loop since normally we cannot feed data that bypass the
closed state check (e.g. no zero-copy forward). But it still remains
dirty to be able to leave and empty mbuf with MFULL and MROOM set, so
better clear them as well.

No backport is needed since this is only in 3.1.
2024-09-03 14:39:04 +02:00
Christopher Faulet
2f3c4d1b6c MINOR: spoe: export the list of SPOP error reasons
The strings representing the human-readable version for SPOP errors are now
exported. It is now an array of IST to ease manipulation.
2024-07-24 14:19:10 +02:00
Christopher Faulet
f8fed07d3a MINOR: spoe: Add a function to validate a version is supported
spoe_check_vsn() function can now be used to check if a version, converted
to an integer, via spoe_str_to_vsn() for instance, is supported. To do so,
the list of all supported version is now exported.
2024-07-24 14:19:10 +02:00
Willy Tarreau
a5c5a68454 BUILD: mux-spop: fix build failure on gcc 4-10 and clang
A label at end of block was added in mux_spop.c in function
spop_conn_update_timeout() by commit 7e1bb7283b ("MEDIUM: mux-spop:
Introduce the SPOP multiplexer"). This is normally not permitted,
so gcc-4 to 10 and clang whine about it:

    CC      src/mux_spop.o
  src/mux_spop.c: In function 'spop_conn_update_timeout':
  src/mux_spop.c:899:2: error: label at end of compound statement
    899 |  leave:
        |  ^~~~~

Let's just add a return there to make the compiler happy. No backport
is needed.
2024-07-15 19:19:13 +02:00
Christopher Faulet
1755c32949 MEDIUM: mux-spop: Announce the pipeling support if possible
Reintroduce the pipelining support. Everyting was alredy in place to be able
to multiplex the streams on a SPOP connection. Here, the pipelining support
is annonced and checked in the agent replies. A hard-coded limit to 20
streams is set if the pipelining is supported on both sides. Otherwise, it
is disabled and only one stream at a time is allowed.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
880c037bcf MEDIUM: mux-spop: Add checks on received frames
Some conformance checks on received frames are added with this patch. Idea
is to detect invalid frames and ignore unknown ones if possible. All checks
are performed on the frame metatdata, mainly on the stream and the frame
identifiers.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
7890d6b28d MINOR: spoe: Remove the spop version from the SPOE appctx context
The SPOE applet no longer manipulate the SPOP verison. So it can be safely
removed from its context.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
62d3a96301 MEDIUM: mux-spop/spoe: Save negociated max-frame-size value in the mux
The SPOE applet is just a pass-through now. It is no longer reponsible to
check the frame size. On the other hand, the SPOP multiplexer negociate the
maximum frame size with the agent. So, it seems logical to store this
negociated value in the mux and no longer in the applet context.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
e68274c90a MAJOR: mux-spop: Make the SPOP connections reusable
Thanks to this patch, SPOP connections can now be inserted in idle
connections list of the server or the session. There is no multiplexing by
SPOP connecitons can be reused. It is the same mechanics than for other
muxes. Noting really new. But it is a huge improvement.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
078f9d3583 MINOR: mux-spop: Use a dedicated function to update the SPOP connection timeout
Force the SPOP servers to use the SPOE engine identifier as pool connection
name. This way, idle SPOP connections, once implemented, of different engine
but using the same backend will not be mixed up.

The related issue is #2502.
2024-07-12 15:27:05 +02:00
Christopher Faulet
7e1bb7283b MEDIUM: mux-spop: Introduce the SPOP multiplexer
It is no possible yet to use it. Idles connections and pipelining mode are
not supported for now. But it should be possible to open a SPOP connection,
perform the HELLO handshake, send a NOTIFY frame based on data produced by
the client side and receive the corresponding ACK frame to transfer its
content to the client side.

The related issue is #2502.
2024-07-12 15:27:04 +02:00