瀏覽代碼

TCP get(sock|peer)name

Aurel Bílý 6 年之前
父節點
當前提交
d1f08dcf8d
共有 4 個文件被更改,包括 73 次插入13 次删除
  1. 12 5
      libs/uv/uv.ml
  2. 37 0
      libs/uv/uv_stubs.c
  3. 2 1
      src/macro/eval/evalHash.ml
  4. 22 7
      src/macro/eval/evalStdLib.ml

+ 12 - 5
libs/uv/uv.ml

@@ -159,6 +159,15 @@ external fs_event_stop : t_fs_event -> unit_cb -> unit uv_result = "w_fs_event_s
 
 (* ------------- TCP ------------------------------------------------ *)
 
+type uv_ip_address =
+	| UvIpv4 of int32
+	| UvIpv6 of bytes
+
+type uv_ip_address_port = {
+	address: uv_ip_address;
+	port: int;
+}
+
 type stream_bytes_cb = bytes uv_result -> unit
 
 external tcp_init : t_loop -> t_tcp uv_result = "w_tcp_init"
@@ -169,6 +178,8 @@ external tcp_bind_ipv4 : t_tcp -> int -> int -> unit uv_result = "w_tcp_bind_ipv
 external tcp_bind_ipv6 : t_tcp -> bytes -> int -> bool -> unit uv_result = "w_tcp_bind_ipv6"
 external tcp_connect_ipv4 : t_tcp -> int -> int -> unit_cb -> unit uv_result = "w_tcp_connect_ipv4"
 external tcp_connect_ipv6 : t_tcp -> bytes -> int -> unit_cb -> unit uv_result = "w_tcp_connect_ipv6"
+external tcp_getsockname : t_tcp -> uv_ip_address_port uv_result = "w_tcp_getsockname"
+external tcp_getpeername : t_tcp -> uv_ip_address_port uv_result = "w_tcp_getpeername"
 external tcp_shutdown : t_tcp -> unit_cb -> unit uv_result = "w_tcp_shutdown"
 external tcp_close : t_tcp -> unit_cb -> unit uv_result = "w_tcp_close"
 external tcp_listen : t_tcp -> int -> unit_cb -> unit uv_result = "w_tcp_listen"
@@ -178,11 +189,7 @@ external tcp_read_stop : t_tcp -> unit uv_result = "w_tcp_read_stop"
 
 (* ------------- DNS ------------------------------------------------ *)
 
-type uv_gai_result =
-	| UvGai4 of int32
-	| UvGai6 of bytes
-
-type dns_gai_cb = (uv_gai_result list) uv_result -> unit
+type dns_gai_cb = (uv_ip_address list) uv_result -> unit
 
 external dns_getaddrinfo : t_loop -> string -> bool -> bool -> int -> dns_gai_cb -> unit uv_result = "w_dns_getaddrinfo_bytecode" "w_dns_getaddrinfo"
 

+ 37 - 0
libs/uv/uv_stubs.c

@@ -676,6 +676,43 @@ CAMLprim value w_tcp_connect_ipv6(value handle, value host, value port, value cb
 	UV_SUCCESS_UNIT;
 }
 
+static value w_tcp_getname(struct sockaddr_storage *storage) {
+	CAMLparam0();
+	CAMLlocal3(res, addr, infostore);
+	res = caml_alloc(2, 0);
+	if (storage->ss_family == AF_INET) {
+		addr = caml_alloc(1, 0);
+		Store_field(addr, 0, caml_copy_int32(ntohl(((struct sockaddr_in *)storage)->sin_addr.s_addr)));
+		Store_field(res, 1, Val_int(ntohs(((struct sockaddr_in *)storage)->sin_port)));
+	} else if (storage->ss_family == AF_INET6) {
+		addr = caml_alloc(1, 1);
+		infostore = caml_alloc_string(sizeof(struct in6_addr));
+		memcpy(&Byte(infostore, 0), ((struct sockaddr_in6 *)storage)->sin6_addr.s6_addr, sizeof(struct in6_addr));
+		Store_field(addr, 0, infostore);
+		Store_field(res, 1, Val_int(ntohs(((struct sockaddr_in6 *)storage)->sin6_port)));
+	} else {
+		UV_ERROR(0);
+	}
+	Store_field(res, 0, addr);
+	UV_SUCCESS(res);
+}
+
+CAMLprim value w_tcp_getsockname(value handle) {
+	CAMLparam1(handle);
+	struct sockaddr_storage storage;
+	int dummy = sizeof(struct sockaddr_storage);
+	UV_ERROR_CHECK(uv_tcp_getsockname(Tcp_val(handle), (struct sockaddr *)&storage, &dummy));
+	CAMLreturn(w_tcp_getname(&storage));
+}
+
+CAMLprim value w_tcp_getpeername(value handle) {
+	CAMLparam1(handle);
+	struct sockaddr_storage storage;
+	int dummy = sizeof(struct sockaddr_storage);
+	UV_ERROR_CHECK(uv_tcp_getpeername(Tcp_val(handle), (struct sockaddr *)&storage, &dummy));
+	CAMLreturn(w_tcp_getname(&storage));
+}
+
 CAMLprim value w_tcp_shutdown(value handle, value cb) {
 	return w_shutdown(handle, cb);
 }

+ 2 - 1
src/macro/eval/evalHash.ml

@@ -145,5 +145,6 @@ let key_nusys_io_File = hash "nusys.io.File"
 let key_nusys_io_AsyncFile = hash "nusys.io.AsyncFile"
 let key_eval_uv_Socket = hash "eval.uv.Socket"
 let key_nusys_net_Dns = hash "nusys.net.Dns"
-let key_sys_net_Address = hash "sys.net.Address"
+let key_nusys_net_Address = hash "nusys.net.Address"
+let key_nusys_net_SocketAddress = hash "nusys.net.SocketAddress"
 let key_eval_uv_Timer = hash "eval.uv.Timer"

+ 22 - 7
src/macro/eval/evalStdLib.ml

@@ -3352,11 +3352,11 @@ module StdUv = struct
 			let res = wrap_sync (Uv.fs_mkdtemp_sync (loop ()) prefix) in
 			encode_string res
 		)
-		let open_ = vfun4 (fun path flags mode binary ->
+		let open_native = vfun4 (fun path flags mode binary ->
 			let path = decode_string path in
-			let flags = default_int flags 0 in
-			let mode = default_int mode 0o666 in
-			(*let binary = default_bool binary true in*)
+			let flags = decode_int flags in
+			let mode = decode_int mode in
+			(*let binary = decode_bool binary in*)
 			let handle = wrap_sync (Uv.fs_open_sync (loop ()) path flags mode) in
 			encode_instance key_nusys_io_File ~kind:(IUv (UvFile handle))
 		)
@@ -3542,6 +3542,19 @@ module StdUv = struct
 			wrap_sync (Uv.tcp_nodelay this noDelay);
 			vnull
 		)
+		let getName fn = vifun0 (fun vthis ->
+			let this = this vthis in
+			let addr = wrap_sync (fn this) in
+			match addr with
+				| {address; port} ->
+					encode_enum_value key_nusys_net_SocketAddress 0 [|(match address with
+							| Uv.UvIpv4 raw -> encode_enum_value key_nusys_net_Address 0 [|VInt32 raw|] None
+							| Uv.UvIpv6 raw -> encode_enum_value key_nusys_net_Address 1 [|encode_bytes raw|] None
+						); vint port|] None
+				| _ -> assert false
+		)
+		let getSockName = getName Uv.tcp_getsockname
+		let getPeerName = getName Uv.tcp_getpeername
 	end
 
 	module Dns = struct
@@ -3569,8 +3582,8 @@ module StdUv = struct
 					| Uv.UvError err -> call_value cb [wrap_error err; vnull]
 					| Uv.UvSuccess entries ->
 						let entries = encode_array (List.map (fun e -> match e with
-							| Uv.UvGai4 raw -> encode_enum_value key_sys_net_Address 0 [|VInt32 raw|] None
-							| Uv.UvGai6 raw -> encode_enum_value key_sys_net_Address 1 [|encode_bytes raw|] None) entries) in
+							| Uv.UvIpv4 raw -> encode_enum_value key_nusys_net_Address 0 [|VInt32 raw|] None
+							| Uv.UvIpv6 raw -> encode_enum_value key_nusys_net_Address 1 [|encode_bytes raw|] None) entries) in
 						call_value cb [vnull; entries]
 					)
 				));
@@ -4238,7 +4251,7 @@ let init_standard_library builtins =
 		"link",StdUv.FileSystem.link;
 		"mkdir_native",StdUv.FileSystem.mkdir_native;
 		"mkdtemp",StdUv.FileSystem.mkdtemp;
-		"open",StdUv.FileSystem.open_;
+		"open_native",StdUv.FileSystem.open_native;
 		"readdirTypes",StdUv.FileSystem.readdirTypes;
 		"readlink",StdUv.FileSystem.readlink;
 		"realpath",StdUv.FileSystem.realpath;
@@ -4313,6 +4326,8 @@ let init_standard_library builtins =
 		"close",StdUv.Socket.close;
 		"setKeepAlive",StdUv.Socket.setKeepAlive;
 		"setNoDelay",StdUv.Socket.setNoDelay;
+		"getSockName",StdUv.Socket.getSockName;
+		"getPeerName",StdUv.Socket.getPeerName;
 	];
 	init_fields builtins (["nusys";"net"],"Dns") [
 		"lookup_native",StdUv.Dns.lookup_native;