open Types let create_udp_socket (net : _ Eio.Net.t) ~sw ~addr ~port : _ Eio.Net.datagram_socket_ty Eio.Resource.t = let bind_addr = match Eio.Net.Ipaddr.of_raw addr with ip -> `Udp (ip, port) in Eio.Net.datagram_socket ~sw net bind_addr let send_udp sock dst buf = Eio.Net.send sock ~dst [ buf ] let recv_udp sock buf = let dst, n = Eio.Net.recv sock buf in (n, dst) let create_tcp_listener (net : _ Eio.Net.t) ~sw ~addr ~port ~backlog = let bind_addr = match Eio.Net.Ipaddr.of_raw addr with ip -> `Tcp (ip, port) in Eio.Net.listen ~sw ~backlog net bind_addr let connect_tcp (net : _ Eio.Net.t) ~sw ~addr ~timeout ~clock = try Ok (Eio.Time.with_timeout_exn clock timeout (fun () -> Eio.Net.connect ~sw net addr)) with | Eio.Time.Timeout -> Error Timeout | Eio.Io (Eio.Net.E (Connection_failure _), _) -> Error Node_unreachable | Eio.Io (Eio.Net.E (Connection_reset _), _) -> Error Connection_reset let send_tcp sock buf = try Eio.Flow.write sock [ buf ]; Ok () with | Eio.Io (Eio.Net.E (Connection_reset _), _) -> Error Connection_reset | End_of_file -> Error Connection_reset let recv_tcp sock buf = try let n = Eio.Flow.single_read sock buf in Ok n with | Eio.Io (Eio.Net.E (Connection_reset _), _) -> Error Connection_reset | End_of_file -> Error Connection_reset let parse_addr_port s = match String.rindex_opt s ':' with | None -> Error `Invalid_addr | Some idx -> ( let host = String.sub s 0 idx in let port_str = String.sub s (idx + 1) (String.length s - idx - 1) in match int_of_string_opt port_str with | None -> Error `Invalid_addr | Some port -> if port < 0 || port > 65535 then Error `Invalid_addr else Ok (host, port)) let parse_udp_addr s = match parse_addr_port s with | Error e -> Error e | Ok (host, port) -> ( try let ip = Eio.Net.Ipaddr.of_raw host in Ok (`Udp (ip, port)) with _ -> Error `Invalid_addr) let parse_tcp_addr s = match parse_addr_port s with | Error e -> Error e | Ok (host, port) -> ( try let ip = Eio.Net.Ipaddr.of_raw host in Ok (`Tcp (ip, port)) with _ -> Error `Invalid_addr)