aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristiano Haesbaert <haesbaert@haesbaert.org>2025-01-12 01:23:34 +0100
committerChristiano Haesbaert <haesbaert@haesbaert.org>2025-01-12 02:41:35 +0100
commit5699c533c6422dd71de2d26297e47c53a3b9e8dc (patch)
tree05fd83678a5b5772327a58f577d92071148a1103
parentcd93e2f6f8bb971e1d33bfc783ce4ab4e7568a5b (diff)
Add net.dial_tcp_from_host{_or_endpoint} and unify them
The main motivation for this is to have sinergy with flags parsing, currently flags for a sockaddr returns a net.Host_Or_Endpoint, but we can't just dial from it since there isn't a variant. Consider the following: ``` Options :: struct { target: net.Host_Or_Endpoint `args:"pos=0,required" usage:"host:port"`, } before :: proc() -> (sock: net.TCP_Socket, err: net.Network_Error) { opt: Options flags.parse_or_exit(&opt, os.args) switch t in opt.target { case net.Host: sock, err = net.dial_tcp(t.hostname, t.port) case net.Endpoint: sock, err = net.dial_tcp(t) } return } after :: proc() -> (sock: net.TCP_Socket, err: net.Network_Error) { opt: Options flags.parse_or_exit(&opt, os.args) sock, err = net.dial_tcp(opt.target) return } ``` For completion, add dial_tcp_from_host() and define the upper functions in terms of the newly added ones, cuts one repeated block, now: from_hostname_and_port_string is parse + from_host_or_endpoint from_hostname_with_port_override is parse + override + from_host_or_endpoint from_host is to_endpoint + from_endpoint from_host_or_endpoint is from_endpoint or from_host
-rw-r--r--core/net/socket.odin57
1 files changed, 35 insertions, 22 deletions
diff --git a/core/net/socket.odin b/core/net/socket.odin
index 950c7ac11..c5ea11e11 100644
--- a/core/net/socket.odin
+++ b/core/net/socket.odin
@@ -34,23 +34,12 @@ any_socket_to_socket :: proc "contextless" (socket: Any_Socket) -> Socket {
Expects both hostname and port to be present in the `hostname_and_port` parameter, either as:
`a.host.name:9999`, or as `1.2.3.4:9999`, or IP6 equivalent.
- Calls `parse_hostname_or_endpoint` and `resolve`, then `dial_tcp_from_endpoint`.
+ Calls `parse_hostname_or_endpoint` and `dial_tcp_from_host_or_endpoint`.
*/
dial_tcp_from_hostname_and_port_string :: proc(hostname_and_port: string, options := default_tcp_options) -> (socket: TCP_Socket, err: Network_Error) {
target := parse_hostname_or_endpoint(hostname_and_port) or_return
- switch t in target {
- case Endpoint:
- return dial_tcp_from_endpoint(t, options)
- case Host:
- if t.port == 0 {
- return 0, .Port_Required
- }
- ep4, ep6 := resolve(t.hostname) or_return
- ep := ep4 if ep4.address != nil else ep6 // NOTE(tetra): We don't know what family the server uses, so we just default to IP4.
- ep.port = t.port
- return dial_tcp_from_endpoint(ep, options)
- }
- unreachable()
+
+ return dial_tcp_from_host_or_endpoint(target, options)
}
/*
@@ -61,17 +50,39 @@ dial_tcp_from_hostname_and_port_string :: proc(hostname_and_port: string, option
*/
dial_tcp_from_hostname_with_port_override :: proc(hostname: string, port: int, options := default_tcp_options) -> (socket: TCP_Socket, err: Network_Error) {
target := parse_hostname_or_endpoint(hostname) or_return
+ switch &t in target {
+ case Endpoint:
+ t.port = port
+ case Host:
+ t.port = port
+ }
+
+ return dial_tcp_from_host_or_endpoint(target, options)
+}
+
+/*
+ Expects the `host` as Host.
+*/
+dial_tcp_from_host :: proc(host: Host, options := default_tcp_options) -> (socket: TCP_Socket, err: Network_Error) {
+ if host.port == 0 {
+ return 0, .Port_Required
+ }
+ ep4, ep6 := resolve(host.hostname) or_return
+ ep := ep4 if ep4.address != nil else ep6 // NOTE(tetra): We don't know what family the server uses, so we just default to IP4.
+ ep.port = host.port
+ return dial_tcp_from_endpoint(ep, options)
+}
+
+/*
+ Expects the `target` as a Host_OrEndpoint.
+ Unwraps the underlying type and calls `dial_tcp_from_host` or `dial_tcp_from_endpoint`.
+*/
+dial_tcp_from_host_or_endpoint :: proc(target: Host_Or_Endpoint, options := default_tcp_options) -> (socket: TCP_Socket, err: Network_Error) {
switch t in target {
case Endpoint:
- return dial_tcp_from_endpoint({t.address, port}, options)
+ return dial_tcp_from_endpoint(t, options)
case Host:
- if port == 0 {
- return 0, .Port_Required
- }
- ep4, ep6 := resolve(t.hostname) or_return
- ep := ep4 if ep4.address != nil else ep6 // NOTE(tetra): We don't know what family the server uses, so we just default to IP4.
- ep.port = port
- return dial_tcp_from_endpoint(ep, options)
+ return dial_tcp_from_host(t, options)
}
unreachable()
}
@@ -90,6 +101,8 @@ dial_tcp :: proc{
dial_tcp_from_address_and_port,
dial_tcp_from_hostname_and_port_string,
dial_tcp_from_hostname_with_port_override,
+ dial_tcp_from_host,
+ dial_tcp_from_host_or_endpoint,
}
create_socket :: proc(family: Address_Family, protocol: Socket_Protocol) -> (socket: Any_Socket, err: Network_Error) {