commit - 2d3c565b4bb352375a5b9d76490504677e1aadf3
commit + 108846853f74d3cd0934bf2ccb2041b95668f1b8
blob - 1975fffc672c1a59c4c8816075b5d03d14e00223
blob + 10a3a3640641835ce1e8ed3e36313257b7b03947
--- net.c
+++ net.c
#include "compat.h"
-/* XXX needs some work to run on top of ev */
-#undef HAVE_ASR_RUN
-
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
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;
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)));
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;
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) {
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)
{
req->len = strlen(req->req);
req->proto = r.proto;
- conn_towards(req);
+ req_resolve(-1, 0, req);
break;
case IMSG_CERT_STATUS: