From 70a675a1137144376e9441fdfe3218262706a10b Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Thu, 14 Sep 2023 11:42:06 +0200 Subject: [PATCH] [server] add support for ipv6 addresses for --wait/--connect --- haxe.opam | 1 + src/compiler/compilationContext.ml | 6 +++--- src/compiler/compiler.ml | 4 ++-- src/compiler/helper.ml | 17 ++++++++++++++--- src/compiler/server.ml | 23 ++++++++++++++++++----- src/dune | 2 +- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/haxe.opam b/haxe.opam index 6a582f07288..16b250972f2 100644 --- a/haxe.opam +++ b/haxe.opam @@ -31,4 +31,5 @@ depends: [ "conf-zlib" "conf-neko" "luv" {>= "0.5.12"} + "ipaddr" ] diff --git a/src/compiler/compilationContext.ml b/src/compiler/compilationContext.ml index 64e3f6b7f3e..0e18bce18d1 100644 --- a/src/compiler/compilationContext.ml +++ b/src/compiler/compilationContext.ml @@ -54,11 +54,11 @@ type server_api = { cache : CompilationCache.t; callbacks : compilation_callbacks; on_context_create : unit -> int; - init_wait_socket : string -> int -> server_accept; - init_wait_connect : string -> int -> server_accept; + init_wait_socket : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> server_accept; + init_wait_connect : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> server_accept; init_wait_stdio : unit -> server_accept; wait_loop : bool -> server_accept -> int; - do_connect : string -> int -> string list -> unit; + do_connect : (Ipaddr.V4.t, Ipaddr.V6.t) Ipaddr.v4v6 -> int -> string list -> unit; } let message ctx msg = diff --git a/src/compiler/compiler.ml b/src/compiler/compiler.ml index 3f1ef3ae676..64c32ef30fb 100644 --- a/src/compiler/compiler.ml +++ b/src/compiler/compiler.ml @@ -572,8 +572,8 @@ module HighLevel = struct (* If we are already connected, ignore (issue #10813) *) loop acc l else begin - let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in - server_api.do_connect host (try int_of_string port with _ -> raise (Arg.Bad "Invalid port")) ((List.rev acc) @ l); + let host, port = Helper.parse_host_port hp in + server_api.do_connect host port ((List.rev acc) @ l); [],None end | "--server-connect" :: hp :: l -> diff --git a/src/compiler/helper.ml b/src/compiler/helper.ml index 26e482ed1c3..2f99746cd17 100644 --- a/src/compiler/helper.ml +++ b/src/compiler/helper.ml @@ -1,3 +1,4 @@ +open Ipaddr exception HelpMessage of string let is_debug_run = try Sys.getenv "HAXEDEBUG" = "1" with _ -> false @@ -52,6 +53,16 @@ let parse_hxml file = parse_hxml_data data let parse_host_port hp = - let host, port = (try ExtString.String.split hp ":" with _ -> "127.0.0.1", hp) in - let port = try int_of_string port with _ -> raise (Arg.Bad "Invalid port") in - host, port \ No newline at end of file + match (Ipaddr.with_port_of_string ~default:(-1) hp) with + (* Short ipv6 notation will be mixed up with port; extract port and rebuild ipv6 *) + | Ok (V6 ip, -1) -> + let octets = ExtLib.String.split_on_char ':' (V6.to_string ip) in + (match (List.rev octets) with + | port :: octets -> (try V6 (V6.of_string_exn (ExtLib.String.join ":" (List.rev octets))), int_of_string port with _ -> raise (Arg.Bad "Invalid host/port")) + | _ -> raise (Arg.Bad "Invalid host/port") + ) + | Ok (_, -1) -> raise (Arg.Bad "Invalid host/port: missing port") + | Ok (ip, port) -> ip, port + (* Default to 127.0.0.1 with given port if no host is provided *) + | Error _ when Str.string_match (Str.regexp "[0-9]+$") hp 0 -> V4 (V4.of_string_exn "127.0.0.1"), int_of_string hp + | Error _ -> raise (Arg.Bad "Invalid host/port") diff --git a/src/compiler/server.ml b/src/compiler/server.ml index 1adc30bb866..f3bcf3a6e0e 100644 --- a/src/compiler/server.ml +++ b/src/compiler/server.ml @@ -4,6 +4,7 @@ open CompilationCache open Timer open Type open DisplayProcessingGlobals +open Ipaddr open Json open CompilationContext open MessageReporting @@ -542,8 +543,12 @@ let init_wait_stdio() = mk_length_prefixed_communication false stdin stderr (* The connect function to connect to [host] at [port] and send arguments [args]. *) -let do_connect host port args = - let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in +let do_connect ip port args = + let (domain, host) = match ip with + | V4 ip -> (Unix.PF_INET, V4.to_string ip) + | V6 ip -> (Unix.PF_INET6, V6.to_string ip) + in + let sock = Unix.socket domain Unix.SOCK_STREAM 0 in (try Unix.connect sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with | Unix.Unix_error(code,_,_) -> failwith("Couldn't connect on " ^ host ^ ":" ^ string_of_int port ^ " (" ^ (Unix.error_message code) ^ ")"); | _ -> failwith ("Couldn't connect on " ^ host ^ ":" ^ string_of_int port) @@ -710,14 +715,22 @@ and wait_loop verbose accept = 0 (* Connect to given host/port and return accept function for communication *) -and init_wait_connect host port = +and init_wait_connect ip port = + let host = match ip with + | V4 ip -> V4.to_string ip + | V6 ip -> V6.to_string ip + in let host = Unix.inet_addr_of_string host in let chin, chout = Unix.open_connection (Unix.ADDR_INET (host,port)) in mk_length_prefixed_communication true chin chout (* The accept-function to wait for a socket connection. *) -and init_wait_socket host port = - let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in +and init_wait_socket ip port = + let (domain, host) = match ip with + | V4 ip -> (Unix.PF_INET, V4.to_string ip) + | V6 ip -> (Unix.PF_INET6, V6.to_string ip) + in + let sock = Unix.socket domain Unix.SOCK_STREAM 0 in (try Unix.setsockopt sock Unix.SO_REUSEADDR true with _ -> ()); (try Unix.bind sock (Unix.ADDR_INET (Unix.inet_addr_of_string host,port)) with _ -> failwith ("Couldn't wait on " ^ host ^ ":" ^ string_of_int port)); ServerMessage.socket_message ("Waiting on " ^ host ^ ":" ^ string_of_int port); diff --git a/src/dune b/src/dune index 045db889643..03cd1d84add 100644 --- a/src/dune +++ b/src/dune @@ -19,7 +19,7 @@ (libraries extc extproc extlib_leftovers ilib javalib mbedtls neko objsize pcre2 swflib ttflib ziplib json - unix str bigarray threads dynlink + unix ipaddr str bigarray threads dynlink xml-light extlib sha luv )