From 9d2c11ebf759e16e6becaf1d4ba440875c600b70 Mon Sep 17 00:00:00 2001 From: Armin Preiml <apreiml@strohwolke.at> Date: Thu, 23 Jan 2025 15:54:31 +0100 Subject: [PATCH] ev::dial: nomen changes Signed-off-by: Armin Preiml <apreiml@strohwolke.at> --- ev/dial/ip.ha | 30 ++++++++++++++++++++---------- ev/dial/registry.ha | 10 +++++----- ev/dial/resolve.ha | 59 ++++++++++++++++++++++++++++++++++++++++++----------- diff --git a/ev/dial/ip.ha b/ev/dial/ip.ha index 0819889dc44822759600d18517a63d603f65d4df..a0ea529978c7845f811bffb175d8d2fc26f301ed 100644 --- a/ev/dial/ip.ha +++ b/ev/dial/ip.ha @@ -35,12 +35,17 @@ loop = loop, cb = cb, user = user, ... - }); + })?; - const req = resolve(loop, "tcp", addr, - service, &dial_tcp_resolvecb, state)?; - state.req = req; - return ev::mkreq(&dial_tcp_cancel, state); + match (resolve(loop, "tcp", addr, + service, &dial_tcp_resolvecb, state)) { + case let req: ev::req => + state.req = req; + return ev::mkreq(&dial_tcp_cancel, state); + case let e: error => + free(state); + return e; + }; }; fn dial_tcp_resolvecb( @@ -135,12 +140,17 @@ loop = loop, cb = cb, user = user, ... - }); + })?; - const req = resolve(loop, "udp", addr, - service, &dial_udp_resolvecb, state)?; - state.req = req; - return ev::mkreq(&dial_udp_cancel, state); + match (resolve(loop, "udp", addr, + service, &dial_udp_resolvecb, state)) { + case let req: ev::req => + state.req = req; + return ev::mkreq(&dial_udp_cancel, state); + case let e: error => + free(state); + return e; + }; }; fn dial_udp_resolvecb( diff --git a/ev/dial/registry.ha b/ev/dial/registry.ha index 982a878ffb8f9a6f6d66e1a6a2fcbd34bba755e4..ee9266cf87e99ad38858d571f826765784588ba7 100644 --- a/ev/dial/registry.ha +++ b/ev/dial/registry.ha @@ -16,7 +16,7 @@ // system. export type unknown_service = !void; // Errors which can occur from dial. -export type error = !(invalid_address | unknown_service +export type error = !(nomem | invalid_address | unknown_service | net::error | dns::error | hosts::error | errors::error); // Converts an [[error]] to a human-readable string. @@ -86,11 +86,11 @@ }; // Registers a new transport-level protocol (e.g. TCP) with the dialer. The name // should be statically allocated. -export fn registerproto(name: str, dial: *dialer) void = { +export fn registerproto(name: str, dial: *dialer) (void | nomem) = { append(protocols, protocol { name = name, dial = dial, - }); + })?; }; // Registers a new application-level service (e.g. SSH) with the dialer. Note @@ -102,13 +102,13 @@ proto: str, name: str, alias: []str, port: u16, -) void = { +) (void | nomem) = { append(services, service { proto = proto, name = name, alias = alias, port = port, - }); + })?; }; fn lookup_service(proto: str, service: str) (u16 | void) = { diff --git a/ev/dial/resolve.ha b/ev/dial/resolve.ha index 3be0d59d188cc79d03306be630f90178f58a33ec..d828724def216cdb655f844f7fb2a149496e2bad 100644 --- a/ev/dial/resolve.ha +++ b/ev/dial/resolve.ha @@ -43,7 +43,7 @@ let state = alloc(resolve_state { cb = cb, user = user, ... - }); + })?; const (addr, port) = match (dial::splitaddr(addr, service)) { case let svc: (str, u16) => @@ -77,13 +77,25 @@ }; match (ip::parse(addr)) { case let addr: ip::addr => - const addrs = alloc([addr]); - resolve_finish(state, (addrs, port)); - return ev::req { ... }; + let addrs: []ip::addr = []; + match (append(addrs, addr)) { + case void => + resolve_finish(state, (addrs, port)); + return ev::req { ... }; + case nomem => + resolve_finish(state, nomem); + return nomem; + }; case ip::invalid => yield; }; - const addrs = hosts::lookup(addr)?; + const addrs = match (hosts::lookup(addr)) { + case let addrs: []ip::addr => + yield addrs; + case let e: hosts::error => + resolve_finish(state, nomem); + return e; + }; if (len(addrs) != 0) { resolve_finish(state, (addrs, port)); return ev::req { ... }; @@ -148,8 +160,11 @@ ], ... }; + let ok = false; state.r6 = edns::query(loop, &query6, &query_cb_v6, state)?; + defer if(!ok) ev::cancel(&state.r6); state.r4 = edns::query(loop, &query4, &query_cb_v4, state)?; + ok = true; return ev::mkreq(&resolve_cancel, state); }; @@ -171,7 +186,7 @@ free(state.ip); free(state); }; -fn query_cb_v4(user: nullable *opaque, r: (*dns::message | dns::error)) void = { +fn query_cb_v4(user: nullable *opaque, r: (*dns::message | dns::error | nomem)) void = { let state = user: *resolve_state; state.r4 = ev::req { ... }; @@ -180,8 +195,18 @@ case let err: dns::error => ev::cancel(&state.r6); resolve_finish(state, err); return; + case nomem => + ev::cancel(&state.r6); + resolve_finish(state, nomem); + return; case let msg: *dns::message => - collect_answers(&state.ip, &msg.answers); + match (collect_answers(&state.ip, &msg.answers)) { + case void => void; + case nomem => + ev::cancel(&state.r6); + resolve_finish(state, nomem); + return; + }; state.nq += 1; }; @@ -191,7 +216,7 @@ }; resolve_finish(state, (state.ip, state.port)); }; -fn query_cb_v6(user: nullable *opaque, r: (*dns::message | dns::error)) void = { +fn query_cb_v6(user: nullable *opaque, r: (*dns::message | dns::error | nomem)) void = { let state = user: *resolve_state; state.r6 = ev::req { ... }; @@ -199,9 +224,19 @@ match (r) { case let err: dns::error => ev::cancel(&state.r4); resolve_finish(state, err); + return; + case nomem => + ev::cancel(&state.r4); + resolve_finish(state, nomem); return; case let msg: *dns::message => - collect_answers(&state.ip, &msg.answers); + match (collect_answers(&state.ip, &msg.answers)) { + case void => void; + case nomem => + ev::cancel(&state.r4); + resolve_finish(state, nomem); + return; + }; state.nq += 1; }; @@ -211,13 +246,13 @@ }; resolve_finish(state, (state.ip, state.port)); }; -fn collect_answers(addrs: *[]ip::addr, answers: *[]dns::rrecord) void = { +fn collect_answers(addrs: *[]ip::addr, answers: *[]dns::rrecord) (void | nomem) = { for (let answer &.. answers) { match (answer.rdata) { case let addr: dns::aaaa => - append(addrs, addr: ip::addr); + append(addrs, addr: ip::addr)?; case let addr: dns::a => - append(addrs, addr: ip::addr); + append(addrs, addr: ip::addr)?; case => void; }; }; -- 2.48.1