extern struct ev_loop *event_base;
-struct ares_options options;
-ares_channel Channel;
void SockStateCb(void *data, int sock, int read, int write);
IO->DNSReplyFree = (FreeDNSReply) ares_free_data;
}
-
void QueryCb(void *arg,
int status,
int timeouts,
IO->DNSStatus = status;
if (status == ARES_SUCCESS)
IO->DNS_CB(arg, abuf, alen);
- IO->PostDNS(IO);
+ else
+ IO->DNSStatus = status;
+/// ev_io_stop(event_base, &IO->dns_io_event);
+
+ ev_timer_init(&IO->unwind_stack_timeout,
+ IO_postdns_callback, 0.0, 0);
+ IO->unwind_stack_timeout.data = IO;
+ ev_timer_start(event_base, &IO->unwind_stack_timeout);
}
-int QueueQuery(ns_type Type, char *name, AsyncIO *IO, IO_CallBack PostDNS)
+void QueryCbDone(AsyncIO *IO)
{
- int length, family;
- char address_b[sizeof(struct in6_addr)];
- int optmask = 0;
- fd_set rfd, wfd;
+ ev_timer_stop(event_base, &IO->unwind_stack_timeout);
+}
+
+void InitC_ares_dns(AsyncIO *IO)
+{
+ int optmask = 0;
if (IO->DNSChannel == NULL) {
optmask |= ARES_OPT_SOCK_STATE_CB;
IO->DNSOptions.sock_state_cb = SockStateCb;
IO->DNSOptions.sock_state_cb_data = IO;
ares_init_options(&IO->DNSChannel, &IO->DNSOptions, optmask);
}
+}
+int QueueQuery(ns_type Type, char *name, AsyncIO *IO, IO_CallBack PostDNS)
+{
+ int length, family;
+ char address_b[sizeof(struct in6_addr)];
+ InitC_ares_dns(IO);
IO->PostDNS = PostDNS;
switch(Type) {
case ns_t_a:
return 0;
}
ares_query(IO->DNSChannel, name, ns_c_in, Type, QueryCb, IO);
- ares_fds(IO->DNSChannel, &rfd, &wfd);
return 1;
}
-static void DNS_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
+static void DNS_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
AsyncIO *IO = watcher->data;
- ares_process_fd(IO->DNSChannel, IO->sock, 0);
+ ares_process_fd(IO->DNSChannel, ARES_SOCKET_BAD, IO->dns_send_event.fd);
}
-
-static void DNS_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
+static void DNS_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
AsyncIO *IO = watcher->data;
- ares_process_fd(IO->DNSChannel, 0, IO->sock);
+ ares_process_fd(IO->DNSChannel, IO->dns_recv_event.fd, ARES_SOCKET_BAD);
}
void SockStateCb(void *data, int sock, int read, int write)
{
+/*
struct timeval tvbuf, maxtv, *ret;
int64_t time = 10;
+*/
AsyncIO *IO = data;
/* already inside of the event queue. */
- IO->sock = sock;
- ev_io_init(&IO->recv_event, DNS_recv_callback, IO->sock, EV_READ);
- IO->recv_event.data = IO;
- ev_io_init(&IO->send_event, DNS_send_callback, IO->sock, EV_WRITE);
- IO->send_event.data = IO;
- if (write)
- ev_io_start(event_base, &IO->send_event);
- else
- ev_io_start(event_base, &IO->recv_event);
-
- maxtv.tv_sec = time/1000;
- maxtv.tv_usec = (time % 1000) * 1000;
-
- ret = ares_timeout(IO->DNSChannel, &maxtv, &tvbuf);
+ if (read) {
+ if ((IO->dns_recv_event.fd != sock) &&
+ (IO->dns_recv_event.fd != 0) &&
+ ((IO->active_dns_event & EV_READ) != 0)) {
+ ev_io_stop(event_base, &IO->dns_recv_event);
+ }
+ IO->dns_recv_event.fd = sock;
+ ev_io_init(&IO->dns_recv_event, DNS_recv_callback, IO->dns_recv_event.fd, EV_READ);
+ IO->dns_recv_event.data = IO;
+ ev_io_start(event_base, &IO->dns_recv_event);
+ IO->active_dns_event = IO->active_dns_event | EV_READ;
+ }
+ if (write) {
+ if ((IO->dns_send_event.fd != sock) &&
+ (IO->dns_send_event.fd != 0) &&
+ ((IO->active_dns_event & EV_WRITE) != 0)) {
+ ev_io_stop(event_base, &IO->dns_send_event);
+ }
+ IO->dns_send_event.fd = sock;
+ ev_io_init(&IO->dns_send_event, DNS_send_callback, IO->dns_send_event.fd, EV_WRITE);
+ IO->dns_send_event.data = IO;
+ ev_io_start(event_base, &IO->dns_send_event);
+ IO->active_dns_event = IO->active_dns_event | EV_WRITE;
+ }
+/*
+ ev_io_start(event_base, &IO->dns_io_event);
+ maxtv.tv_sec = time/1000;
+ maxtv.tv_usec = (time % 1000) * 1000;
+
+ ret = ares_timeout(IO->DNSChannel, &maxtv, &tvbuf);
+ }
+*/
+ if ((read == 0) && (write == 0)) {
+ if ((IO->active_dns_event & EV_READ) != 0)
+ ev_io_stop(event_base, &IO->dns_recv_event);
+ if ((IO->active_dns_event & EV_WRITE) != 0)
+ ev_io_stop(event_base, &IO->dns_send_event);
+ IO->active_dns_event = 0;
+ }
}
CTDL_MODULE_INIT(c_ares_client)
{
if (!threading)
{
- int optmask = 0;
-
-
int r = ares_library_init(ARES_LIB_INIT_ALL);
if (0 != r) {
// TODO
// ThrowException(Exception::Error(String::New(ares_strerror(r))));
//// assert(r == 0);
}
-
- optmask |= ARES_OPT_SOCK_STATE_CB;
- memset(&options, 0, sizeof(struct ares_options));
- options.sock_state_cb = SockStateCb;
-
- ares_init_options(&Channel, &options, optmask);
-
}
return "c-ares";
}