diff --git a/adsbus/Makefile b/adsbus/Makefile index 6223b8c..9092ded 100644 --- a/adsbus/Makefile +++ b/adsbus/Makefile @@ -1,7 +1,7 @@ CC ?= clang -CFLAGS ?= -Wall -Werror -O4 -g --std=gnu11 --pedantic-errors -fPIE -pie -fstack-protector-strong +CFLAGS ?= -Wall -Werror -O4 -g --std=gnu11 --pedantic-errors -fPIE -pie -fstack-protector-strong -pthread LDFLAGS ?= $(CFLAGS) -Wl,-z,relro -Wl,-z,now -LIBS ?= -ljansson -lanl +LIBS ?= -ljansson OBJ_NETWORK = incoming.o outgoing.o receive.o send.o OBJ_PROTOCOL = airspy_adsb.o beast.o json.o raw.o stats.o diff --git a/adsbus/adsbus.c b/adsbus/adsbus.c index bb897b0..4b12b0a 100644 --- a/adsbus/adsbus.c +++ b/adsbus/adsbus.c @@ -14,6 +14,7 @@ #include "peer.h" #include "rand.h" #include "receive.h" +#include "resolve.h" #include "send.h" #include "server.h" #include "stats.h" @@ -100,6 +101,7 @@ int main(int argc, char *argv[]) { hex_init(); rand_init(); + resolve_init(); server_init(); wakeup_init(); peer_init(); @@ -117,6 +119,7 @@ int main(int argc, char *argv[]) { peer_loop(); rand_cleanup(); + resolve_cleanup(); wakeup_cleanup(); send_cleanup(); diff --git a/adsbus/resolve.c b/adsbus/resolve.c index c2bccc1..705d44b 100644 --- a/adsbus/resolve.c +++ b/adsbus/resolve.c @@ -5,73 +5,91 @@ #include #include #include +#include #include "peer.h" #include "resolve.h" -struct resolve { - struct peer peer; - +struct resolve_request { + int fd; + const char *node; + const char *service; + int flags; struct addrinfo **addrs; const char **error; - - struct peer *inner_peer; - - struct addrinfo ar_request; - struct gaicb gaicb; - struct gaicb *requests[1]; - - struct sigevent sev; }; +struct resolve_peer { + struct peer peer; + struct peer *inner_peer; +}; + +static pthread_t resolve_thread; +static int resolve_write_fd; + static void resolve_handler(struct peer *peer) { - struct resolve *res = (struct resolve *) peer; + struct resolve_peer *resolve_peer = (struct resolve_peer *) peer; - assert(!close(res->peer.fd)); + assert(!close(resolve_peer->peer.fd)); - int err = gai_error(&res->gaicb); - if (err == 0) { - *res->addrs = res->gaicb.ar_result; - *res->error = NULL; - } else { - *res->addrs = NULL; - *res->error = gai_strerror(err); - } - struct peer *inner_peer = res->inner_peer; - free(res); + struct peer *inner_peer = resolve_peer->inner_peer; + free(resolve_peer); inner_peer->event_handler(inner_peer); } -static void resolve_callback(union sigval val) { - assert(!close(val.sival_int)); +static void *resolve_main(void *arg) { + int fd = (intptr_t) arg; + struct resolve_request *request; + ssize_t ret; + while ((ret = read(fd, &request, sizeof(request))) == sizeof(request)) { + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | request->flags, + }; + int err = getaddrinfo(request->node, request->service, &hints, request->addrs); + if (err) { + *request->addrs = NULL; + *request->error = gai_strerror(err); + } else { + *request->error = NULL; + } + close(request->fd); + free(request); + } + assert(!ret); + return NULL; +} + +void resolve_init() { + int fds[2]; + assert(!pipe2(fds, O_CLOEXEC)); + resolve_write_fd = fds[1]; + assert(!pthread_create(&resolve_thread, NULL, resolve_main, (void *) (intptr_t) fds[0])); +} + +void resolve_cleanup() { + assert(!close(resolve_write_fd)); + assert(!pthread_join(resolve_thread, NULL)); } void resolve(struct peer *peer, const char *node, const char *service, int flags, struct addrinfo **addrs, const char **error) { - struct resolve *res = malloc(sizeof(*res)); - res->addrs = addrs; - res->error = error; - res->inner_peer = peer; - int fds[2]; - assert(!pipe2(fds, O_NONBLOCK)); - res->peer.fd = fds[0]; - res->peer.event_handler = resolve_handler; - peer_epoll_add((struct peer *) res, EPOLLRDHUP); + assert(!pipe2(fds, O_CLOEXEC)); - res->requests[0] = &res->gaicb; - res->gaicb.ar_name = node; - res->gaicb.ar_service = service; - res->gaicb.ar_request = &res->ar_request; - res->ar_request.ai_family = AF_UNSPEC; - res->ar_request.ai_socktype = SOCK_STREAM; - res->ar_request.ai_protocol = 0; - res->ar_request.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | flags; + struct resolve_request *request = malloc(sizeof(*request)); + request->fd = fds[1]; + request->node = node; + request->service = service; + request->flags = flags; + request->addrs = addrs; + request->error = error; + assert(write(resolve_write_fd, &request, sizeof(request)) == sizeof(request)); - res->sev.sigev_notify = SIGEV_THREAD; - res->sev.sigev_value.sival_int = fds[1]; - res->sev.sigev_notify_function = resolve_callback; - res->sev.sigev_notify_attributes = NULL; - - assert(!getaddrinfo_a(GAI_NOWAIT, res->requests, 1, &res->sev)); + struct resolve_peer *resolve_peer = malloc(sizeof(*resolve_peer)); + resolve_peer->peer.fd = fds[0]; + resolve_peer->peer.event_handler = resolve_handler; + resolve_peer->inner_peer = peer; + peer_epoll_add((struct peer *) resolve_peer, EPOLLRDHUP); } diff --git a/adsbus/resolve.h b/adsbus/resolve.h index d81777c..61f4abe 100644 --- a/adsbus/resolve.h +++ b/adsbus/resolve.h @@ -3,4 +3,6 @@ struct peer; struct addrinfo; +void resolve_init(); +void resolve_cleanup(); void resolve(struct peer *, const char *, const char *, int, struct addrinfo **, const char **);