commit 108846853f74d3cd0934bf2ccb2041b95668f1b8 from: Omar Polo date: Thu Feb 22 13:29:11 2024 UTC net: re-enable asr_run Make asr_run() work on top of ev. While here, rename the function names and add real error checking. commit - 2d3c565b4bb352375a5b9d76490504677e1aadf3 commit + 108846853f74d3cd0934bf2ccb2041b95668f1b8 blob - 1975fffc672c1a59c4c8816075b5d03d14e00223 blob + 10a3a3640641835ce1e8ed3e36313257b7b03947 --- net.c +++ net.c @@ -16,9 +16,6 @@ #include "compat.h" -/* XXX needs some work to run on top of ev */ -#undef HAVE_ASR_RUN - #include #include #include @@ -80,8 +77,9 @@ struct req { struct addrinfo *servinfo, *p; #if HAVE_ASR_RUN - struct addrinfo hints; - struct event_asr *asrev; + struct asr_query *q; + int ar_fd; + unsigned long ar_timeout; #endif TAILQ_ENTRY(req) reqs; @@ -91,12 +89,6 @@ static struct req *req_by_id(uint32_t); static void die(void) __attribute__((__noreturn__)); - -#if HAVE_ASR_RUN -static void query_done(struct asr_result*, void*); -#endif -static void conn_towards(struct req*); - static void close_with_err(struct req*, const char*); static void close_with_errf(struct req*, const char*, ...) __attribute__((format(printf, 2, 3))); @@ -132,63 +124,7 @@ die(void) abort(); /* TODO */ } -#if HAVE_ASR_RUN static void -query_done(struct asr_result *res, void *d) -{ - struct req *req = d; - - req->asrev = NULL; - if (res->ar_gai_errno != 0) { - close_with_errf(req, "failed to resolve %s: %s", - req->host, gai_strerror(res->ar_gai_errno)); - return; - } - - req->fd = -1; - req->servinfo = res->ar_addrinfo; - req->p = res->ar_addrinfo; - req->state = CONN_CONNECTING; - net_ev(-1, EV_READ, req); -} - -static void -conn_towards(struct req *req) -{ - struct asr_query *q; - - req->hints.ai_family = AF_UNSPEC; - req->hints.ai_socktype = SOCK_STREAM; - q = getaddrinfo_async(req->host, req->port, &req->hints, - NULL); - req->asrev = event_asr_run(q, query_done, req); -} -#else -static void -conn_towards(struct req *req) -{ - struct addrinfo hints; - int status; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - if ((status = getaddrinfo(req->host, req->port, &hints, - &req->servinfo))) { - close_with_errf(req, "failed to resolve %s: %s", - req->host, gai_strerror(status)); - return; - } - - req->fd = -1; - req->p = req->servinfo; - req->state = CONN_CONNECTING; - net_ev(-1, EV_READ, req); -} -#endif - -static void close_conn(int fd, int ev, void *d) { struct req *req = d; @@ -197,8 +133,14 @@ close_conn(int fd, int ev, void *d) req->state = CONN_CLOSE; #if HAVE_ASR_RUN - if (req->asrev != NULL) - event_asr_abort(req->asrev); + if (req->ar_timeout) { + ev_timer_cancel(req->ar_timeout); + req->ar_timeout = 0; + } + if (req->q) { + asr_abort(req->q); + ev_del(req->ar_fd); + } #endif if (req->handshake_tout != 0) { @@ -259,6 +201,97 @@ close_with_errf(struct req *req, const char *fmt, ...) free(s); } +#if HAVE_ASR_RUN +static void +req_resolve(int fd, int ev, void *d) +{ + struct req *req = d; + struct addrinfo hints; + struct asr_result ar; + struct timeval tv; + + if (req->q == NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + req->q = getaddrinfo_async(req->host, req->port, &hints, NULL); + if (req->q == NULL) { + close_with_errf(req, "getaddrinfo_async: %s", + strerror(errno)); + return; + } + } + + if (fd != -1) + ev_del(fd); + if (req->ar_timeout) { + ev_timer_cancel(req->ar_timeout); + req->ar_timeout = 0; + } + + if (asr_run(req->q, &ar) == 0) { + ev = 0; + if (ar.ar_cond & ASR_WANT_READ) + ev |= EV_READ; + if (ar.ar_cond & ASR_WANT_WRITE) + ev |= EV_WRITE; + + req->ar_fd = ar.ar_fd; + if (ev_add(req->ar_fd, ev, req_resolve, req) == -1) { + close_with_errf(req, "ev_add failure: %s", + strerror(errno)); + return; + } + + tv.tv_sec = ar.ar_timeout / 1000; + tv.tv_usec = (ar.ar_timeout % 1000) * 1000; + req->ar_timeout = ev_timer(&tv, req_resolve, req); + if (req->ar_timeout == 0) + close_with_errf(req, "ev_timer failure: %s", + strerror(errno)); + return; + } + + req->ar_fd = -1; + req->q = NULL; + + if (ar.ar_gai_errno) { + close_with_errf(req, "failed to resolve %s: %s", + req->host, gai_strerror(ar.ar_gai_errno)); + return; + } + + req->servinfo = ar.ar_addrinfo; + + req->fd = -1; + req->p = req->servinfo; + net_ev(-1, EV_READ, req); +} +#else +static void +req_resolve(int fd, int ev, struct req *req) +{ + struct addrinfo hints; + int s; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + s = getaddrinfo(req->host, req->port, &hints, &req->servinfo); + if (s != 0) { + close_with_errf(req, "failed to resolve %s: %s", + req->host, gai_strerror(s)); + return; + } + + req->fd = -1; + req->p = req->servinfo; + net_ev(-1, EV_READ, req); +} +#endif + static int try_to_connect(struct req *req) { @@ -592,7 +625,7 @@ handle_dispatch_imsg(int fd, int event, void *d) req->len = strlen(req->req); req->proto = r.proto; - conn_towards(req); + req_resolve(-1, 0, req); break; case IMSG_CERT_STATUS: