From ef5b1a680d669fd3b3493ab7f22580bd7a7f5bb5 Mon Sep 17 00:00:00 2001 From: Romain Beauxis Date: Wed, 15 Jan 2025 09:07:25 -0600 Subject: [PATCH] Add ipv6only, debug. --- .github/scripts/build-posix.sh | 4 +++ dune-project | 2 +- liquidsoap-core.opam | 2 +- src/core/io/srt_io.ml | 55 ++++++++++++++++++++++------------ 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/.github/scripts/build-posix.sh b/.github/scripts/build-posix.sh index e35d81a46c..330b133228 100755 --- a/.github/scripts/build-posix.sh +++ b/.github/scripts/build-posix.sh @@ -45,6 +45,10 @@ git clone https://github.com/savonet/ocaml-xiph.git cd ocaml-xiph opam install -y . +git clone https://github.com/savonet/ocaml-srt.git +cd ocaml-srt +opam install -y . + cd /tmp/liquidsoap-full/liquidsoap ./.github/scripts/checkout-deps.sh diff --git a/dune-project b/dune-project index dfe24e7bce..d85f2eec4e 100644 --- a/dune-project +++ b/dune-project @@ -134,7 +134,7 @@ (shine (< 0.2.0)) (soundtouch (< 0.1.9)) (speex (< 1.0.0)) - (srt (< 0.3.0)) + (srt (< 0.3.2)) (ssl (< 0.7.0)) (tls (< 1.0.2)) (sdl-liquidsoap (< 2)) diff --git a/liquidsoap-core.opam b/liquidsoap-core.opam index 39767caf15..1e8ee276b2 100644 --- a/liquidsoap-core.opam +++ b/liquidsoap-core.opam @@ -100,7 +100,7 @@ conflicts: [ "shine" {< "0.2.0"} "soundtouch" {< "0.1.9"} "speex" {< "1.0.0"} - "srt" {< "0.3.0"} + "srt" {< "0.3.2"} "ssl" {< "0.7.0"} "tls" {< "1.0.2"} "sdl-liquidsoap" {< "2"} diff --git a/src/core/io/srt_io.ml b/src/core/io/srt_io.ml index e3ce1b53c7..7a165b0bb4 100644 --- a/src/core/io/srt_io.ml +++ b/src/core/io/srt_io.ml @@ -106,6 +106,13 @@ let common_options ~mode = Lang.string_t, Some (Lang.string "0.0.0.0"), Some "Address to bind on the local machine. Used only in listener mode" ); + ( "ipv6only", + Lang.nullable_t Lang.bool_t, + Some (Lang.bool true), + Some + "If `true`, binding to the ipv6 wildcard address `::` will bind to \ + both IPv6 and IPv4 wildcard address. Defaults to system default when \ + `null`." ); ( "polling_delay", Lang.float_t, Some (Lang.float 2.), @@ -165,6 +172,7 @@ type common_options = { hostname : string; port : int; bind_address : Unix.sockaddr; + ipv6only : bool option; listen_callback : Srt.listen_callback option; streamid : string option; pbkeylen : int option; @@ -190,6 +198,7 @@ let parse_common_options p = ( List.assoc "bind_address" p, Printf.sprintf "Invalid address: %s" (Printexc.to_string exn) )) in + let ipv6only = Lang.to_valued_option Lang.to_bool (List.assoc "ipv6only" p) in let passphrase_v = List.assoc "passphrase" p in let passphrase = Lang.to_valued_option Lang.to_string passphrase_v in (match passphrase with @@ -251,6 +260,7 @@ let parse_common_options p = hostname = Lang.to_string (List.assoc "host" p); port = Lang.to_int (List.assoc "port" p); bind_address; + ipv6only; listen_callback; pbkeylen; enforced_encryption; @@ -401,12 +411,15 @@ let string_of_address = function | Unix.ADDR_INET (addr, port) -> Printf.sprintf "%s:%d" (Unix.string_of_inet_addr addr) port -let mk_socket ~payload_size ~messageapi () = +let mk_socket ~payload_size ~ipv6only ~messageapi () = let s = Srt.create_socket () in Srt.setsockflag s Srt.payloadsize payload_size; Srt.setsockflag s Srt.transtype `Live; Srt.setsockflag s Srt.messageapi messageapi; Srt.setsockflag s Srt.enforced_encryption conf_enforced_encryption#get; + (match ipv6only with + | None -> () + | Some v -> Srt.setsockflag s Srt.ipv6only v); s let close_socket s = Srt.close s @@ -492,7 +505,7 @@ class virtual caller ~enforced_encryption ~pbkeylen ~passphrase ~streamid (match Atomic.exchange socket None with | None -> () | Some (_, s) -> close_socket s); - let s = mk_socket ~payload_size ~messageapi () in + let s = mk_socket ~ipv6only:None ~payload_size ~messageapi () in try Srt.setsockflag s Srt.sndsyn true; Srt.setsockflag s Srt.rcvsyn true; @@ -557,8 +570,8 @@ class virtual caller ~enforced_encryption ~pbkeylen ~passphrase ~streamid end class virtual listener ~enforced_encryption ~pbkeylen ~passphrase ~max_clients - ~listen_callback ~payload_size ~messageapi ~bind_address ~read_timeout - ~write_timeout ~on_connect ~on_disconnect () = + ~listen_callback ~payload_size ~messageapi ~bind_address ~ipv6only + ~read_timeout ~write_timeout ~on_connect ~on_disconnect () = object (self) val mutable client_sockets = [] method virtual id : string @@ -577,8 +590,10 @@ class virtual listener ~enforced_encryption ~pbkeylen ~passphrase ~max_clients match Atomic.get listening_socket with | Some s -> s | None -> ( - let s = mk_socket ~payload_size ~messageapi () in + let s = mk_socket ~payload_size ~ipv6only ~messageapi () in try + Printf.printf "BIND SRT SOCKET: %s\n" + (string_of_address bind_address); Srt.bind s bind_address; let max_clients_callback = Option.map @@ -796,9 +811,9 @@ class virtual input_base ~max ~self_sync ~on_connect ~on_disconnect end class input_listener ~enforced_encryption ~pbkeylen ~passphrase ~listen_callback - ~bind_address ~max ~payload_size ~self_sync ~on_connect ~on_disconnect - ~read_timeout ~write_timeout ~messageapi ~dump ~on_start ~on_stop ~autostart - format = + ~bind_address ~ipv6only ~max ~payload_size ~self_sync ~on_connect + ~on_disconnect ~read_timeout ~write_timeout ~messageapi ~dump ~on_start + ~on_stop ~autostart format = object (self) inherit input_base @@ -808,8 +823,8 @@ class input_listener ~enforced_encryption ~pbkeylen ~passphrase ~listen_callback inherit listener ~enforced_encryption ~pbkeylen ~passphrase ~listen_callback - ~max_clients:(Some 1) ~bind_address ~payload_size ~read_timeout - ~write_timeout ~messageapi ~on_connect ~on_disconnect () + ~max_clients:(Some 1) ~bind_address ~ipv6only ~payload_size + ~read_timeout ~write_timeout ~messageapi ~on_connect ~on_disconnect () method private get_socket = match self#get_sockets with @@ -880,6 +895,7 @@ let _ = pbkeylen; passphrase; bind_address; + ipv6only; listen_callback; polling_delay; read_timeout; @@ -913,9 +929,9 @@ let _ = | `Listener -> (new input_listener ~enforced_encryption ~pbkeylen ~passphrase ~listen_callback - ~bind_address ~read_timeout ~write_timeout ~payload_size - ~self_sync ~on_connect ~on_disconnect ~messageapi ~max ~dump - ~on_start ~on_stop ~autostart format + ~bind_address ~ipv6only ~read_timeout ~write_timeout + ~payload_size ~self_sync ~on_connect ~on_disconnect ~messageapi + ~max ~dump ~on_start ~on_stop ~autostart format :> < Start_stop.active_source ; get_sockets : (Unix.sockaddr * Srt.socket) list >) | `Caller -> @@ -1050,7 +1066,7 @@ class output_caller ~enforced_encryption ~pbkeylen ~passphrase ~streamid class output_listener ~enforced_encryption ~pbkeylen ~passphrase ~listen_callback ~max_clients ~payload_size ~messageapi ~on_start ~on_stop ~infallible ~register_telnet ~autostart ~on_connect ~on_disconnect - ~bind_address ~read_timeout ~write_timeout ~encoder_factory source = + ~bind_address ~ipv6only ~read_timeout ~write_timeout ~encoder_factory source = object (self) inherit output_base @@ -1059,9 +1075,9 @@ class output_listener ~enforced_encryption ~pbkeylen ~passphrase inherit listener - ~bind_address ~payload_size ~read_timeout ~write_timeout ~messageapi - ~on_connect ~on_disconnect ~enforced_encryption ~pbkeylen ~passphrase - ~listen_callback ~max_clients () + ~bind_address ~ipv6only ~payload_size ~read_timeout ~write_timeout + ~messageapi ~on_connect ~on_disconnect ~enforced_encryption ~pbkeylen + ~passphrase ~listen_callback ~max_clients () method private client_error socket exn bt = Utils.log_exception ~log:self#log @@ -1106,6 +1122,7 @@ let _ = pbkeylen; passphrase; bind_address; + ipv6only; listen_callback; polling_delay; read_timeout; @@ -1155,8 +1172,8 @@ let _ = | `Listener -> (new output_listener ~enforced_encryption ~pbkeylen ~passphrase ~bind_address - ~read_timeout ~write_timeout ~payload_size ~autostart ~on_start - ~on_stop ~infallible ~register_telnet ~messageapi + ~ipv6only ~read_timeout ~write_timeout ~payload_size ~autostart + ~on_start ~on_stop ~infallible ~register_telnet ~messageapi ~encoder_factory ~on_connect ~on_disconnect ~listen_callback ~max_clients source :> < Output.output