#include #include #include "libggnet_dns.h" /* * For dns with libevent, see * http://www.wangafu.net/~nickm/libevent-2.0/doxygen/html/dns_8h.html * http://www.wangafu.net/~nickm/libevent-book/Ref9_dns.html * spike/evdns_chrooted.c * spike/evdns.c */ static void _cb_evdns_reverse(int, char, int, int, void *, void *); struct req_reverse { LIST_ENTRY(req_reverse) entry; struct ggnet_dns *ggdns; struct evdns_request *ereq; struct in_addr ip; void (*cb_usr)(struct in_addr *, char *, void *); void *data; }; struct ggnet_dns * ggnet_dns_new(struct event_base *ev_base) { struct ggnet_dns *ggdns = NULL; ggdns = calloc(1, sizeof(struct ggnet_dns)); if (!ggdns) { printf("could not allocate ggnet_dns\n"); exit(1); } ggdns->ev_base = ev_base; ggdns->evdns_base = evdns_base_new(ev_base, 1); if (!ggdns->evdns_base) goto err; return ggdns; err: if (ggdns) free(ggdns); return NULL; } void ggnet_dns_free(struct ggnet_dns *ggdns) { evdns_base_free(ggdns->evdns_base, 1); free(ggdns); } int ggnet_dns_reverse(struct ggnet_dns *ggdns, struct in_addr *ip, void (*cb_usr)(struct in_addr *, char *, void *), void *data) { struct evutil_addrinfo hints; struct req_reverse *req; struct evdns_request *ereq; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = EVUTIL_AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; req = malloc(sizeof(struct req_reverse)); if (!req) { printf("could not allocate req_reverse\n"); exit(1); } req->ggdns = ggdns; memcpy(&req->ip, ip, sizeof(struct in_addr)); req->cb_usr = cb_usr; req->data = data; LIST_INSERT_HEAD(&ggdns->req_reverse_list, req, entry); ggdns->req_reverse_pending++; ereq = evdns_base_resolve_reverse(ggdns->evdns_base, ip, 0, _cb_evdns_reverse, req); if (ereq == NULL) { printf("libggnet_dns WARNING: dns request for %d returned immediately\n", ip->s_addr); /* remove req from list and free it happened in the callback. */ return 0; } req->ereq = ereq; return 1; } static void _cb_evdns_reverse(int result, char type, int count, int ttl, void *addresses, void *arg) { struct req_reverse *req; req = arg; if (type != DNS_PTR) { printf("libggnet_dns WARNING: dns reverse for %d received non DNS_PTR\n", req->ip.s_addr); goto free; } req->cb_usr(&req->ip, addresses, req->data); free: LIST_REMOVE(req, entry); req->ggdns->req_reverse_pending--; free(req); }