diff --git a/scripts/base/frameworks/cluster/main.zeek b/scripts/base/frameworks/cluster/main.zeek index 6620060fae..73e3cf541b 100644 --- a/scripts/base/frameworks/cluster/main.zeek +++ b/scripts/base/frameworks/cluster/main.zeek @@ -363,7 +363,9 @@ export { ## WebSocket server options to pass to :zeek:see:`Cluster::listen_websocket`. type WebSocketServerOptions: record { ## The host address to listen on. - listen_host: string; + listen_host: string &optional &deprecated="Remove in v8.1: Use $listen_addr instead."; + ## The address to listen on, cannot be used together with ``listen_host``. + listen_addr: addr &optional; ## The port the WebSocket server is supposed to listen on. listen_port: port; ## The maximum event queue size for this server. diff --git a/src/cluster/cluster.bif b/src/cluster/cluster.bif index 83a7cd8f3e..011e53b245 100644 --- a/src/cluster/cluster.bif +++ b/src/cluster/cluster.bif @@ -1,6 +1,7 @@ %%{ #include +#include "zeek/IPAddr.h" #include "zeek/cluster/Backend.h" #include "zeek/cluster/BifSupport.h" #include "zeek/cluster/Manager.h" @@ -192,8 +193,32 @@ function Cluster::__listen_websocket%(options: WebSocketServerOptions%): bool tls_options_rec->GetFieldOrDefault("ciphers")->ToStdString(), }; - struct ServerOptions server_options { - options_rec->GetField("listen_host")->ToStdString(), + std::string listen_addr; + + // Backwards compat for listen_host if listen_addr isn't set. + if ( options_rec->HasField("listen_host") ) { + if ( options_rec->HasField("listen_addr") ) { + zeek::emit_builtin_error("cannot use both listen_addr and listen_host"); + return zeek::val_mgr->False(); + } + + auto host = options_rec->GetField("listen_host")->ToStdString(); + if ( ! zeek::IPAddr::IsValid(host.c_str()) ) { + zeek::emit_builtin_error("invalid listen_host"); + return zeek::val_mgr->False(); + } + + listen_addr = std::move(host); + + } else if ( options_rec->HasField("listen_addr") ) { + listen_addr = options_rec->GetField("listen_addr")->AsAddr().AsString(); + } else { + zeek::emit_builtin_error("missing listen_host field"); + return zeek::val_mgr->False(); + } + + struct ServerOptions server_options{ + listen_addr, static_cast(options_rec->GetField("listen_port")->Port()), }; diff --git a/testing/btest/Baseline.zam/cluster.websocket.listen-idempotent/.stderr b/testing/btest/Baseline.zam/cluster.websocket.listen-idempotent/.stderr index f55de0446c..b46f38d9fd 100644 --- a/testing/btest/Baseline.zam/cluster.websocket.listen-idempotent/.stderr +++ b/testing/btest/Baseline.zam/cluster.websocket.listen-idempotent/.stderr @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/main.zeek, line 673: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_x)) -error in <...>/main.zeek, line 673: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_wss_port)) -error in <...>/main.zeek, line 673: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_qs)) +error in <...>/main.zeek, line 675: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_x)) +error in <...>/main.zeek, line 675: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_wss_port)) +error in <...>/main.zeek, line 675: Already listening on 127.0.0.1: (Cluster::__listen_websocket(ws_opts_qs)) received termination signal diff --git a/testing/btest/Baseline.zam/cluster.websocket.one-ipv6-deprecated/..manager..stderr b/testing/btest/Baseline.zam/cluster.websocket.one-ipv6-deprecated/..manager..stderr new file mode 100644 index 0000000000..9cdf7df5e4 --- /dev/null +++ b/testing/btest/Baseline.zam/cluster.websocket.one-ipv6-deprecated/..manager..stderr @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +warning in ../manager.zeek, line 12: deprecated (Cluster::WebSocketServerOptions$listen_host): Remove in v8.1: Use $listen_addr instead. ((coerce [$listen_host=::1, $listen_port=to_port(getenv(WEBSOCKET_PORT))] to Cluster::WebSocketServerOptions)) +warning in : deprecated (Cluster::WebSocketServerOptions$listen_host): Remove in v8.1: Use $listen_addr instead. (Cluster::WebSocketServerOptions($listen_host=::1, $listen_port=to_port(getenv(WEBSOCKET_PORT)))) +received termination signal diff --git a/testing/btest/Baseline.zam/cluster.websocket.tls-usage-error/.stderr b/testing/btest/Baseline.zam/cluster.websocket.tls-usage-error/.stderr index 49a7f00389..66e26e28c6 100644 --- a/testing/btest/Baseline.zam/cluster.websocket.tls-usage-error/.stderr +++ b/testing/btest/Baseline.zam/cluster.websocket.tls-usage-error/.stderr @@ -1,3 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/main.zeek, line 673: Invalid tls_options: No key_file field (Cluster::__listen_websocket(Cluster::options.0)) -error in <...>/main.zeek, line 673: Invalid tls_options: No cert_file field (Cluster::__listen_websocket(Cluster::options.3)) +error in <...>/main.zeek, line 675: Invalid tls_options: No key_file field (Cluster::__listen_websocket(Cluster::options.0)) +error in <...>/main.zeek, line 675: Invalid tls_options: No cert_file field (Cluster::__listen_websocket(Cluster::options.3)) diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client..stderr b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client..stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client..stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client.out b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client.out new file mode 100644 index 0000000000..c2f4ea81db --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..client.out @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Connected +Sending ping 0 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 1}] +Sending ping 1 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 2}] +Sending ping 2 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 3}] +Sending ping 3 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 4}] +Sending ping 4 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 5}] diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager..stderr b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager..stderr new file mode 100644 index 0000000000..38376fb320 --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager..stderr @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +warning in ../manager.zeek, line 12: deprecated (Cluster::WebSocketServerOptions$listen_host): Remove in v8.1: Use $listen_addr instead. ((coerce [$listen_host=::1, $listen_port=to_port(getenv(WEBSOCKET_PORT))] to Cluster::WebSocketServerOptions)) +received termination signal diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager.out b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager.out new file mode 100644 index 0000000000..ae19b33c56 --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6-deprecated/..manager.out @@ -0,0 +1,8 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Cluster::websocket_client_added, [/test/pings, /zeek/wstest/ws1/] +got ping: ping 0, 0 +got ping: ping 1, 1 +got ping: ping 2, 2 +got ping: ping 3, 3 +got ping: ping 4, 4 +Cluster::websocket_client_lost diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6/..client..stderr b/testing/btest/Baseline/cluster.websocket.one-ipv6/..client..stderr new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6/..client..stderr @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6/..client.out b/testing/btest/Baseline/cluster.websocket.one-ipv6/..client.out new file mode 100644 index 0000000000..c2f4ea81db --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6/..client.out @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Connected +Sending ping 0 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 1}] +Sending ping 1 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 2}] +Sending ping 2 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 3}] +Sending ping 3 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 4}] +Sending ping 4 +topic /test/pings event name pong args [{'@data-type': 'string', 'data': 'my-message'}, {'@data-type': 'count', 'data': 5}] diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager..stderr b/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager..stderr new file mode 100644 index 0000000000..e3f6131b1d --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager..stderr @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +received termination signal diff --git a/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager.out b/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager.out new file mode 100644 index 0000000000..ae19b33c56 --- /dev/null +++ b/testing/btest/Baseline/cluster.websocket.one-ipv6/..manager.out @@ -0,0 +1,8 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +Cluster::websocket_client_added, [/test/pings, /zeek/wstest/ws1/] +got ping: ping 0, 0 +got ping: ping 1, 1 +got ping: ping 2, 2 +got ping: ping 3, 3 +got ping: ping 4, 4 +Cluster::websocket_client_lost diff --git a/testing/btest/Baseline/cluster.websocket.tls-usage-error/.stderr b/testing/btest/Baseline/cluster.websocket.tls-usage-error/.stderr index 46b508db58..9acc82d0db 100644 --- a/testing/btest/Baseline/cluster.websocket.tls-usage-error/.stderr +++ b/testing/btest/Baseline/cluster.websocket.tls-usage-error/.stderr @@ -1,3 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in <...>/tls-usage-error.zeek, line 17: Invalid tls_options: No key_file field (Cluster::listen_websocket((coerce [$listen_host=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_key] to Cluster::WebSocketServerOptions))) -error in <...>/tls-usage-error.zeek, line 18: Invalid tls_options: No cert_file field (Cluster::listen_websocket((coerce [$listen_host=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_cert] to Cluster::WebSocketServerOptions))) +error in <...>/tls-usage-error.zeek, line 17: Invalid tls_options: No key_file field (Cluster::listen_websocket((coerce [$listen_addr=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_key] to Cluster::WebSocketServerOptions))) +error in <...>/tls-usage-error.zeek, line 18: Invalid tls_options: No cert_file field (Cluster::listen_websocket((coerce [$listen_addr=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_cert] to Cluster::WebSocketServerOptions))) diff --git a/testing/btest/Files/ws/wstest.py b/testing/btest/Files/ws/wstest.py index fa746c882b..9373f006d2 100644 --- a/testing/btest/Files/ws/wstest.py +++ b/testing/btest/Files/ws/wstest.py @@ -43,6 +43,7 @@ WS_PORT = ( # IPv4 non-secure WebSocker URL for version 1 WS4_URL_V1 = f"ws://127.0.0.1:{WS_PORT}/v1/messages/json" +WS6_URL_V1 = f"ws://[::1]:{WS_PORT}/v1/messages/json" DEFAULT_RECV_TIMEOUT = 0.1 OWN_TOPIC_PREFIX = "/zeek/wstest" diff --git a/testing/btest/cluster/websocket/bad-event-args.zeek b/testing/btest/cluster/websocket/bad-event-args.zeek index 323614d312..ae72dfdbb6 100644 --- a/testing/btest/cluster/websocket/bad-event-args.zeek +++ b/testing/btest/cluster/websocket/bad-event-args.zeek @@ -35,7 +35,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/zeek/event/my_topic"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/bad-subscriptions.zeek b/testing/btest/cluster/websocket/bad-subscriptions.zeek index be2cd473f4..1124d64452 100644 --- a/testing/btest/cluster/websocket/bad-subscriptions.zeek +++ b/testing/btest/cluster/websocket/bad-subscriptions.zeek @@ -35,7 +35,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/zeek/event/my_topic"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } global added = 0; diff --git a/testing/btest/cluster/websocket/bad-url.zeek b/testing/btest/cluster/websocket/bad-url.zeek index 1e6349b25a..52afa00350 100644 --- a/testing/btest/cluster/websocket/bad-url.zeek +++ b/testing/btest/cluster/websocket/bad-url.zeek @@ -37,7 +37,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/zeek/event/my_topic"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/broker/manager-recvs.zeek b/testing/btest/cluster/websocket/broker/manager-recvs.zeek index 3bc6318c24..5ec20c1d82 100644 --- a/testing/btest/cluster/websocket/broker/manager-recvs.zeek +++ b/testing/btest/cluster/websocket/broker/manager-recvs.zeek @@ -42,7 +42,7 @@ event zeek_init() Cluster::subscribe("/test/pings/"); Cluster::listen_websocket([ - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")), ]); } diff --git a/testing/btest/cluster/websocket/broker/manager-sends.zeek b/testing/btest/cluster/websocket/broker/manager-sends.zeek index dd39916b49..c37448f91c 100644 --- a/testing/btest/cluster/websocket/broker/manager-sends.zeek +++ b/testing/btest/cluster/websocket/broker/manager-sends.zeek @@ -40,7 +40,7 @@ global lost = 0; event zeek_init() { Cluster::listen_websocket([ - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")), ]); } diff --git a/testing/btest/cluster/websocket/broker/manager-worker-ping-pong.zeek b/testing/btest/cluster/websocket/broker/manager-worker-ping-pong.zeek index 614f5a47b2..87b704112e 100644 --- a/testing/btest/cluster/websocket/broker/manager-worker-ping-pong.zeek +++ b/testing/btest/cluster/websocket/broker/manager-worker-ping-pong.zeek @@ -76,7 +76,7 @@ event Cluster::node_up(name: string, id: string) # Delay listening on WebSocket clients until worker-1 is around. if ( name == "worker-1" ) Cluster::listen_websocket([ - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")) ]); } diff --git a/testing/btest/cluster/websocket/broker/no-subscriptions.zeek b/testing/btest/cluster/websocket/broker/no-subscriptions.zeek index e540085f5d..3bedb087b7 100644 --- a/testing/btest/cluster/websocket/broker/no-subscriptions.zeek +++ b/testing/btest/cluster/websocket/broker/no-subscriptions.zeek @@ -32,7 +32,7 @@ redef Broker::disable_ssl = T; event zeek_init() { Cluster::subscribe("/test/pings"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } global ping_count = 0; diff --git a/testing/btest/cluster/websocket/broker/oneshot.zeek b/testing/btest/cluster/websocket/broker/oneshot.zeek index b029caa814..ed100c28d2 100644 --- a/testing/btest/cluster/websocket/broker/oneshot.zeek +++ b/testing/btest/cluster/websocket/broker/oneshot.zeek @@ -36,7 +36,7 @@ global ping: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/test/pings"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/cluster-log.zeek b/testing/btest/cluster/websocket/cluster-log.zeek index 2f7ba20fc6..0cb1a40be0 100644 --- a/testing/btest/cluster/websocket/cluster-log.zeek +++ b/testing/btest/cluster/websocket/cluster-log.zeek @@ -43,7 +43,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/test/manager"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/listen-idempotent.zeek b/testing/btest/cluster/websocket/listen-idempotent.zeek index e187386ca3..7aea163b8b 100644 --- a/testing/btest/cluster/websocket/listen-idempotent.zeek +++ b/testing/btest/cluster/websocket/listen-idempotent.zeek @@ -20,20 +20,20 @@ event zeek_init() local ws_port = to_port(getenv("WEBSOCKET_PORT")); local wss_port = to_port(getenv("WEBSOCKET_SECURE_PORT")); - local ws_opts = Cluster::WebSocketServerOptions($listen_host="127.0.0.1", $listen_port=ws_port); + local ws_opts = Cluster::WebSocketServerOptions($listen_addr=127.0.0.1, $listen_port=ws_port); local ws_opts_x = copy(ws_opts); ws_opts_x$tls_options = tls_options; - local ws_opts_wss_port = Cluster::WebSocketServerOptions($listen_host="127.0.0.1", $listen_port=wss_port); + local ws_opts_wss_port = Cluster::WebSocketServerOptions($listen_addr=127.0.0.1, $listen_port=wss_port); local ws_tls_opts = Cluster::WebSocketServerOptions( - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=wss_port, $tls_options=tls_options, ); # Same as ws_tls_opts local ws_tls_opts_copy = Cluster::WebSocketServerOptions( - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=wss_port, $tls_options=tls_options_2, ); diff --git a/testing/btest/cluster/websocket/one-ipv6-deprecated.zeek b/testing/btest/cluster/websocket/one-ipv6-deprecated.zeek new file mode 100644 index 0000000000..70f91ff092 --- /dev/null +++ b/testing/btest/cluster/websocket/one-ipv6-deprecated.zeek @@ -0,0 +1,85 @@ +# @TEST-DOC: Use listen_host to listen on an IPv6 address, otherwise same as one-ipv6.zeek +# +# @TEST-REQUIRES: have-zeromq +# @TEST-REQUIRES: python3 -c 'import websockets.sync' +# @TEST-REQUIRES: can-listen-tcp 6 ::1 +# +# @TEST-GROUP: cluster-zeromq +# +# @TEST-PORT: XPUB_PORT +# @TEST-PORT: XSUB_PORT +# @TEST-PORT: LOG_PULL_PORT +# @TEST-PORT: WEBSOCKET_PORT +# +# @TEST-EXEC: cp $FILES/zeromq/cluster-layout-simple.zeek cluster-layout.zeek +# @TEST-EXEC: cp $FILES/zeromq/test-bootstrap.zeek zeromq-test-bootstrap.zeek +# @TEST-EXEC: cp $FILES/ws/wstest.py . +# +# @TEST-EXEC: zeek -b --parse-only manager.zeek +# @TEST-EXEC: python3 -m py_compile client.py +# +# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=manager zeek -b ../manager.zeek >out" +# @TEST-EXEC: btest-bg-run client "python3 ../client.py >out" +# +# @TEST-EXEC: btest-bg-wait 30 +# @TEST-EXEC: btest-diff ./manager/out +# @TEST-EXEC: btest-diff ./manager/.stderr +# @TEST-EXEC: btest-diff ./client/out +# @TEST-EXEC: btest-diff ./client/.stderr + +# @TEST-START-FILE manager.zeek +@load ./zeromq-test-bootstrap +redef exit_only_after_terminate = T; + +global ping_count = 0; + +global ping: event(msg: string, c: count) &is_used; +global pong: event(msg: string, c: count) &is_used; + +event zeek_init() + { + Cluster::subscribe("/test/pings/"); + Cluster::listen_websocket([$listen_host="::1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + } + +event ping(msg: string, n: count) &is_used + { + ++ping_count; + print fmt("got ping: %s, %s", msg, n); + local e = Cluster::make_event(pong, "my-message", ping_count); + Cluster::publish("/test/pings", e); + } + +event Cluster::websocket_client_added(info: Cluster::EndpointInfo, subscriptions: string_vec) + { + print "Cluster::websocket_client_added", subscriptions; + } + +event Cluster::websocket_client_lost(info: Cluster::EndpointInfo, code: count, reason: string) + { + print "Cluster::websocket_client_lost"; + terminate(); + } +# @TEST-END-FILE + + +# @TEST-START-FILE client.py +# @TEST-START-FILE client.py +import wstest + +def run(ws_url): + with wstest.connect("ws1", ws_url) as tc: + print("Connected") + tc.hello_v1(["/test/pings"]) + + for i in range(5): + print("Sending ping", i) + tc.send_json(wstest.build_event_v1("/test/pings/", "ping", [f"ping {i}", i])) + pong = tc.recv_json() + assert pong["@data-type"] == "vector" + ev = pong["data"][2]["data"] + print("topic", pong["topic"], "event name", ev[0]["data"], "args", ev[1]["data"]) + +if __name__ == "__main__": + wstest.main(run, wstest.WS6_URL_V1) +# @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/one-ipv6.zeek b/testing/btest/cluster/websocket/one-ipv6.zeek new file mode 100644 index 0000000000..9e50244e7a --- /dev/null +++ b/testing/btest/cluster/websocket/one-ipv6.zeek @@ -0,0 +1,85 @@ +# @TEST-DOC: Make a WebSocket server listen on IPv6 ::1. +# +# @TEST-REQUIRES: have-zeromq +# @TEST-REQUIRES: python3 -c 'import websockets.sync' +# @TEST-REQUIRES: can-listen-tcp 6 ::1 +# +# @TEST-GROUP: cluster-zeromq +# +# @TEST-PORT: XPUB_PORT +# @TEST-PORT: XSUB_PORT +# @TEST-PORT: LOG_PULL_PORT +# @TEST-PORT: WEBSOCKET_PORT +# +# @TEST-EXEC: cp $FILES/zeromq/cluster-layout-simple.zeek cluster-layout.zeek +# @TEST-EXEC: cp $FILES/zeromq/test-bootstrap.zeek zeromq-test-bootstrap.zeek +# @TEST-EXEC: cp $FILES/ws/wstest.py . +# +# @TEST-EXEC: zeek -b --parse-only manager.zeek +# @TEST-EXEC: python3 -m py_compile client.py +# +# @TEST-EXEC: btest-bg-run manager "ZEEKPATH=$ZEEKPATH:.. && CLUSTER_NODE=manager zeek -b ../manager.zeek >out" +# @TEST-EXEC: btest-bg-run client "python3 ../client.py >out" +# +# @TEST-EXEC: btest-bg-wait 30 +# @TEST-EXEC: btest-diff ./manager/out +# @TEST-EXEC: btest-diff ./manager/.stderr +# @TEST-EXEC: btest-diff ./client/out +# @TEST-EXEC: btest-diff ./client/.stderr + +# @TEST-START-FILE manager.zeek +@load ./zeromq-test-bootstrap +redef exit_only_after_terminate = T; + +global ping_count = 0; + +global ping: event(msg: string, c: count) &is_used; +global pong: event(msg: string, c: count) &is_used; + +event zeek_init() + { + Cluster::subscribe("/test/pings/"); + Cluster::listen_websocket([$listen_addr=[::1], $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + } + +event ping(msg: string, n: count) &is_used + { + ++ping_count; + print fmt("got ping: %s, %s", msg, n); + local e = Cluster::make_event(pong, "my-message", ping_count); + Cluster::publish("/test/pings", e); + } + +event Cluster::websocket_client_added(info: Cluster::EndpointInfo, subscriptions: string_vec) + { + print "Cluster::websocket_client_added", subscriptions; + } + +event Cluster::websocket_client_lost(info: Cluster::EndpointInfo, code: count, reason: string) + { + print "Cluster::websocket_client_lost"; + terminate(); + } +# @TEST-END-FILE + + +# @TEST-START-FILE client.py +# @TEST-START-FILE client.py +import wstest + +def run(ws_url): + with wstest.connect("ws1", ws_url) as tc: + print("Connected") + tc.hello_v1(["/test/pings"]) + + for i in range(5): + print("Sending ping", i) + tc.send_json(wstest.build_event_v1("/test/pings/", "ping", [f"ping {i}", i])) + pong = tc.recv_json() + assert pong["@data-type"] == "vector" + ev = pong["data"][2]["data"] + print("topic", pong["topic"], "event name", ev[0]["data"], "args", ev[1]["data"]) + +if __name__ == "__main__": + wstest.main(run, wstest.WS6_URL_V1) +# @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/one-pipelining.zeek b/testing/btest/cluster/websocket/one-pipelining.zeek index 0f43142280..6f42c4a297 100644 --- a/testing/btest/cluster/websocket/one-pipelining.zeek +++ b/testing/btest/cluster/websocket/one-pipelining.zeek @@ -37,7 +37,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/zeek/event/my_topic"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/one.zeek b/testing/btest/cluster/websocket/one.zeek index bcd6b7775e..a92e7e5e44 100644 --- a/testing/btest/cluster/websocket/one.zeek +++ b/testing/btest/cluster/websocket/one.zeek @@ -37,7 +37,7 @@ global pong: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/zeek/event/my_topic"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/btest/cluster/websocket/ping-timeout.zeek b/testing/btest/cluster/websocket/ping-timeout.zeek index f0347b1a3a..47c25606f6 100644 --- a/testing/btest/cluster/websocket/ping-timeout.zeek +++ b/testing/btest/cluster/websocket/ping-timeout.zeek @@ -39,7 +39,7 @@ event Cluster::websocket_client_lost(info: Cluster::EndpointInfo, code: count, r event zeek_init() { - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT")), $ping_interval=1sec]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")), $ping_interval=1sec]); Cluster::subscribe("/test/pings/"); } # @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/terminate-while-queuing.zeek b/testing/btest/cluster/websocket/terminate-while-queuing.zeek index 006fa55dc8..787f02671a 100644 --- a/testing/btest/cluster/websocket/terminate-while-queuing.zeek +++ b/testing/btest/cluster/websocket/terminate-while-queuing.zeek @@ -53,7 +53,7 @@ event Cluster::websocket_client_lost(info: Cluster::EndpointInfo, code: count, r event zeek_init() { - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); Cluster::subscribe("/test/pings/"); } # @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/three.zeek b/testing/btest/cluster/websocket/three.zeek index 3bf980cc8e..29938b45ce 100644 --- a/testing/btest/cluster/websocket/three.zeek +++ b/testing/btest/cluster/websocket/three.zeek @@ -71,7 +71,7 @@ event Cluster::Backend::ZeroMQ::subscription(topic: string) event zeek_init() { - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); Cluster::subscribe("/test/manager"); } # @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/tls-usage-error.zeek b/testing/btest/cluster/websocket/tls-usage-error.zeek index d6357324dd..1b1329e3a4 100644 --- a/testing/btest/cluster/websocket/tls-usage-error.zeek +++ b/testing/btest/cluster/websocket/tls-usage-error.zeek @@ -14,6 +14,6 @@ event zeek_init() $key_file="../localhost.key", ); - assert ! Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=1234/tcp, $tls_options=tls_options_no_key]); - assert ! Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=1234/tcp, $tls_options=tls_options_no_cert]); + assert ! Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_key]); + assert ! Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=1234/tcp, $tls_options=tls_options_no_cert]); } diff --git a/testing/btest/cluster/websocket/tls.zeek b/testing/btest/cluster/websocket/tls.zeek index bd816c5328..235102428f 100644 --- a/testing/btest/cluster/websocket/tls.zeek +++ b/testing/btest/cluster/websocket/tls.zeek @@ -46,7 +46,7 @@ event zeek_init() ); local ws_server_options = Cluster::WebSocketServerOptions( - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")), $tls_options=tls_options, ); diff --git a/testing/btest/cluster/websocket/two-pipelining.zeek b/testing/btest/cluster/websocket/two-pipelining.zeek index fbf51da293..63a57c5280 100644 --- a/testing/btest/cluster/websocket/two-pipelining.zeek +++ b/testing/btest/cluster/websocket/two-pipelining.zeek @@ -103,7 +103,7 @@ event Cluster::Backend::ZeroMQ::subscription(topic: string) event zeek_init() { - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); Cluster::subscribe("/test/manager"); } # @TEST-END-FILE diff --git a/testing/btest/cluster/websocket/zeromq/manager-worker-ping-pong.zeek b/testing/btest/cluster/websocket/zeromq/manager-worker-ping-pong.zeek index b9f19948ef..a27d7f44fd 100644 --- a/testing/btest/cluster/websocket/zeromq/manager-worker-ping-pong.zeek +++ b/testing/btest/cluster/websocket/zeromq/manager-worker-ping-pong.zeek @@ -79,7 +79,7 @@ event Cluster::node_up(name: string, id: string) # Delay listening on WebSocket clients until worker-1 is around. if ( name == "worker-1" ) Cluster::listen_websocket([ - $listen_host="127.0.0.1", + $listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT")) ]); } diff --git a/testing/btest/cluster/websocket/zeromq/no-subscriptions.zeek b/testing/btest/cluster/websocket/zeromq/no-subscriptions.zeek index 305b0919eb..073056fb8f 100644 --- a/testing/btest/cluster/websocket/zeromq/no-subscriptions.zeek +++ b/testing/btest/cluster/websocket/zeromq/no-subscriptions.zeek @@ -33,7 +33,7 @@ redef exit_only_after_terminate = T; event zeek_init() { Cluster::subscribe("/test/pings"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } global ping_count = 0; diff --git a/testing/btest/cluster/websocket/zeromq/oneshot.zeek b/testing/btest/cluster/websocket/zeromq/oneshot.zeek index 19f9f12720..e7e76521af 100644 --- a/testing/btest/cluster/websocket/zeromq/oneshot.zeek +++ b/testing/btest/cluster/websocket/zeromq/oneshot.zeek @@ -38,7 +38,7 @@ global ping: event(msg: string, c: count) &is_used; event zeek_init() { Cluster::subscribe("/test/pings"); - Cluster::listen_websocket([$listen_host="127.0.0.1", $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); + Cluster::listen_websocket([$listen_addr=127.0.0.1, $listen_port=to_port(getenv("WEBSOCKET_PORT"))]); } event ping(msg: string, n: count) &is_used diff --git a/testing/scripts/can-listen-tcp b/testing/scripts/can-listen-tcp new file mode 100755 index 0000000000..7522daaed8 --- /dev/null +++ b/testing/scripts/can-listen-tcp @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# +# Try binding on the given family with addr and a port of 0 so that an +# ephemeral port is allocated. This can be used to guard IPv6 tests. + +import socket +import sys + + +def usage(): + print(f"Usage: {sys.argv[0]} 4|6 ", file=sys.stderr) + sys.exit(1) + + +if len(sys.argv) != 3: + usage() + +family = 0 + +if sys.argv[1] == "4": + family = socket.AF_INET +elif sys.argv[1] == "6": + family = socket.AF_INET6 +else: + usage() + +addr = sys.argv[2] +port = 0 + +s = socket.socket(family) + +try: + s.bind((addr, port)) +except Exception as e: + print(f"cannot listen on {addr}:{port} ({e!r})") + sys.exit(1) +finally: + try: + s.close() + except: + pass