Files
asterisk/configs/samples/websocket_client.conf.sample
George Joseph d8df207318 WebSocket Enhancements: Proxies and Keepalives for ARI and Media Outbound Websockets.
See the notes below for high-level descriptions of the new features.

* Proxies

Outbound/forward HTTP proxies are now supported and configurable in
websocket_client.conf. You can specify a host:port plus optional proxy_username
and proxy_password. Because WebSockets aren't consistently supported among
proxies (specifically passing through UPGRADEs), the CONNECT method is always
used to establish a TCP tunnel through the proxy. This is required if a TLS
session is to be established with the WebSocket server anyway.  It's important
to understand that that negotiation with the proxy is ALWAYS unsecured. Once
the proxy establishes the tunnel, the TLS session will be negotiated directly
with the remote WebSocket server via the tunnel.

* Keepalives

Both TCP-level and WebSocket PING/PONG keepalives can be configured and are
available with either the curl or tcptls client implementations. The TCP
keepalives are handled entirely by the operating system and require no
resources from Asterisk but by their very nature, they can't traverse proxies.
WebSocket PING/PONGs are implemented in the Asterisk websocket code and require
a scheduler thread to keep track of them so they're a bit more complicated but
they do traverse proxies.  Which one is used is completely up to the admin.
You could use both.

* Other Changes

A few changes were needed to res/ari/ari_websockets and
res/res_aeap/transport_websocket to add explicit calls to ast_websocket_close.
They had been assuming that the websocket session destructor would close the
websocket when it unreffed it but the keepalive process now holds a reference
so the destructor wouldn't actually run without the call to ast_websocket_close
to stop the keepalives.

A few new methods were added to tcptls.c to allow switching an existing
connection from unsecured to TLS.  These were required because the initial
connection and handshake with a proxy is always unsecured but then needs
to be switched to TLS if required for the remote WebSocket server.

There was a bug in sorcery.h where the ast_sorcery_register_uint macro
was referencing _stringify (which doesn't exist) instead of _sorcery_stringify.

Resolves: #1881
Resolves: #1933

UserNote: Forward/outbound proxies can now be specified for outbound websockets.
See the websocket_client.conf.sample file for configuration information.

UserNote: TCP-level or WebSocket PING/PONG keepalives can now be enabled on
outbound websockets.  They can help detect network failures even when a
persistent connection is idle. See the websocket_client.conf.sample
file for configuration information.

DeveloperNote: The addition of the proxy and keepalive configuration parameters
pushed the websocket client parameter count over 32. This necessitated changing
the size of the ast_ws_client_fields enum from a 32 bit bitfield to a 64-bit
bitfield with a corresponding change to the ast_websocket_client structure.
2026-06-09 14:22:56 +00:00

160 lines
9.1 KiB
Plaintext

; Common WebSocket Client Configuration for res_websocket_client
;
;[connection1] ; The connection name
;type = websocket_client ; Must be "websocket_client"
;connection_type = persistent : "persistent" or "per_call_config"
; Default: none
;uri = ws://localhost:8765 ; The URI needed to contact the remote server.
; If you've enabled tls, use "wss" for the scheme.
; Default: none
;protocols = ari ; The websocket protocol expected by the server.
; Default: none
;username = username ; An authentication username if required by the server.
; Default: none
;password = password ; The authentication password for the username.
; Default: none
;connection_timeout = 500 ; Connection timeout in milliseconds.
; Default: 500
;reconnect_interval = 1000 ; Number of milliseconds between (re)connection
; attempts.
; Default: 500
;reconnect_attempts = 4 ; For per_call connections, this is the number of
; (re)connection attempts to make before returning an
; and terminating the call. Persistent connections
; always retry forever but this setting will control
; how often failure messages are logged.
; Default: 4 for both connection types.
;tls_enabled = no ; Set to "yes" to enable TLS connections.
; Default: no
;ca_list_file = /etc/pki/tls/cert.pem
; A file containing all CA certificates needed
; for the connection. Not needed if your server
; has a certificate from a recognized CA.
; Default: none
;ca_list_path = /etc/pki/ca-trust/extracted/pem/directory-hash
; A directory containing individual CA certificates
; as an alternative to ca_list_file. Rarely needed.
; Default: none
;cert_file = /etc/asterisk/cert.pem
; If the server requires you to have a client
; certificate, specify it here and if it wasn't
; issued by a recognized CA, make sure the matching
; CA certificate is available in ca_list_file or
; ca_list_path.
; Default: none
;priv_key_file = /etc/asterisk/privkey.pem
; The private key for the client certificate.
;verify_server_cert = no ; Verify that the server certificate is valid.
; Default: yes
;verify_server_hostname = no ; Verify that the hostname in the server's certificate
; matches the hostname in the URI configured above.
; Default: yes
;
; Outbound/Forward HTTP Proxy
;
; If you need to use a proxy to reach the websocket server, you can configure it below.
; Because WebSockets aren't consistently supported among proxies (specifically passing
; through UPGRADEs), the CONNECT method is always used to establish a TCP tunnel
; through the proxy. This is required if a TLS session is to be established with the
; WebSocket server anyway. It's important to understand that that negotiation with the
; proxy is ALWAYS unsecured. Once the proxy establishes the tunnel, the TLS session
; will be negotiated directly with the remote WebSocket server via the tunnel.
;
;proxy_host = proxy:8080 ; The <hostname>:<port> for the forward proxy.
; Default: none
;proxy_username = username ; An authentication username for the proxy.
; Default: none
;proxy_password = password ; An authentication password for the proxy.
; Default: none
;
; Detecting active connection failures.
;
; Generally speaking, if the websocket server process dies, the host operating
; system will automatically close the TCP connection. Asterisk will detect
; that immediately and attempt to re-establish the connection using the configured
; connection_timeout, reconnect_interval and reconnect_attempts parameters.
;
; However if the host server itself dies or packets are being dropped in the
; network, Asterisk won't be able to detect this until the next time it tries
; to send data. To address this, there are two capabilities available:
; TCP Keepalives and WebSocket PING/PONG.
;
; Which method you choose is entirely up to you and your environment. Nothing
; prevents you from activating both but sending a PING frame will reset the
; TCP keepalive idle timeout so, depending on the intervals configured, the
; connection may never be idle long enough to trigger sending keepalives.
;
; * TCP Keepalives
;
; TCP keepalives are implemented by the Linux kernel and once configured, require no
; resources from Asterisk. The same can be said for the server side as replying to
; the keepalives is also handled entirely by the operating system without any
; involvement from application servers. Once the configured number of replies are
; missed, the kernel will close the socket which notifies Asterisk and causes an
; attempt to reconnect using the configured connection_timeout, reconnect_interval
; and reconnect_attempts parameters.
;
; The one downside to TCP keepalives is that they won't traverse a proxy so
; you'll really only be testing if you can reach the proxy, not the websocket
; server itself. However, if the proxy itself can be configured to do TCP
; keepalives to the websocket server, you could still use TCP keepalives
; between Asterisk and the proxy to create an effective end-to-end test.
;
;enable_tcp_keepalives = yes ; Enable TCP keepalives on outgoing WebSockets.
; Default: no
;tcp_keepalive_time = 20 ; Start sending keepalives when no data has been sent on
; the connection for this many seconds.
; Default: 20 seconds
;tcp_keepalive_interval = 20 ; Send keepalives at this interval in seconds.
; If a reply isn't received by the time the next keepalive
; is due to be sent, it's considered missed so this option
; also controls how long it takes to detect a failure.
; See below.
; Default: 20 seconds
;tcp_keepalive_probes = 3 ; Close the connection after this many missed replies.
; The time to detect a failure will be between
; (probes * interval) and ((probes + 1) * interval) seconds.
; If the connection closes and reconnect_interval and
; reconnect_attempts are set, a new connection will be
; attempted using those parameters.
; Default: 3 probes
;
; * WebSocket PING/PONG frames
;
; WebSocket PING/PONG frames are another way to detect failures. When configured,
; Asterisk will send a WebSoocket PING frame to the server at the configured interval.
; All WebSocket server implementation are REQUIRED to respond with a PONG frame.
; Once the configured number of PONG replies are missed, Asterisk will close the
; connection and attempt to reconnect using the configured connection_timeout,
; reconnect_interval and reconnect_attempts parameters. Unlike TCP heepalives
; however, Asterisk must create a scheduler thread and manage the process so it's
; not without overhead, however small.
;
; In contrast to TCP keepalives, WebSocket PING/PONGs will traverse a proxy.
;
;enable_pingpongs = yes ; Enable Websocket PING/PONGs
; Default: no
;pingpong_interval = 20 ; Send WebSocket PINGs at this interval in seconds.
; If a reply isn't received by the time the next PING is due
; to be sent, it's considered missed so this option also controls
; how long it takes to detect a failure. See below.
; Default: 20 seconds
;pingpong_probes = 3 ; Close the connection after this many missed PONG replies.
; The time to detect a failure is will be between
; (probes * interval) and ((probes + 1) * interval)
; seconds. If the connection closes and reconnect_interval and
; reconnect_attempts are set, a new connection will be attempted using
; those parameters.
; Default: 3 probes
;
; Also be aware...many websocket server implementations can send PING frames
; _to_ Asterisk which will automatically generate PONG replies. These won't
; interfere with Asterisk sending its own PINGs.
;