]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
3 years agoMINOR: httpclient: Don't limit data transfer to 1024 bytes
Christopher Faulet [Wed, 12 Jan 2022 13:46:03 +0000 (14:46 +0100)] 
MINOR: httpclient: Don't limit data transfer to 1024 bytes

For debug purpose, no more 1024 bytes were copied at a time. But there is no
reason to keep this limitation. Thus, it is removed.

This patch may be backported to 2.5.

3 years agoBUG/MEDIUM: httpclient: Xfer the request when the stream is created
Christopher Faulet [Wed, 12 Jan 2022 14:27:41 +0000 (15:27 +0100)] 
BUG/MEDIUM: httpclient: Xfer the request when the stream is created

Since the HTTP legacy mode was removed, it is unexpected to create an HTTP
stream without a valid request. Thanks to this change, the wait_for_request
analyzer was significatly simplified. And it is possible because HTTP
multiplexers already take care to have a valid request to create a stream.

But it means that any HTTP applet on the client side must do the same. The
httpclient client is one of them. And it is not a problem because the
request is generated before starting the applet. We must just take care to
set the right state.

For now it works "by chance", because the applet seems to be scheduled
before the stream itself. But if this change, this will lead to crash
because the stream expects to have a request when wait_for_request analyzer.

This patch should be backported to 2.5.

3 years agoBUG/MINOR: httpclient: Revisit HC request and response buffers allocation
Christopher Faulet [Wed, 12 Jan 2022 10:14:08 +0000 (11:14 +0100)] 
BUG/MINOR: httpclient: Revisit HC request and response buffers allocation

For now, these buffers are allocated when the httpclient is created and
freed when it is released. Usually, we try to avoid to keep buffer allocated
if it is not required. Empty buffers should be released ASAP. Apart for
that, there is no issue with the response side because a copy is always
performed. However, for the request side, a swap with the channel's buffer
is always performed. And there is no guarantee the channel's buffer is
allocated. Thus, after the swap, the httpclient can retrieve a null
buffer. In practice, this never happens. But this may change. And it will be
required for a futur fix.

So, now, we systematically take care to have an allocated buffer when we
want to write in it. And it is released as soon as it becomes empty.

This patch should be backported to 2.5.

3 years agoMINOR: mworker/cli: add flags in the prompt
William Lallemand [Wed, 2 Feb 2022 13:13:54 +0000 (14:13 +0100)] 
MINOR: mworker/cli: add flags in the prompt

The master CLI prompt is now able to show flags in its prompt depending
on the mode used: experimental (x), expert (e), mcli-debug (d).

3 years agoMINOR: mworker/cli: mcli-debug-mode enables every command
William Lallemand [Wed, 2 Feb 2022 10:43:20 +0000 (11:43 +0100)] 
MINOR: mworker/cli: mcli-debug-mode enables every command

"mcli-debug-mode on" enables every command that were meant for a worker,
on the CLI of the master. Which mean you can issue, "show fd", show
stat" in order to debug the MASTER proxy.

You can also combine it with "expert-mode on" or "experimental-mode on"
to access to more commands.

3 years agoBUG/MINOR: mworker/cli: don't display help on master applet
William Lallemand [Wed, 2 Feb 2022 10:23:58 +0000 (11:23 +0100)] 
BUG/MINOR: mworker/cli: don't display help on master applet

When in expert or experimental mode on the master CLI, and issuing a
command for the master process, all commands are prefixed by
"mode-experimental -" or/and "mode-expert on -", however these commands
were not available in the master applet, so the help was issued for
each one.

3 years agoCLEANUP: cleanup a commentary in pcli_parse_request()
William Lallemand [Wed, 2 Feb 2022 13:07:08 +0000 (14:07 +0100)] 
CLEANUP: cleanup a commentary in pcli_parse_request()

Remove '1' from a commentary in pcli_parse_request()

3 years agoDOC: management: add expert and experimental mode in 9.4.1
William Lallemand [Wed, 2 Feb 2022 14:29:21 +0000 (15:29 +0100)] 
DOC: management: add expert and experimental mode in 9.4.1

Add the expert and experimental mode in the Master CLI commands section.

3 years agoDOC: management: rework the Master CLI section
William Lallemand [Wed, 2 Feb 2022 13:44:19 +0000 (14:44 +0100)] 
DOC: management: rework the Master CLI section

Rework the master CLI section the same way the "Unix Socket commands"
section is made, ordering the available keywords in the section.

3 years ago[RELEASE] Released version 2.6-dev1 v2.6-dev1
Willy Tarreau [Tue, 1 Feb 2022 17:06:59 +0000 (18:06 +0100)] 
[RELEASE] Released version 2.6-dev1

Released version 2.6-dev1 with the following main changes :
    - BUG/MINOR: cache: Fix loop on cache entries in "show cache"
    - BUG/MINOR: httpclient: allow to replace the host header
    - BUG/MINOR: lua: don't expose internal proxies
    - MEDIUM: mworker: seamless reload use the internal sockpairs
    - BUG/MINOR: lua: remove loop initial declarations
    - BUG/MINOR: mworker: does not add the -sf in wait mode
    - BUG/MEDIUM: mworker: FD leak of the eventpoll in wait mode
    - MINOR: quic: do not reject PADDING followed by other frames
    - REORG: quic: add comment on rare thread concurrence during CID alloc
    - CLEANUP: quic: add comments on CID code
    - MEDIUM: quic: handle CIDs to rattach received packets to connection
    - MINOR: qpack: support litteral field line with non-huff name
    - MINOR: quic: activate QUIC traces at compilation
    - MINOR: quic: use more verbose QUIC traces set at compile-time
    - MEDIUM: pool: refactor malloc_trim/glibc and jemalloc api addition detections.
    - MEDIUM: pool: support purging jemalloc arenas in trim_all_pools()
    - BUG/MINOR: mworker: deinit of thread poller was called when not initialized
    - BUILD: pools: only detect link-time jemalloc on ELF platforms
    - CI: github actions: add the output of $CC -dM -E-
    - BUG/MEDIUM: cli: Properly set stream analyzers to process one command at a time
    - BUILD: evports: remove a leftover from the dead_fd cleanup
    - MINOR: quic: Set "no_application_protocol" alert
    - MINOR: quic: More accurate immediately close.
    - MINOR: quic: Immediately close if no transport parameters extension found
    - MINOR: quic: Rename qc_prep_hdshk_pkts() to qc_prep_pkts()
    - MINOR: quic: Possible crash when inspecting the xprt context
    - MINOR: quic: Dynamically allocate the secrete keys
    - MINOR: quic: Add a function to derive the key update secrets
    - MINOR: quic: Add structures to maintain key phase information
    - MINOR: quic: Optional header protection key for quic_tls_derive_keys()
    - MINOR: quic: Add quic_tls_key_update() function for Key Update
    - MINOR: quic: Enable the Key Update process
    - MINOR: quic: Delete the ODCIDs asap
    - BUG/MINOR: vars: Fix the set-var and unset-var converters
    - MEDIUM: pool: Following up on previous pool trimming update.
    - BUG/MEDIUM: mux-h1: Fix splicing by properly detecting end of message
    - BUG/MINOR: mux-h1: Fix splicing for messages with unknown length
    - MINOR: mux-h1: Improve H1 traces by adding info about http parsers
    - MINOR: mux-h1: register a stats module
    - MINOR: mux-h1: add counters instance to h1c
    - MINOR: mux-h1: count open connections/streams on stats
    - MINOR: mux-h1: add stat for total count of connections/streams
    - MINOR: mux-h1: add stat for total amount of bytes received and sent
    - REGTESTS: h1: Add a script to validate H1 splicing support
    - BUG/MINOR: server: Don't rely on last default-server to init server SSL context
    - BUG/MEDIUM: resolvers: Detach query item on response error
    - MEDIUM: resolvers: No longer store query items in a list into the response
    - BUG/MAJOR: segfault using multiple log forward sections.
    - BUG/MEDIUM: h1: Properly reset h1m flags when headers parsing is restarted
    - BUG/MINOR: resolvers: Don't overwrite the error for invalid query domain name
    - BUILD: bug: Fix error when compiling with -DDEBUG_STRICT_NOCRASH
    - BUG/MEDIUM: sample: Fix memory leak in sample_conv_jwt_member_query
    - DOC: spoe: Clarify use of the event directive in spoe-message section
    - DOC: config: Specify %Ta is only available in HTTP mode
    - BUILD: tree-wide: avoid warnings caused by redundant checks of obj_types
    - IMPORT: slz: use the correct CRC32 instruction when running in 32-bit mode
    - MINOR: quic: fix segfault on CONNECTION_CLOSE parsing
    - MINOR: h3: add BUG_ON on control receive function
    - MEDIUM: xprt-quic: finalize app layer initialization after ALPN nego
    - MINOR: h3: remove duplicated FIN flag position
    - MAJOR: mux-quic: implement a simplified mux version
    - MEDIUM: mux-quic: implement release mux operation
    - MEDIUM: quic: detect the stream FIN
    - MINOR: mux-quic: implement subscribe on stream
    - MEDIUM: mux-quic: subscribe on xprt if remaining data after send
    - MEDIUM: mux-quic: wake up xprt on data transferred
    - MEDIUM: mux-quic: handle when sending buffer is full
    - MINOR: quic: RX buffer full due to wrong CRYPTO data handling
    - MINOR: quic: Race issue when consuming RX packets buffer
    - MINOR: quic: QUIC encryption level RX packets race issue
    - MINOR: quic: Delete remaining RX handshake packets
    - MINOR: quic: Remove QUIC TX packet length evaluation function
    - MINOR: hq-interop: fix tx buffering
    - MINOR: mux-quic: remove uneeded code to check fin on TX
    - MINOR: quic: add HTX EOM on request end
    - BUILD: mux-quic: fix compilation with DEBUG_MEM_STATS
    - MINOR: http-rules: Add capture action to http-after-response ruleset
    - BUG/MINOR: cli/server: Don't crash when a server is added with a custom id
    - MINOR: mux-quic: do not release qcs if there is remaining data to send
    - MINOR: quic: notify the mux on CONNECTION_CLOSE
    - BUG/MINOR: mux-quic: properly initialize flow control
    - MINOR: quic: Compilation fix for quic_rx_packet_refinc()
    - MINOR: h3: fix possible invalid dereference on htx parsing
    - DOC: config: retry-on list is space-delimited
    - DOC: config: fix error-log-format example
    - BUG/MEDIUM: mworker/cli: crash when trying to access an old PID in prompt mode
    - MINOR: hq-interop: refix tx buffering
    - REGTESTS: ssl: use X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY for cert check
    - MINOR: cli: "show version" displays the current process version
    - CLEANUP: cfgparse: modify preprocessor guards around numa detection code
    - MEDIUM: cfgparse: numa detect topology on FreeBSD.
    - BUILD: ssl: unbreak the build with newer libressl
    - MINOR: vars: Move UPDATEONLY flag test to vars_set_ifexist
    - MINOR: vars: Set variable type to ANY upon creation
    - MINOR: vars: Delay variable content freeing in var_set function
    - MINOR: vars: Parse optional conditions passed to the set-var converter
    - MINOR: vars: Parse optional conditions passed to the set-var actions
    - MEDIUM: vars: Enable optional conditions to set-var converter and actions
    - DOC: vars: Add documentation about the set-var conditions
    - REGTESTS: vars: Add new test for conditional set-var
    - MINOR: quic: Attach timer task to thread for the connection.
    - CLEANUP: quic_frame: Remove a useless suffix to STOP_SENDING
    - MINOR: quic: Add traces for STOP_SENDING frame and modify others
    - CLEANUP: quic: Remove cdata_len from quic_tx_packet struct
    - MINOR: quic: Enable TLS 0-RTT if needed
    - MINOR: quic: No TX secret at EARLY_DATA encryption level
    - MINOR: quic: Add quic_set_app_ops() function
    - MINOR: ssl_sock: Set the QUIC application from ssl_sock_advertise_alpn_protos.
    - MINOR: quic: Make xprt support 0-RTT.
    - MINOR: qpack: Missing check for truncated QPACK fields
    - CLEANUP: quic: Comment fix for qc_strm_cpy()
    - MINOR: hq_interop: Stop BUG_ON() truncated streams
    - MINOR: quic: Do not mix packet number space and connection flags
    - CLEANUP: quic: Shorten a litte bit the traces in lstnr_rcv_pkt()
    - MINOR: mux-quic: fix trace on stream creation
    - CLEANUP: quic: fix spelling mistake in a trace
    - CLEANUP: quic: rename quic_conn conn to qc in quic_conn_free
    - MINOR: quic: add missing lock on cid tree
    - MINOR: quic: rename constant for haproxy CIDs length
    - MINOR: quic: refactor concat DCID with address for Initial packets
    - MINOR: quic: compare coalesced packets by DCID
    - MINOR: quic: refactor DCID lookup
    - MINOR: quic: simplify the removal from ODCID tree
    - REGTESTS: vars: Remove useless ssl tunes from conditional set-var test
    - MINOR: ssl: Remove empty lines from "show ssl ocsp-response" output
    - MINOR: quic: Increase the RX buffer for each connection
    - MINOR: quic: Add a function to list remaining RX packets by encryption level
    - MINOR: quic: Stop emptying the RX buffer asap.
    - MINOR: quic: Do not expect to receive only one O-RTT packet
    - MINOR: quic: Do not forget STREAM frames received in disorder
    - MINOR: quic: Wrong packet refcount handling in qc_pkt_insert()
    - DOC: fix misspelled keyword "resolve_retries" in resolvers
    - CLEANUP: quic: rename quic_conn instances to qc
    - REORG: quic: move mux function outside of xprt
    - MINOR: quic: add reference to quic_conn in ssl context
    - MINOR: quic: add const qualifier for traces function
    - MINOR: trace: add quic_conn argument definition
    - MINOR: quic: use quic_conn as argument to traces
    - MINOR: quic: add quic_conn instance in traces for qc_new_conn
    - MINOR: quic: Add stream IDs to qcs_push_frame() traces
    - MINOR: quic: unchecked qc_retrieve_conn_from_cid() returned value
    - MINOR: quic: Wrong dropped packet skipping
    - MINOR: quic: Handle the cases of overlapping STREAM frames
    - MINOR: quic: xprt traces fixes
    - MINOR: quic: Drop asap Retry or Version Negotiation packets
    - MINOR: pools: work around possibly slow malloc_trim() during gc
    - DEBUG: ssl: make sure we never change a servername on established connections
    - MINOR: quic: Add traces for RX frames (flow control related)
    - MINOR: quic: Add CONNECTION_CLOSE phrase to trace
    - REORG: quic: remove qc_ prefix on functions which not used it directly
    - BUG/MINOR: quic: upgrade rdlock to wrlock for ODCID removal
    - MINOR: quic: remove unnecessary call to free_quic_conn_cids()
    - MINOR: quic: store ssl_sock_ctx reference into quic_conn
    - MINOR: quic: remove unnecessary if in qc_pkt_may_rm_hp()
    - MINOR: quic: replace usage of ssl_sock_ctx by quic_conn
    - MINOR: quic: delete timer task on quic_close()
    - MEDIUM: quic: implement refcount for quic_conn
    - BUG/MINOR: quic: fix potential null dereference
    - BUG/MINOR: quic: fix potential use of uninit pointer
    - BUG/MEDIUM: backend: fix possible sockaddr leak on redispatch
    - BUG/MEDIUM: peers: properly skip conn_cur from incoming messages
    - CI: Github Actions: do not show VTest failures if build failed
    - BUILD: opentracing: display warning in case of using OT_USE_VARS at compile time
    - MINOR: compat: detect support for dl_iterate_phdr()
    - MINOR: debug: add ability to dump loaded shared libraries
    - MINOR: debug: add support for -dL to dump library names at boot
    - BUG/MEDIUM: ssl: initialize correctly ssl w/ default-server
    - REGTESTS: ssl: fix ssl_default_server.vtc
    - BUG/MINOR: ssl: free the fields in srv->ssl_ctx
    - BUG/MEDIUM: ssl: free the ckch instance linked to a server
    - REGTESTS: ssl: update of a crt with server deletion
    - BUILD/MINOR: cpuset FreeBSD 14 build fix.
    - MINOR: pools: always evict oldest objects first in pool_evict_from_local_cache()
    - DOC: pool: document the purpose of various structures in the code
    - CLEANUP: pools: do not use the extra pointer to link shared elements
    - CLEANUP: pools: get rid of the POOL_LINK macro
    - MINOR: pool: allocate from the shared cache through the local caches
    - CLEANUP: pools: group list updates in pool_get_from_cache()
    - MINOR: pool: rely on pool_free_nocache() in pool_put_to_shared_cache()
    - MINOR: pool: make pool_is_crowded() always true when no shared pools are used
    - MINOR: pool: check for pool's fullness outside of pool_put_to_shared_cache()
    - MINOR: pool: introduce pool_item to represent shared pool items
    - MINOR: pool: add a function to estimate how many may be released at once
    - MEDIUM: pool: compute the number of evictable entries once per pool
    - MINOR: pools: prepare pool_item to support chained clusters
    - MINOR: pools: pass the objects count to pool_put_to_shared_cache()
    - MEDIUM: pools: centralize cache eviction in a common function
    - MEDIUM: pools: start to batch eviction from local caches
    - MEDIUM: pools: release cached objects in batches
    - OPTIM: pools: reduce local pool cache size to 512kB
    - CLEANUP: assorted typo fixes in the code and comments This is 29th iteration of typo fixes
    - CI: github actions: update OpenSSL to 3.0.1
    - BUILD/MINOR: tools: solaris build fix on dladdr.
    - BUG/MINOR: cli: fix _getsocks with musl libc
    - BUG/MEDIUM: http-ana: Preserve response's FLT_END analyser on L7 retry
    - MINOR: quic: Wrong traces after rework
    - MINOR: quic: Add trace about in flight bytes by packet number space
    - MINOR: quic: Wrong first packet number space computation
    - MINOR: quic: Wrong packet number space computation for PTO
    - MINOR: quic: Wrong loss time computation in qc_packet_loss_lookup()
    - MINOR: quic: Wrong ack_delay compution before calling quic_loss_srtt_update()
    - MINOR: quic: Remove nb_pto_dgrams quic_conn struct member
    - MINOR: quic: Wrong packet number space trace in qc_prep_pkts()
    - MINOR: quic: Useless test in qc_prep_pkts()
    - MINOR: quic: qc_prep_pkts() code moving
    - MINOR: quic: Speeding up Handshake Completion
    - MINOR: quic: Probe Initial packet number space more often
    - MINOR: quic: Probe several packet number space upon timer expiration
    - MINOR: quic: Comment fix.
    - MINOR: quic: Improve qc_prep_pkts() flexibility
    - MINOR: quic: Do not drop secret key but drop the CRYPTO data
    - MINOR: quic: Prepare Handshake packets asap after completed handshake
    - MINOR: quic: Flag asap the connection having reached the anti-amplification limit
    - MINOR: quic: PTO timer too often reset
    - MINOR: quic: Re-arm the PTO timer upon datagram receipt
    - MINOR: proxy: add option idle-close-on-response
    - MINOR: cpuset: switch to sched_setaffinity for FreeBSD 14 and above.
    - CI: refactor spelling check
    - CLEANUP: assorted typo fixes in the code and comments
    - BUILD: makefile: add -Wno-atomic-alignment to work around clang abusive warning
    - MINOR: quic: Only one CRYPTO frame by encryption level
    - MINOR: quic: Missing retransmission from qc_prep_fast_retrans()
    - MINOR: quic: Non-optimal use of a TX buffer
    - BUG/MEDIUM: mworker: don't use _getsocks in wait mode
    - BUG/MINOR: ssl: Store client SNI in SSL context in case of ClientHello error
    - BUG/MAJOR: mux-h1: Don't decrement .curr_len for unsent data
    - DOC: internals: document the pools architecture and API
    - CI: github actions: clean default step conditions
    - BUILD: cpuset: fix build issue on macos introduced by previous change
    - MINOR: quic: Remaining TRACEs with connection as firt arg
    - MINOR: quic: Reset ->conn quic_conn struct member when calling qc_release()
    - MINOR: quic: Flag the connection as being attached to a listener
    - MINOR: quic: Wrong CRYPTO frame concatenation
    - MINOR: quid: Add traces quic_close() and quic_conn_io_cb()
    - REGTESTS: ssl: Fix ssl_errors regtest with OpenSSL 1.0.2
    - MINOR: quic: Do not dereference ->conn quic_conn struct member
    - MINOR: quic: fix return of quic_dgram_read
    - MINOR: quic: add config parse source file
    - MINOR: quic: implement Retry TLS AEAD tag generation
    - MEDIUM: quic: implement Initial token parsing
    - MINOR: quic: define retry_source_connection_id TP
    - MEDIUM: quic: implement Retry emission
    - MINOR: quic: free xprt tasklet on its thread
    - BUG/MEDIUM: connection: properly leave stopping list on error
    - MINOR: pools: enable pools with DEBUG_FAIL_ALLOC as well
    - MINOR: quic: As server, skip 0-RTT packet number space
    - MINOR: quic: Do not wakeup the I/O handler before the mux is started
    - BUG/MEDIUM: htx: Adjust length to add DATA block in an empty HTX buffer
    - CI: github actions: use cache for OpenTracing
    - BUG/MINOR: httpclient: don't send an empty body
    - BUG/MINOR: httpclient: set default Accept and User-Agent headers
    - BUG/MINOR: httpclient/lua: don't pop the lua stack when getting headers
    - BUILD/MINOR: fix solaris build with clang.
    - BUG/MEDIUM: server: avoid changing healthcheck ctx with set server ssl
    - CI: refactor OpenTracing build script
    - DOC: management: mark "set server ssl" as deprecated
    - MEDIUM: cli: yield between each pipelined command
    - MINOR: channel: add new function co_getdelim() to support multiple delimiters
    - BUG/MINOR: cli: avoid O(bufsize) parsing cost on pipelined commands
    - MEDIUM: h2/hpack: emit a Dynamic Table Size Update after settings change
    - MINOR: quic: Retransmit the TX frames in the same order
    - MINOR: quic: Remove the packet number space TX MT_LIST
    - MINOR: quic: Splice the frames which could not be added to packets
    - MINOR: quic: Add the number of TX bytes to traces
    - CLEANUP: quic: Replace <nb_pto_dgrams> by <probe>
    - MINOR: quic: Send two ack-eliciting packets when probing packet number spaces
    - MINOR: quic: Probe regardless of the congestion control
    - MINOR: quic: Speeding up handshake completion
    - MINOR: quic: Release RX Initial packets asap
    - MINOR: quic: Release asap TX frames to be transmitted
    - MINOR: quic: Probe even if coalescing
    - BUG/MEDIUM: cli: Never wait for more data on client shutdown
    - BUG/MEDIUM: mcli: do not try to parse empty buffers
    - BUG/MEDIUM: mcli: always realign wrapping buffers before parsing them
    - BUG/MINOR: stream: make the call_rate only count the no-progress calls
    - MINOR: quic: do not use quic_conn after dropping it
    - MINOR: quic: adjust quic_conn refcount decrement
    - MINOR: quic: fix race-condition on xprt tasklet free
    - MINOR: quic: free SSL context on quic_conn free
    - MINOR: quic: Add QUIC_FT_RETIRE_CONNECTION_ID parsing case
    - MINOR: quic: Wrong packet number space selection
    - DEBUG: pools: add new build option DEBUG_POOL_INTEGRITY
    - MINOR: quic: add missing include in quic_sock
    - MINOR: quic: fix indentation in qc_send_ppkts
    - MINOR: quic: remove dereferencement of connection when possible
    - MINOR: quic: set listener accept cb on parsing
    - MEDIUM: quic/ssl: add new ex data for quic_conn
    - MINOR: quic: initialize ssl_sock_ctx alongside the quic_conn
    - MINOR: ssl: fix build in release mode
    - MINOR: pools: partially uninline pool_free()
    - MINOR: pools: partially uninline pool_alloc()
    - MINOR: pools: prepare POOL_EXTRA to be split into multiple extra fields
    - MINOR: pools: extend pool_cache API to pass a pointer to a caller
    - DEBUG: pools: add new build option DEBUG_POOL_TRACING
    - DEBUG: cli: add a new "debug dev fd" expert command
    - MINOR: fd: register the write side of the poller pipe as well
    - CI: github actions: use cache for SSL libs
    - BUILD: debug/cli: condition test of O_ASYNC to its existence
    - BUILD: pools: fix build error on DEBUG_POOL_TRACING
    - MINOR: quic: refactor header protection removal
    - MINOR: quic: handle app data according to mux/connection layer status
    - MINOR: quic: refactor app-ops initialization
    - MINOR: receiver: define a flag for local accept
    - MEDIUM: quic: flag listener for local accept
    - MINOR: quic: do not manage connection in xprt snd_buf
    - MINOR: quic: remove wait handshake/L6 flags on init connection
    - MINOR: listener: add flags field
    - MINOR: quic: define QUIC flag on listener
    - MINOR: quic: create accept queue for QUIC connections
    - MINOR: listener: define per-thr struct
    - MAJOR: quic: implement accept queue
    - CLEANUP: mworker: simplify mworker_free_child()
    - BUILD/DEBUG: lru: update the standalone code to support the revision
    - DEBUG: lru: use a xorshift generator in the testing code
    - BUG/MAJOR: compiler: relax alignment constraints on certain structures
    - BUG/MEDIUM: fd: always align fdtab[] to 64 bytes
    - MINOR: quic: No DCID length for datagram context
    - MINOR: quic: Comment fix about the token found in Initial packets
    - MINOR: quic: Get rid of a struct buffer in quic_lstnr_dgram_read()
    - MINOR: quic: Remove the QUIC haproxy server packet parser
    - MINOR: quic: Add new defintion about DCIDs offsets
    - MINOR: quic: Add a list to QUIC sock I/O handler RX buffer
    - MINOR: quic: Allocate QUIC datagrams from sock I/O handler
    - MINOR: proto_quic: Allocate datagram handlers
    - MINOR: quic: Pass CID as a buffer to quic_get_cid_tid()
    - MINOR: quic: Convert quic_dgram_read() into a task
    - CLEANUP: quic: Remove useless definition
    - MINOR: proto_quic: Wrong allocations for TX rings and RX bufs
    - MINOR: quic: Do not consume the RX buffer on QUIC sock i/o handler side
    - MINOR: quic: Do not reset a full RX buffer
    - MINOR: quic: Attach all the CIDs to the same connection
    - MINOR: quic: Make usage of by datagram handler trees
    - MEDIUM: da: new optional data file download scheduler service.
    - MEDIUM: da: update doc and build for new scheduler mode service.
    - MEDIUM: da: update module to handle schedule mode.
    - MINOR: quic: Drop Initial packets with wrong ODCID
    - MINOR: quic: Wrong RX buffer tail handling when no more contiguous data
    - MINOR: quic: Iterate over all received datagrams
    - MINOR: quic: refactor quic CID association with threads
    - BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names
    - DEV: flags: Add missing flags
    - BUG/MINOR: sink: Use the right field in appctx context in release callback
    - MINOR: sock: move the unused socket cleaning code into its own function
    - BUG/MEDIUM: mworker: close unused transferred FDs on load failure
    - BUILD: atomic: make the old HA_ATOMIC_LOAD() support const pointers
    - BUILD: cpuset: do not use const on the source of CPU_AND/CPU_ASSIGN
    - BUILD: checks: fix inlining issue on set_srv_agent_[addr,port}
    - BUILD: vars: avoid overlapping field initialization
    - BUILD: server-state: avoid using not-so-portable isblank()
    - BUILD: mux_fcgi: avoid aliasing of a const struct in traces
    - BUILD: tree-wide: mark a few numeric constants as explicitly long long
    - BUILD: tools: fix warning about incorrect cast with dladdr1()
    - BUILD: task: use list_to_mt_list() instead of casting list to mt_list
    - BUILD: mworker: include tools.h for platforms without unsetenv()
    - BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload
    - MINOR: mworker: set the master side of ipc_fd in the worker to -1
    - MINOR: mworker: allocate and initialize a mworker_proc
    - CI: Consistently use actions/checkout@v2
    - REGTESTS: Remove REQUIRE_VERSION=1.8 from all tests
    - MINOR: mworker: sets used or closed worker FDs to -1
    - MINOR: quic: Try to accept 0-RTT connections
    - MINOR: quic: Do not try to treat 0-RTT packets without started mux
    - MINOR: quic: Do not try to accept a connection more than one time
    - MINOR: quic: Initialize the connection timer asap
    - MINOR: quic: Do not use connection struct xprt_ctx too soon
    - Revert "MINOR: mworker: sets used or closed worker FDs to -1"
    - BUILD: makefile: avoid testing all -Wno-* options when not needed
    - BUILD: makefile: validate support for extra warnings by batches
    - BUILD: makefile: only compute alternative options if required
    - DEBUG: fd: make sure we never try to insert/delete an impossible FD number
    - MINOR: mux-quic: add comment
    - MINOR: mux-quic: properly initialize qcc flags
    - MINOR: mux-quic: do not consider CONNECTION_CLOSE for the moment
    - MINOR: mux-quic: create a timeout task
    - MEDIUM: mux-quic: delay the closing with the timeout
    - MINOR: mux-quic: release idle conns on process stopping
    - MINOR: listener: replace the listener's spinlock with an rwlock
    - BUG/MEDIUM: listener: read-lock the listener during accept()
    - MINOR: mworker/cli: set expert/experimental mode from the CLI

3 years agoMINOR: mworker/cli: set expert/experimental mode from the CLI
William Lallemand [Tue, 1 Feb 2022 15:08:50 +0000 (16:08 +0100)] 
MINOR: mworker/cli: set expert/experimental mode from the CLI

Allow to set the master CLI in expert or experimental mode. No command
within the master are unlocked yet, but it gives the ability to send
expert or experimental commands to the workers.

    echo "@1; experimental-mode on; del server be1/s2" | socat /var/run/haproxy.master -
    echo "experimental-mode on; @1 del server be1/s2" | socat /var/run/haproxy.master -

3 years agoBUG/MEDIUM: listener: read-lock the listener during accept()
Willy Tarreau [Tue, 1 Feb 2022 15:37:00 +0000 (16:37 +0100)] 
BUG/MEDIUM: listener: read-lock the listener during accept()

Listeners might be disabled by other threads while running in
listener_accept() due to a stopping condition or possibly a rebinding
error after a failed stop/start. When this happens, the listener's FD
is -1 and accesses made by the lower layers to fdtab[-1] do not end up
well. This can occasionally be noticed if running at high connection
rates in master-worker mode when compiled with ASAN and hammered with
10 reloads per second. From time to time an out-of-bounds error will
be reported.

One approach could consist in keeping a copy of critical information
such as the FD before proceeding but that's not correct since in case of
close() the FD might be reassigned to another connection for example.

In fact what is needed is to read-lock the listener during this operation
so that it cannot change while we're touching it.

Tests have shown that using a spinlock only does generally work well but
it doesn't scale much with threads and we can see listener_accept() eat
10-15% CPU on a 24 thread machine at 300k conn/s. For this reason the
lock was turned to an rwlock by previous commit and this patch only takes
the read lock to make sure other operations do not change the listener's
state while threads are accepting connections. With this approach, no
performance loss was noticed at all and listener_accept() doesn't appear
in perf top.

This ought to be backported to about all branches that make use of the
unlocked listeners, but in practice it seems to mostly concern 2.3 and
above, since 2.2 and older will take the FD in the argument (and the
race exists there, this FD could end up being reassigned in parallel
but there's not much that can be done there to prevent that race; at
least a permanent error will be reported).

For backports, the current approach is preferred, with a preliminary
backport of previous commit "MINOR: listener: replace the listener's
spinlock with an rwlock". However if for any reason this commit cannot
be backported, the current patch can be modified to simply take a
spinlock (tested and works), it will just impact high performance
workloads (like DDoS protection).

3 years agoMINOR: listener: replace the listener's spinlock with an rwlock
Willy Tarreau [Tue, 1 Feb 2022 15:23:00 +0000 (16:23 +0100)] 
MINOR: listener: replace the listener's spinlock with an rwlock

We'll need to lock the listener a little bit more during accept() and
tests show that a spinlock is a massive performance killer, so let's
first switch to an rwlock for this lock.

This patch might have to be backported for the next patch to work, and
if so, the change is almost mechanical (look for LISTENER_LOCK), but do
not forget about the few HA_SPIN_INIT() in the file. There's no reference
to this lock outside of listener.c nor listener-t.h.

3 years agoMINOR: mux-quic: release idle conns on process stopping
Amaury Denoyelle [Mon, 31 Jan 2022 14:41:14 +0000 (15:41 +0100)] 
MINOR: mux-quic: release idle conns on process stopping

Implement the idle frontend connection cleanup for QUIC mux. Each
connection is registered on the mux_stopping_list. On process closing,
the mux is notified via a new function qc_wake. This function immediatly
release the connection if the parent proxy is stopped.

This allows to quickly close the process even if there is QUIC
connection stucked on timeout.

3 years agoMEDIUM: mux-quic: delay the closing with the timeout
Amaury Denoyelle [Tue, 1 Feb 2022 09:33:09 +0000 (10:33 +0100)] 
MEDIUM: mux-quic: delay the closing with the timeout

Do not close immediatly the connection if there is no bidirectional
stream opened. Schedule instead the mux timeout when this condition is
verified. On the timer expiration, the mux/connection can be freed.

3 years agoMINOR: mux-quic: create a timeout task
Amaury Denoyelle [Thu, 13 Jan 2022 15:28:06 +0000 (16:28 +0100)] 
MINOR: mux-quic: create a timeout task

This task will be used to schedule a timer when there is no activity on
the mux. The timeout is set via the "timeout client" from the
configuration file.

The timeout task process schedule the timeout only on specific
conditions. Currently, it's done if there is no opened bidirectional
stream.

For now this task is not used. This will be implemented in the following
commit.

3 years agoMINOR: mux-quic: do not consider CONNECTION_CLOSE for the moment
Amaury Denoyelle [Tue, 1 Feb 2022 14:15:11 +0000 (15:15 +0100)] 
MINOR: mux-quic: do not consider CONNECTION_CLOSE for the moment

Remove the condition on CONNECTION_CLOSE reception to close immediately
streams. It can cause some crash as the QUIC xprt layer still access the
qcs to send data and handle ACK.

The whole interface and buffering between QUIC xprt and mux must be
properly reorganized to better handle this case. Once this is done, it
may have some sense to free the qcs streams on CONNECTION_CLOSE
reception.

3 years agoMINOR: mux-quic: properly initialize qcc flags
Amaury Denoyelle [Tue, 1 Feb 2022 14:14:24 +0000 (15:14 +0100)] 
MINOR: mux-quic: properly initialize qcc flags

Set qcc.flags to 0 on qc_init.

3 years agoMINOR: mux-quic: add comment
Amaury Denoyelle [Tue, 1 Feb 2022 09:16:05 +0000 (10:16 +0100)] 
MINOR: mux-quic: add comment

Explain the qc_release_detached_streams function purpose and interface.
Most notably the return code which is the count of released streams.

3 years agoDEBUG: fd: make sure we never try to insert/delete an impossible FD number
Willy Tarreau [Mon, 31 Jan 2022 19:05:02 +0000 (20:05 +0100)] 
DEBUG: fd: make sure we never try to insert/delete an impossible FD number

It's among the cases that would provoke memory corruption, let's add
some tests against negative FDs and those larger than the table. This
must never ever happen and would currently result in silent corruption
or a crash. Better have a noticeable one exhibiting the call chain if
that were to happen.

3 years agoBUILD: makefile: only compute alternative options if required
Willy Tarreau [Mon, 31 Jan 2022 14:27:58 +0000 (15:27 +0100)] 
BUILD: makefile: only compute alternative options if required

Currently, the way the "cc-opt-alt" macro works consists in always
pre-calculating the alternative value for the case the main one would
not work, and pass both to an "if" clause in shell. Most of the time
we evaluate the second one for no reason.

Let's change this to use an internal "if" function instead, and directly
pass both option names to cc-opt-alt instead of passing a pre-calculated
expression. This saves one fork/exec per option and makes the option
easier to use.

3 years agoBUILD: makefile: validate support for extra warnings by batches
Willy Tarreau [Mon, 31 Jan 2022 14:10:14 +0000 (15:10 +0100)] 
BUILD: makefile: validate support for extra warnings by batches

The makefile takes quite some time to check supported warning options
and that's getting quite annoying. Most of the time all the tested ones
are quite legacy and well supported, so let's first try to validate
them all at once, and only if they fail, test them individually.

Doing so reduces the number of calls to the compiler to ~4 during the
startup, which is much better.

3 years agoBUILD: makefile: avoid testing all -Wno-* options when not needed
Willy Tarreau [Mon, 31 Jan 2022 10:54:16 +0000 (11:54 +0100)] 
BUILD: makefile: avoid testing all -Wno-* options when not needed

We already have 9 different warning shutup options and this list grows
with each new version. Testing for their support takes some time at the
makefile's initialisation which is visible on all options (make clean
etc). Some compilers like clang are extremely slow to validate them all
and spend roughly half a second on modern machines to validate all
options. And some compilers are happier than others when passed a -Wno-*
option they do not know:
  - gcc < 4 complains loudly
  - gcc 4 and above do not say anything, unless there is already another
    warning, in which case they will report about the unknown option as
    well, but without affecting the return code
  - clang by default rejects unknown options but supports a special option
    -Wno-unknown-warning-option to silently ignore them

This patch improves the situation a bit by detecting if the compiler
already supports random options, only supports them when called with
-Wno-unknown-warning-option, or not at all. Based on this, a variable
is set to indicate if we can avoid testing for all unknown options and
assume they are supported, and another one is set to hold the optionally
required option to shut the warning. This results in almost halving the
makefile's startup time, which is particularly appreciable with latest
compilers which become really fat (the other half is caused by the same
tests on various cc-opt).

3 years agoRevert "MINOR: mworker: sets used or closed worker FDs to -1"
William Lallemand [Mon, 31 Jan 2022 18:06:07 +0000 (19:06 +0100)] 
Revert "MINOR: mworker: sets used or closed worker FDs to -1"

This reverts commit ea7371e93484cd55d712abd720f47bc5fcaa9246.

This can't work correctly as we need this FD in the worker to be
inserted in the fdtab. The correct way to do it would be to cleanup the
mworker_proc in the master after the fork().

3 years agoMINOR: quic: Do not use connection struct xprt_ctx too soon
Frédéric Lécaille [Mon, 31 Jan 2022 09:37:07 +0000 (10:37 +0100)] 
MINOR: quic: Do not use connection struct xprt_ctx too soon

In fact the xprt_ctx of the connection is first stored into quic_conn
struct as soon as it is initialized from qc_conn_alloc_ssl_ctx().
As quic_conn_init_timer() is run after this function, we can associate
the timer context of the timer to the one from the quic_conn struct.

3 years agoMINOR: quic: Initialize the connection timer asap
Frédéric Lécaille [Mon, 31 Jan 2022 09:16:18 +0000 (10:16 +0100)] 
MINOR: quic: Initialize the connection timer asap

We must move this initialization from xprt_start() callback, which
comes too late (after handshake completion for 1RTT session). This timer must be
usable as soon as we have packets to send/receive. Let's initialize it after
the TLS context is initialized in qc_conn_alloc_ssl_ctx(). This latter function
initializes I/O handler task (quic_conn_io_cb) to send/receive packets.

3 years agoMINOR: quic: Do not try to accept a connection more than one time
Frédéric Lécaille [Fri, 28 Jan 2022 20:43:48 +0000 (21:43 +0100)] 
MINOR: quic: Do not try to accept a connection more than one time

We add a new flag to mark a connection as already enqueued for acception.
This is useful for 0-RTT session where a connection is first enqueued for
acception as soon as 0-RTT RX secrets could be derived. Then as for any other
connection, we could accept one more time this connection after handshake
completion which lead to very bad side effects.

Thank you to Amaury for this nice patch.

3 years agoMINOR: quic: Do not try to treat 0-RTT packets without started mux
Frédéric Lécaille [Fri, 28 Jan 2022 20:41:06 +0000 (21:41 +0100)] 
MINOR: quic: Do not try to treat 0-RTT packets without started mux

We proceed the same was as for 1-RTT packets: we do not try to treat
them until the mux is started.

3 years agoMINOR: quic: Try to accept 0-RTT connections
Frédéric Lécaille [Fri, 28 Jan 2022 20:38:45 +0000 (21:38 +0100)] 
MINOR: quic: Try to accept 0-RTT connections

When a listener managed to derive 0-RTT RX secrets we consider it accepted
the early data. So we enqueue the connection into the accept queue.

3 years agoMINOR: mworker: sets used or closed worker FDs to -1
William Lallemand [Mon, 31 Jan 2022 10:01:24 +0000 (11:01 +0100)] 
MINOR: mworker: sets used or closed worker FDs to -1

mworker_cli_sockpair_new() is used to create the socketpair CLI listener of
the worker. Its FD is referenced in the mworker_proc structure, however,
once it's assigned to the listener the reference should be removed so we
don't use it accidentally.

The same must be done in case of errors if the FDs were already closed.

3 years agoREGTESTS: Remove REQUIRE_VERSION=1.8 from all tests
Tim Duesterhus [Fri, 28 Jan 2022 17:09:20 +0000 (18:09 +0100)] 
REGTESTS: Remove REQUIRE_VERSION=1.8 from all tests

HAProxy 1.8 is the lowest supported version, thus this always matches.

see 1b095cac9468d0c3eeb157e9b1a2947487bd3c83

3 years agoCI: Consistently use actions/checkout@v2
Tim Duesterhus [Fri, 28 Jan 2022 17:45:37 +0000 (18:45 +0100)] 
CI: Consistently use actions/checkout@v2

v2 is the current version of the checkout action and faster than v1.

3 years agoMINOR: mworker: allocate and initialize a mworker_proc
William Lallemand [Fri, 28 Jan 2022 20:11:41 +0000 (21:11 +0100)] 
MINOR: mworker: allocate and initialize a mworker_proc

mworker_proc_new() allocates and initializes correctly a mworker_proc
structure.

3 years agoMINOR: mworker: set the master side of ipc_fd in the worker to -1
William Lallemand [Fri, 28 Jan 2022 20:56:24 +0000 (21:56 +0100)] 
MINOR: mworker: set the master side of ipc_fd in the worker to -1

Once the child->ipc_fd[0] is closed in the worker, set the value to -1
so we don't reference a closed FD anymore.

3 years agoBUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload
William Lallemand [Fri, 28 Jan 2022 20:17:30 +0000 (21:17 +0100)] 
BUG/MINOR: mworker: fix a FD leak of a sockpair upon a failed reload

When starting HAProxy in master-worker, the master pre-allocate a struct
mworker_proc and do a socketpair() before the configuration parsing. If
the configuration loading failed, the FD are never closed because they
aren't part of listener, they are not even in the fdtab.

This patch fixes the issue by cleaning the mworker_proc structure that
were not asssigned a process, and closing its FDs.

Must be backported as far as 2.0, the srv_drop() only frees the memory
and could be dropped since it's done before an exec().

3 years agoBUILD: mworker: include tools.h for platforms without unsetenv()
Willy Tarreau [Fri, 28 Jan 2022 11:25:14 +0000 (12:25 +0100)] 
BUILD: mworker: include tools.h for platforms without unsetenv()

In this case we fall back to my_unsetenv() thus we need tools.h
to avoid a warning.

3 years agoBUILD: task: use list_to_mt_list() instead of casting list to mt_list
Willy Tarreau [Fri, 28 Jan 2022 08:48:12 +0000 (09:48 +0100)] 
BUILD: task: use list_to_mt_list() instead of casting list to mt_list

There were a few casts of list* to mt_list* that were upsetting some
old compilers (not sure about the effect on others). We had created
list_to_mt_list() purposely for this, let's use it instead of applying
this cast.

3 years agoBUILD: tools: fix warning about incorrect cast with dladdr1()
Willy Tarreau [Fri, 28 Jan 2022 08:42:29 +0000 (09:42 +0100)] 
BUILD: tools: fix warning about incorrect cast with dladdr1()

dladdr1() is used on glibc and takes a void**, but we pass it a
const ElfW(Sym)** and some compilers complain that we're aliasing.
Let's just set a may_alias attribute on the local variable to
address this. There's no need to backport this unless warnings are
reported on older distros or uncommon compilers.

3 years agoBUILD: tree-wide: mark a few numeric constants as explicitly long long
Willy Tarreau [Fri, 28 Jan 2022 08:39:24 +0000 (09:39 +0100)] 
BUILD: tree-wide: mark a few numeric constants as explicitly long long

At a few places in the code the switch/case ond flags are tested against
64-bit constants without explicitly being marked as long long. Some
32-bit compilers complain that the constant is too large for a long, and
other likely always use long long there. Better fix that as it's uncertain
what others which do not complain do. It may be backported to avoid doubts
on uncommon platforms if needed, as it touches very few areas.

3 years agoBUILD: mux_fcgi: avoid aliasing of a const struct in traces
Willy Tarreau [Fri, 28 Jan 2022 08:36:35 +0000 (09:36 +0100)] 
BUILD: mux_fcgi: avoid aliasing of a const struct in traces

fcgi_trace() declares fconn as a const and casts its mbuf array to
(struct buffer*), which rightfully upsets some older compilers. Better
just declare it as a writable variable and get rid of the cast. It's
harmless anyway. This has been there since 2.1 with commit 5c0f859c2
("MINOR: mux-fcgi/trace: Register a new trace source with its events")
and doens't need to be backported though it would not harm either.

3 years agoBUILD: server-state: avoid using not-so-portable isblank()
Willy Tarreau [Fri, 28 Jan 2022 08:32:43 +0000 (09:32 +0100)] 
BUILD: server-state: avoid using not-so-portable isblank()

Once in a while we get rid of this one. isblank() is missing on old
C libraries and only matches two values, so let's just replace it.
It was brought with this commit in 2.4:

  0bf268e18 ("MINOR: server: Be more strict on the server-state line parsing")

It may be backported though it's really not important.

3 years agoBUILD: vars: avoid overlapping field initialization
Willy Tarreau [Fri, 28 Jan 2022 08:22:07 +0000 (09:22 +0100)] 
BUILD: vars: avoid overlapping field initialization

Compiling vars.c with gcc 4.2 shows that we're initializing some local
structs field members in a not really portable way:

src/vars.c: In function 'vars_parse_cli_set_var':
src/vars.c:1195: warning: initialized field overwritten
src/vars.c:1195: warning: (near initialization for 'px.conf.args')
src/vars.c:1195: warning: initialized field overwritten
src/vars.c:1195: warning: (near initialization for 'px.conf')
src/vars.c:1201: warning: initialized field overwritten
src/vars.c:1201: warning: (near initialization for 'rule.conf')

It's totally harmless anyway, but better clean this up.

3 years agoBUILD: checks: fix inlining issue on set_srv_agent_[addr,port}
Willy Tarreau [Fri, 28 Jan 2022 08:16:47 +0000 (09:16 +0100)] 
BUILD: checks: fix inlining issue on set_srv_agent_[addr,port}

These functions are declared as external functions in check.h and
as inline functions in check.c. Let's move them as static inline in
check.h. This appeared in 2.4 with the following commits:

  4858fb2e1 ("MEDIUM: check: align agentaddr and agentport behaviour")
  1c921cd74 ("BUG/MINOR: check: consitent way to set agentaddr")

While harmless (it only triggers build warnings with some gcc 4.x),
it should probably be backported where the paches above are present
to keep the code consistent.

3 years agoBUILD: cpuset: do not use const on the source of CPU_AND/CPU_ASSIGN
Willy Tarreau [Fri, 28 Jan 2022 08:10:52 +0000 (09:10 +0100)] 
BUILD: cpuset: do not use const on the source of CPU_AND/CPU_ASSIGN

The man page indicates that CPU_AND() and CPU_ASSIGN() take a variable,
not a const on the source, even though it doesn't make much sense. But
with older libcs, this triggers a build warning:

  src/cpuset.c: In function 'ha_cpuset_and':
  src/cpuset.c:53: warning: initialization discards qualifiers from pointer target type
  src/cpuset.c: In function 'ha_cpuset_assign':
  src/cpuset.c:101: warning: initialization discards qualifiers from pointer target type

Better stick stricter to the documented API as this is really harmless
here. There's no need to backport it (unless build issues are reported,
which is quite unlikely).

3 years agoBUILD: atomic: make the old HA_ATOMIC_LOAD() support const pointers
Willy Tarreau [Fri, 28 Jan 2022 07:52:57 +0000 (08:52 +0100)] 
BUILD: atomic: make the old HA_ATOMIC_LOAD() support const pointers

We have an implementation of atomic ops for older versions of gcc that
do not provide the __builtin_* API (< 4.4). Recent changes to the pools
broke that in pool_releasable() by having a load from a const pointer,
which doesn't work there due to a temporary local variable that is
declared then assigned. Let's make use of a compount statement to assign
it a value when declaring it.

There's no need to backport this.

3 years agoBUG/MEDIUM: mworker: close unused transferred FDs on load failure
Willy Tarreau [Fri, 28 Jan 2022 17:40:06 +0000 (18:40 +0100)] 
BUG/MEDIUM: mworker: close unused transferred FDs on load failure

When the master process is reloaded on a new config, it will try to
connect to the previous process' socket to retrieve all known
listening FDs to be reused by the new listeners. If listeners were
removed, their unused FDs are simply closed.

However there's a catch. In case a socket fails to bind, the master
will cancel its startup and swithc to wait mode for a new operation
to happen. In this case it didn't close the possibly remaining FDs
that were left unused.

It is very hard to hit this case, but it can happen during a
troubleshooting session with fat fingers. For example, let's say
a config runs like this:

   frontend ftp
        bind 1.2.3.4:20000-29999

The admin wants to extend the port range down to 10000-29999 and
by mistake ends up with:

   frontend ftp
        bind 1.2.3.41:20000-29999

Upon restart the bind will fail if the address is not present, and the
master will then switch to wait mode without releasing the previous FDs
for 1.2.3.4:20000-29999 since they're now apparently unused. Then once
the admin fixes the config and does:

   frontend ftp
        bind 1.2.3.4:10000-29999

The service will start, but will bind new sockets, half of them
overlapping with the previous ones that were not properly closed. This
may result in a startup error (if SO_REUSEPORT is not enabled or not
available), in a FD number exhaustion (if the error is repeated many
times), or in connections being randomly accepted by the process if
they sometimes land on the old FD that nobody listens on.

This patch will need to be backported as far as 1.8, and depends on
previous patch:

   MINOR: sock: move the unused socket cleaning code into its own function

Note that before 2.3 most of the code was located inside haproxy.c, so
the patch above should probably relocate the function there instead of
sock.c.

3 years agoMINOR: sock: move the unused socket cleaning code into its own function
Willy Tarreau [Fri, 28 Jan 2022 17:28:18 +0000 (18:28 +0100)] 
MINOR: sock: move the unused socket cleaning code into its own function

The startup code used to scan the list of unused sockets retrieved from
an older process, and to close them one by one. This also required that
the knowledge of the internal storage of these temporary sockets was
known from outside sock.c and that the code was copy-pasted at every
call place.

This patch moves this into sock.c under the name
sock_drop_unused_old_sockets(), and removes the xfer_sock_list
definition from sock.h since the rest of the code doesn't need to know
this.

This cleanup is minimal and preliminary to a future fix that will need
to be backported to all versions featuring FD transfers over the CLI.

3 years agoBUG/MINOR: sink: Use the right field in appctx context in release callback
Christopher Faulet [Fri, 14 Jan 2022 14:03:22 +0000 (15:03 +0100)] 
BUG/MINOR: sink: Use the right field in appctx context in release callback

In the release callback, ctx.peers was used instead of ctx.sft. Concretly,
it is not an issue because the appctx context is an union and these both
fields are structures with a unique pointer. But it will be a problem if
that changes.

This patch must be backported as far as 2.2.

3 years agoDEV: flags: Add missing flags
Christopher Faulet [Tue, 18 Jan 2022 09:46:10 +0000 (10:46 +0100)] 
DEV: flags: Add missing flags

The flags dev tool was not updated since a while. Support for several flags
was missing. It is up to date now.

3 years agoBUG/MEDIUM: resolvers: Really ignore trailing dot in domain names
Christopher Faulet [Fri, 28 Jan 2022 16:47:57 +0000 (17:47 +0100)] 
BUG/MEDIUM: resolvers: Really ignore trailing dot in domain names

When a string is converted to a domain name label, the trailing dot must be
ignored. In resolv_str_to_dn_label(), there is a test to do so. However, the
trailing dot is not really ignored. The character itself is not copied but
the string index is still moved to the next char. Thus, this trailing dot is
counted in the length of the last encoded part of the domain name. Worst,
because the copy is skipped, a garbage character is included in the domain
name.

This patch should fix the issue #1528. It must be backported as far as 2.0.

3 years agoMINOR: quic: refactor quic CID association with threads
Amaury Denoyelle [Fri, 28 Jan 2022 15:02:13 +0000 (16:02 +0100)] 
MINOR: quic: refactor quic CID association with threads

Do not use an extra DCID parameter on new_quic_cid to be able to
associated a new generated CID to a thread ID. Simply do the computation
inside the function. The API is cleaner this way.

This also has the effects to improve the apparent randomness of CIDs.
With the previous version the first byte of all CIDs are identical for a
connection which could lead to privacy issue. This version may not be
totally perfect on this aspect but it improves the situation.

3 years agoMINOR: quic: Iterate over all received datagrams
Frédéric Lécaille [Fri, 28 Jan 2022 14:38:52 +0000 (15:38 +0100)] 
MINOR: quic: Iterate over all received datagrams

Make the listener datagram handler iterate over all received datagrams

3 years agoMINOR: quic: Wrong RX buffer tail handling when no more contiguous data
Frédéric Lécaille [Fri, 28 Jan 2022 12:10:24 +0000 (13:10 +0100)] 
MINOR: quic: Wrong RX buffer tail handling when no more contiguous data

The producer must know where is the tailing hole in the RX buffer
when it purges it from consumed datagram. This is done allocating
a fake datagram with the remaining number of bytes which cannot be produced
at the tail of the RX buffer as length.

3 years agoMINOR: quic: Drop Initial packets with wrong ODCID
Frédéric Lécaille [Thu, 27 Jan 2022 15:51:54 +0000 (16:51 +0100)] 
MINOR: quic: Drop Initial packets with wrong ODCID

According to the RFC 9000, the client ODCID must have a minimal length of 8 bytes.

3 years agoMEDIUM: da: update module to handle schedule mode.
David Carlier [Fri, 21 Jan 2022 20:51:20 +0000 (20:51 +0000)] 
MEDIUM: da: update module to handle schedule mode.

The DeviceAtlas addon can optionally interacts with the new service
 without change of configuration in the HAProxy part.
Note that however it requires the DeviceAtlas Identification C API
2.4.0 minimum from this point.

Signed-off-by: David Carlier <dcarlier@deviceatlas.com>
3 years agoMEDIUM: da: update doc and build for new scheduler mode service.
David Carlier [Thu, 27 Jan 2022 18:13:54 +0000 (18:13 +0000)] 
MEDIUM: da: update doc and build for new scheduler mode service.

Mentions of the new database update runtime mode and update of
the legit module and the dummy part too.
Note the DeviceAtlas C API version 2.4.0 minimum required
alongside with libCURL, libzip and libgz.

3 years agoMEDIUM: da: new optional data file download scheduler service.
David Carlier [Fri, 21 Jan 2022 20:46:40 +0000 (20:46 +0000)] 
MEDIUM: da: new optional data file download scheduler service.

New specialized service to daily handle the update of download file without
interruption of service and to be preemptively started before HAProxy.
It consists on a standalone utility which shared a memory block with
the DeviceAtlas module which handles the JSON data file update on
a daily basis.

Signed-off-by: David Carlier <dcarlier@deviceatlas.com>
3 years agoMINOR: quic: Make usage of by datagram handler trees
Frédéric Lécaille [Thu, 27 Jan 2022 14:35:56 +0000 (15:35 +0100)] 
MINOR: quic: Make usage of by datagram handler trees

The CID trees are no more attached to the listener receiver but to the
underlying datagram handlers (one by thread) which run always on the same thread.
So, any operation on these trees do not require any locking.

3 years agoMINOR: quic: Attach all the CIDs to the same connection
Frédéric Lécaille [Thu, 27 Jan 2022 14:20:31 +0000 (15:20 +0100)] 
MINOR: quic: Attach all the CIDs to the same connection

We copy the first octet of the original destination connection ID to any CID for
the connection calling new_quic_cid(). So this patch modifies only this function
to take a dcid as passed parameter.

3 years agoMINOR: quic: Do not reset a full RX buffer
Frédéric Lécaille [Thu, 27 Jan 2022 11:19:28 +0000 (12:19 +0100)] 
MINOR: quic: Do not reset a full RX buffer

As the RX buffer is not consumed by the sock i/o handler as soon as a datagram
is produced, when full an RX buffer must not be reset. The remaining room is
consumed without modifying it. The consumer has a represention of its contents:
a list of datagrams.

3 years agoMINOR: quic: Do not consume the RX buffer on QUIC sock i/o handler side
Frédéric Lécaille [Thu, 27 Jan 2022 10:31:50 +0000 (11:31 +0100)] 
MINOR: quic: Do not consume the RX buffer on QUIC sock i/o handler side

Rename quic_lstnr_dgram_read() to quic_lstnr_dgram_dispatch() to reflect its new role.
After calling this latter, the sock i/o handler must consume the buffer only if
the datagram it received is detected as wrong by quic_lstnr_dgram_dispatch().
The datagram handler task mark the datagram as consumed atomically setting ->buf
to NULL value. The sock i/o handler is responsible of flushing its RX buffer
before using it. It also keeps a datagram among the consumed ones so that
to pass it to quic_lstnr_dgram_dispatch() and prevent it from allocating a new one.

3 years agoMINOR: proto_quic: Wrong allocations for TX rings and RX bufs
Frédéric Lécaille [Thu, 27 Jan 2022 09:23:31 +0000 (10:23 +0100)] 
MINOR: proto_quic: Wrong allocations for TX rings and RX bufs

As mentionned in the comment, the tx_qrings and rxbufs members of
receiver struct must be pointers to pointers!
Modify the functions responsible of their allocations consequently.
Note that this code could work because sizeof rxbuf and sizeof tx_qrings
are greater than the size of pointer!

3 years agoCLEANUP: quic: Remove useless definition
Frédéric Lécaille [Thu, 27 Jan 2022 08:31:15 +0000 (09:31 +0100)] 
CLEANUP: quic: Remove useless definition

The quic_dgram_ctx struct has been replaced by quic_dgram struct.
There is no need to keek a typedef for a pointer to function since we
converted the UDP datagram parser (quic_dgram_read()) into a task.

3 years agoMINOR: quic: Convert quic_dgram_read() into a task
Frédéric Lécaille [Thu, 27 Jan 2022 08:15:40 +0000 (09:15 +0100)] 
MINOR: quic: Convert quic_dgram_read() into a task

quic_dgram_read() parses all the QUIC packets from a UDP datagram. It is the best
candidate to be converted into a task, because is processing data unit is the UDP
datagram received by the QUIC sock i/o handler. If correct, this datagram is
added to the context of a task, quic_lstnr_dghdlr(), a conversion of quic_dgram_read()
into a task. This task pop a datagram from an mt_list and passes it among to
the packet handler (quic_lstnr_pkt_rcv()).
Modify the quic_dgram struct to play the role of the old quic_dgram_ctx struct when
passed to quic_lstnr_pkt_rcv().
Modify the datagram handlers allocation to set their tasks to quic_lstnr_dghdlr().

3 years agoMINOR: quic: Pass CID as a buffer to quic_get_cid_tid()
Frédéric Lécaille [Wed, 26 Jan 2022 17:04:50 +0000 (18:04 +0100)] 
MINOR: quic: Pass CID as a buffer to quic_get_cid_tid()

Very minor modification so that this function might be used for a context
without CID (at datagram level).

3 years agoMINOR: proto_quic: Allocate datagram handlers
Frédéric Lécaille [Wed, 26 Jan 2022 16:45:39 +0000 (17:45 +0100)] 
MINOR: proto_quic: Allocate datagram handlers

Add quic_dghdlr new struct do define datagram handler tasks, one by thread.
Allocate them and attach them to the listener receiver part calling
quic_alloc_dghdlrs_listener() newly implemented function.

3 years agoMINOR: quic: Allocate QUIC datagrams from sock I/O handler
Frédéric Lécaille [Wed, 26 Jan 2022 15:07:16 +0000 (16:07 +0100)] 
MINOR: quic: Allocate QUIC datagrams from sock I/O handler

Add quic_dgram new structure to store information about datagrams received
by the sock I/O handler (quic_sock_fd_iocb) and its associated pool.
Implement quic_get_dgram_dcid() to retrieve the datagram DCID which must
be the same for all the packets in the datagram.
Modify quic_lstnr_dgram_read() called by the sock I/O handler to allocate
a quic_dgram each time a correct datagram is found and add it to the sock I/O
handler rxbuf dgram list.

3 years agoMINOR: quic: Add a list to QUIC sock I/O handler RX buffer
Frédéric Lécaille [Wed, 26 Jan 2022 14:55:21 +0000 (15:55 +0100)] 
MINOR: quic: Add a list to QUIC sock I/O handler RX buffer

This list will be used to store datagrams in the rxbuf struct used
by the quic_sock_fd_iocb() QUIC sock I/O handler with one rxbuf by thread.

3 years agoMINOR: quic: Add new defintion about DCIDs offsets
Frédéric Lécaille [Wed, 26 Jan 2022 14:47:33 +0000 (15:47 +0100)] 
MINOR: quic: Add new defintion about DCIDs offsets

Define the offsets of the DCIDs from the beginning of a QUIC packets.
Note that they must always be present. As QUIC servers, QUIC haproxy listeners
always use a CID, source CID on the haproxy side, which is a destination ID on the
peer side.

3 years agoMINOR: quic: Remove the QUIC haproxy server packet parser
Frédéric Lécaille [Wed, 26 Jan 2022 08:07:40 +0000 (09:07 +0100)] 
MINOR: quic: Remove the QUIC haproxy server packet parser

This function is no more used anymore, broken and uses code shared with the
listener packet parser. This is becoming anoying to continue to modify
it without testing each time we modify the code it shares with the
listener packet parser.

3 years agoMINOR: quic: Get rid of a struct buffer in quic_lstnr_dgram_read()
Frédéric Lécaille [Tue, 25 Jan 2022 21:33:11 +0000 (22:33 +0100)] 
MINOR: quic: Get rid of a struct buffer in quic_lstnr_dgram_read()

This is to be sure xprt functions do not manipulate the buffer struct
passed as parameter to quic_lstnr_dgram_read() from low level datagram
I/O callback in quic_sock.c (quic_sock_fd_iocb()).

3 years agoMINOR: quic: Comment fix about the token found in Initial packets
Frédéric Lécaille [Tue, 25 Jan 2022 20:21:56 +0000 (21:21 +0100)] 
MINOR: quic: Comment fix about the token found in Initial packets

Mention that the token is sent only by servers in both server and listener
packet parsers.
Remove a "TO DO" section in listener packet parser because there is nothing
more to do in this function about the token

3 years agoMINOR: quic: No DCID length for datagram context
Frédéric Lécaille [Tue, 25 Jan 2022 19:52:21 +0000 (20:52 +0100)] 
MINOR: quic: No DCID length for datagram context

This quic_dgram_ctx struct member is used to denote if we are parsing a new
datagram (null value), or a coalesced packet into the current datagram (non null
value). But it was never set.

3 years agoBUG/MEDIUM: fd: always align fdtab[] to 64 bytes
Willy Tarreau [Thu, 27 Jan 2022 15:10:48 +0000 (16:10 +0100)] 
BUG/MEDIUM: fd: always align fdtab[] to 64 bytes

There's a risk that fdtab is not 64-byte aligned. The first effect is that
it may cause false sharing between cache lines resulting in contention
when adjacent FDs are used by different threads. The second is related
to what is explained in commit "BUG/MAJOR: compiler: relax alignment
constraints on certain structures", i.e. that modern compilers might
make use of aligned vector operations to zero some entries, and would
crash. We do not use any memset() or so on fdtab, so the risk is almost
inexistent, but that's not a reason for violating some valid assumptions.

This patch addresses this by allocating 64 extra bytes and aligning the
structure manually (this is an extremely cheap solution for this specific
case). The original address is stored in a new variable "fdtab_addr" and
is the one that gets freed. This remains extremely simple and should be
easily backportable. A dedicated aligned allocator later would help, of
course.

This needs to be backported as far as 2.2. No issue related to this was
reported yet, but it could very well happen as compilers evolve. In
addition this should preserve high performance across restarts (i.e.
no more dependency on allocator's alignment).

3 years agoBUG/MAJOR: compiler: relax alignment constraints on certain structures
Willy Tarreau [Thu, 27 Jan 2022 14:46:19 +0000 (15:46 +0100)] 
BUG/MAJOR: compiler: relax alignment constraints on certain structures

In github bug #1517, Mike Lothian reported instant crashes on startup
on RHEL8 + gcc-11 that appeared with 2.4 when allocating a proxy.

The analysis brought us down to the THREAD_ALIGN() entries that were
placed inside the "server" struct to avoid false sharing of cache lines.
It turns out that some modern gcc make use of aligned vector operations
to manipulate some fields (e.g. memset() etc) and that these structures
allocated using malloc() are not necessarily aligned, hence the crash.

The compiler is allowed to do that because the structure claims to be
aligned. The problem is in fact that the alignment propagates to other
structures that embed it. While most of these structures are used as
statically allocated variables, some are dynamic and cannot use that.
A deeper analysis showed that struct server does this, propagates to
struct proxy, which propagates to struct spoe_config, all of which
are allocated using malloc/calloc.

A better approach would consist in usins posix_memalign(), but this one
is not available everywhere and will either need to be reimplemented
less efficiently (by always wasting 64 bytes before the area), or a
few functions will have to be specifically written to deal with the
few structures that are dynamically allocated.

But the deeper problem that remains is that it is difficult to track
structure alignment, as there's no available warning to check this.
For the long term we'll probably have to create a macro such as
"struct_malloc()" etc which takes a type and enforces an alignment
based on the one of this type. This also means propagating that to
pools as well, and it's not a tiny task.

For now, let's get rid of the forced alignment in struct server, and
replace it with extra padding. By punching 63-byte holes, we can keep
areas on separate cache lines. Doing so moderately increases the size
of the "server" structure (~+6%) but that's the best short-term option
and it's easily backportable.

This will have to be backported as far as 2.4.

Thanks to Mike for the detailed report.

3 years agoDEBUG: lru: use a xorshift generator in the testing code
Willy Tarreau [Wed, 26 Jan 2022 10:06:07 +0000 (11:06 +0100)] 
DEBUG: lru: use a xorshift generator in the testing code

The standalone testing code used to rely on rand(), but switching to a
xorshift generator speeds up the test by 7% which is important to
accurately measure the real impact of the LRU code itself.

3 years agoBUILD/DEBUG: lru: update the standalone code to support the revision
Willy Tarreau [Wed, 26 Jan 2022 10:03:59 +0000 (11:03 +0100)] 
BUILD/DEBUG: lru: update the standalone code to support the revision

The standalone testing code didn't implement the revision and didn't
build anymore, let's fix that.

3 years agoCLEANUP: mworker: simplify mworker_free_child()
William Lallemand [Thu, 27 Jan 2022 14:33:40 +0000 (15:33 +0100)] 
CLEANUP: mworker: simplify mworker_free_child()

Remove useless checks and simplify the function.

3 years agoMAJOR: quic: implement accept queue
Amaury Denoyelle [Wed, 19 Jan 2022 15:01:05 +0000 (16:01 +0100)] 
MAJOR: quic: implement accept queue

Do not proceed to direct accept when creating a new quic_conn. Wait for
the QUIC handshake to succeeds to insert the quic_conn in the accept
queue. A tasklet is then woken up to call listener_accept to accept the
quic_conn.

The most important effect is that the connection/mux layers are not
instantiated at the same time as the quic_conn. This forces to delay
some process to be sure that the mux is allocated :
* initialization of mux transport parameters
* installation of the app-ops

Also, the mux instance is not checked now to wake up the quic_conn
tasklet. This is safe because the xprt-quic code is now ready to handle
the absence of the connection/mux layers.

Note that this commit has a deep impact as it changes significantly the
lower QUIC architecture. Most notably, it breaks the 0-RTT feature.

3 years agoMINOR: listener: define per-thr struct
Amaury Denoyelle [Tue, 25 Jan 2022 15:21:47 +0000 (16:21 +0100)] 
MINOR: listener: define per-thr struct

Create a new structure li_per_thread. This is uses as an array in the
listener structure, with an entry allocated per thread. The new function
li_init_per_thr is responsible of the allocation.

For now, li_per_thread contains fields only useful for QUIC listeners.
As such, it is only allocated for QUIC listeners.

3 years agoMINOR: quic: create accept queue for QUIC connections
Amaury Denoyelle [Wed, 19 Jan 2022 14:46:11 +0000 (15:46 +0100)] 
MINOR: quic: create accept queue for QUIC connections

Create a new type quic_accept_queue to handle QUIC connections accept.
A queue will be allocated for each thread. It contains a list of
listeners which contains at least one quic_conn ready to be accepted and
the tasklet to run listener_accept for these listeners.

3 years agoMINOR: quic: define QUIC flag on listener
Amaury Denoyelle [Tue, 25 Jan 2022 16:48:47 +0000 (17:48 +0100)] 
MINOR: quic: define QUIC flag on listener

Mark QUIC listeners with the flag LI_F_QUIC_LISTENER. It is set by the
proto-quic layer on the add listener callback. This allows to override
more clearly the accept callback on quic_session_accept.

3 years agoMINOR: listener: add flags field
Amaury Denoyelle [Tue, 25 Jan 2022 16:47:09 +0000 (17:47 +0100)] 
MINOR: listener: add flags field

Define a new field in listener structure named flags.

For the moment, no flag is defined. This will be notably useful to
differentiate QUIC listeners with the implementation of a QUIC conn
accept queue.

3 years agoMINOR: quic: remove wait handshake/L6 flags on init connection
Amaury Denoyelle [Wed, 19 Jan 2022 14:58:27 +0000 (15:58 +0100)] 
MINOR: quic: remove wait handshake/L6 flags on init connection

The connection is allocated after finishing the QUIC handshake. Remove
handshake/L6 flags when initializing the connection as handshake is
finished with success at this stage.

3 years agoMINOR: quic: do not manage connection in xprt snd_buf
Amaury Denoyelle [Wed, 19 Jan 2022 14:54:23 +0000 (15:54 +0100)] 
MINOR: quic: do not manage connection in xprt snd_buf

Remove usage of connection in quic_conn_from_buf. As connection and
quic_conn are decorrelated, it is not logical to check connection flags
when using sendto.

This require to store the L4 peer address in quic_conn to be able to use
sendto.

This change is required to delay allocation of connection.

3 years agoMEDIUM: quic: flag listener for local accept
Amaury Denoyelle [Wed, 26 Jan 2022 10:56:48 +0000 (11:56 +0100)] 
MEDIUM: quic: flag listener for local accept

QUIC connections are distributed accross threads by xprt-quic according
to their CIDs. As such disable the thread selection in listener_accept
for QUIC listeners.

This prevents connection from migrating to another threads after its
allocation which can results in unexpected side-effects.

3 years agoMINOR: receiver: define a flag for local accept
Amaury Denoyelle [Wed, 19 Jan 2022 10:37:50 +0000 (11:37 +0100)] 
MINOR: receiver: define a flag for local accept

This flag is named RX_F_LOCAL_ACCEPT. It will be activated for special
receivers where connection balancing to threads is already handle
outside of listener_accept, such as with QUIC listeners.

3 years agoMINOR: quic: refactor app-ops initialization
Amaury Denoyelle [Wed, 19 Jan 2022 10:29:25 +0000 (11:29 +0100)] 
MINOR: quic: refactor app-ops initialization

Add a new function in mux-quic to install app-ops. For now this
functions is called during the ALPN negotiation of the QUIC handshake.

This change will be useful when the connection accept queue will be
implemented. It will be thus required to delay the app-ops
initialization because the mux won't be allocated anymore during the
QUIC handshake.

3 years agoMINOR: quic: handle app data according to mux/connection layer status
Amaury Denoyelle [Wed, 26 Jan 2022 08:51:28 +0000 (09:51 +0100)] 
MINOR: quic: handle app data according to mux/connection layer status

Define a new enum to represent the status of the mux/connection layer
above a quic_conn. This is important to know if it's possible to handle
application data, or if it should be buffered or dropped.

3 years agoMINOR: quic: refactor header protection removal
Amaury Denoyelle [Mon, 24 Jan 2022 17:34:52 +0000 (18:34 +0100)] 
MINOR: quic: refactor header protection removal

Adjust the function to check if header protection can be removed. It can
now be used both for a single packet in qc_lstnr_pkt_rcv and in the
quic_conn handler to handle buffered packets for a specific encryption
level.

3 years agoBUILD: pools: fix build error on DEBUG_POOL_TRACING
Willy Tarreau [Tue, 25 Jan 2022 14:56:50 +0000 (15:56 +0100)] 
BUILD: pools: fix build error on DEBUG_POOL_TRACING

When squashing commit add43fa43 ("DEBUG: pools: add new build option
DEBUG_POOL_TRACING") I managed to break the build and to fail to detect
it even after the rebase and a full rebuild :-(

3 years agoBUILD: debug/cli: condition test of O_ASYNC to its existence
Willy Tarreau [Tue, 25 Jan 2022 13:51:53 +0000 (14:51 +0100)] 
BUILD: debug/cli: condition test of O_ASYNC to its existence

David Carlier reported a build breakage on Haiku since commit
5be7c198e ("DEBUG: cli: add a new "debug dev fd" expert command")
due to O_ASYNC not being defined. Ilya also reported it broke the
build on Cygwin. It's not that portable and sometimes defined as
O_NONBLOCK for portability. But here we don't even need that, as
we already condition other flags, let's just ignore it if it does
not exist.

3 years agoCI: github actions: use cache for SSL libs
Ilya Shipitsin [Fri, 21 Jan 2022 19:00:44 +0000 (00:00 +0500)] 
CI: github actions: use cache for SSL libs

we have two kinds of SSL libs built - git based and version based.
this commit introduces caching for version based SSL libs.

3 years agoMINOR: fd: register the write side of the poller pipe as well
Willy Tarreau [Mon, 24 Jan 2022 19:33:09 +0000 (20:33 +0100)] 
MINOR: fd: register the write side of the poller pipe as well

The poller's pipe was only registered on the read side since we don't
need to poll to write on it. But this leaves some known FDs so it's
better to also register the write side with no event. This will allow
to show them in "show fd" and to avoid dumping them as unhandled FDs.

Note that the only other type of unhandled FDs left are:
  - stdin/stdout/stderr
  - epoll FDs

The later can be registered upon startup though but at least a dummy
handler would be needed to keep the fdtab clean.

3 years agoDEBUG: cli: add a new "debug dev fd" expert command
Willy Tarreau [Mon, 24 Jan 2022 19:26:09 +0000 (20:26 +0100)] 
DEBUG: cli: add a new "debug dev fd" expert command

This command will scan the whole file descriptors space to look for
existing FDs that are unknown to haproxy's fdtab, and will try to dump
a maximum number of information about them (including type, mode, device,
size, uid/gid, cloexec, O_* flags, socket types and addresses when
relevant). The goal is to help detecting inherited FDs from parent
processes as well as potential leaks.

Some of those listed are actually known but handled so deep into some
systems that they're not in the fdtab (such as epoll FDs or inter-
thread pipes). This might be refined in the future so that these ones
become known and do not appear.

Example of output:

 $ socat - /tmp/sock1 <<< "expert-mode on;debug dev fd"

    0 type=tty. mod=0620 dev=0x8803 siz=0 uid=1000 gid=5 fs=0x16 ino=0x6 getfd=+0 getfl=O_RDONLY,O_APPEND
    1 type=tty. mod=0620 dev=0x8803 siz=0 uid=1000 gid=5 fs=0x16 ino=0x6 getfd=+0 getfl=O_RDONLY,O_APPEND
    2 type=tty. mod=0620 dev=0x8803 siz=0 uid=1000 gid=5 fs=0x16 ino=0x6 getfd=+0 getfl=O_RDONLY,O_APPEND
    3 type=pipe mod=0600 dev=0 siz=0 uid=1000 gid=100 fs=0xc ino=0x18112348 getfd=+0
    4 type=epol mod=0600 dev=0 siz=0 uid=0 gid=0 fs=0xd ino=0x3674 getfd=+0 getfl=O_RDONLY
   33 type=pipe mod=0600 dev=0 siz=0 uid=1000 gid=100 fs=0xc ino=0x24af8251 getfd=+0 getfl=O_RDONLY
   34 type=epol mod=0600 dev=0 siz=0 uid=0 gid=0 fs=0xd ino=0x3674 getfd=+0 getfl=O_RDONLY
   36 type=pipe mod=0600 dev=0 siz=0 uid=1000 gid=100 fs=0xc ino=0x24af8d1b getfd=+0 getfl=O_RDONLY
   37 type=epol mod=0600 dev=0 siz=0 uid=0 gid=0 fs=0xd ino=0x3674 getfd=+0 getfl=O_RDONLY
   39 type=pipe mod=0600 dev=0 siz=0 uid=1000 gid=100 fs=0xc ino=0x24afa04f getfd=+0 getfl=O_RDONLY
   41 type=pipe mod=0600 dev=0 siz=0 uid=1000 gid=100 fs=0xc ino=0x24af8252 getfd=+0 getfl=O_RDONLY
   42 type=epol mod=0600 dev=0 siz=0 uid=0 gid=0 fs=0xd ino=0x3674 getfd=+0 getfl=O_RDONLY

3 years agoDEBUG: pools: add new build option DEBUG_POOL_TRACING
Willy Tarreau [Mon, 24 Jan 2022 14:52:51 +0000 (15:52 +0100)] 
DEBUG: pools: add new build option DEBUG_POOL_TRACING

This new option, when set, will cause the callers of pool_alloc() and
pool_free() to be recorded into an extra area in the pool that is expected
to be helpful for later inspection (e.g. in core dumps). For example it
may help figure that an object was released to a pool with some sub-fields
not yet released or that a use-after-free happened after releasing it,
with an immediate indication about the exact line of code that released
it (possibly an error path).

This only works with the per-thread cache, and even objects refilled from
the shared pool directly into the thread-local cache will have a NULL
there. That's not an issue since these objects have not yet been freed.
It's worth noting that pool_alloc_nocache() continues not to set any
caller pointer (e.g. when the cache is empty) because that would require
a possibly undesirable API change.

The extra cost is minimal (one pointer per object) and this completes
well with DEBUG_POOL_INTEGRITY.

3 years agoMINOR: pools: extend pool_cache API to pass a pointer to a caller
Willy Tarreau [Mon, 24 Jan 2022 14:51:50 +0000 (15:51 +0100)] 
MINOR: pools: extend pool_cache API to pass a pointer to a caller

This adds a caller to pool_put_to_cache() and pool_get_from_cache()
which will optionally be used to pass a pointer to their callers. For
now it's not used, only the API is extended to support this pointer.

3 years agoMINOR: pools: prepare POOL_EXTRA to be split into multiple extra fields
Willy Tarreau [Mon, 24 Jan 2022 14:44:26 +0000 (15:44 +0100)] 
MINOR: pools: prepare POOL_EXTRA to be split into multiple extra fields

Here the idea is to calculate the POOL_EXTRA size that is appended at
the end of a pool object based on the sum of enabled optional fields
so that we can more easily compute offsets and sizes depending on build
options.

For this, POOL_EXTRA is replaced with POOL_EXTRA_MARK which itself is
set either to sizeof(void*) or zero depending on whether we enable
marking the origin pool or not upon allocation.

3 years agoMINOR: pools: partially uninline pool_alloc()
Willy Tarreau [Mon, 24 Jan 2022 15:09:29 +0000 (16:09 +0100)] 
MINOR: pools: partially uninline pool_alloc()

The pool_alloc() function was already a wrapper to __pool_alloc() which
was also inlined but took a set of flags. This latter was uninlined and
moved to pool.c, and pool_alloc()/pool_zalloc() turned to macros so that
they can more easily evolve to support debugging options.

The number of call places made this code grow over time and doing only
this change saved ~1% of the whole executable's size.

3 years agoMINOR: pools: partially uninline pool_free()
Willy Tarreau [Mon, 24 Jan 2022 10:51:43 +0000 (11:51 +0100)] 
MINOR: pools: partially uninline pool_free()

The pool_free() function has become a bit big over time due to the
extra consistency checks. It used to remain inline only to deal
cleanly with the NULL pointer free that's quite present on some
structures (e.g. in stream_free()).

Here we're splitting the function in two:
  - __pool_free() does the inner block without the pointer test and
    becomes a function ;

  - pool_free() is now a macro that only checks the pointer and calls
    __pool_free() if needed.

The use of a macro versus an inline function is only motivated by an
easier intrumentation of the code later.

With this change, the code size reduces by ~1%, which means that at
this point all pool_free() call places used to represent more than
1% of the total code size.