From 6411a3107aabdcd24a4b5c25ea97292ab8b25535 Mon Sep 17 00:00:00 2001 From: Laurent Ghigonis Date: Sat, 15 Dec 2012 03:09:01 +0100 Subject: integrate gg_sniff dns handling into libggnet it can be enabled in ggnet by calling ggnet_set_dns(), or can be used independently by including an calling ggnet_dns_new(), ggnet_dns_free() and ggnet_dns_reverse() WARNING: not tested yet, only compiles --- libglouglou/Makefile | 4 +- libglouglou/libggnet.c | 16 +++++++ libglouglou/libggnet.h | 16 ++++++- libglouglou/libggnet_dns.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ libglouglou/libggnet_dns.h | 22 +++++++++ 5 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 libglouglou/libggnet_dns.c create mode 100644 libglouglou/libggnet_dns.h diff --git a/libglouglou/Makefile b/libglouglou/Makefile index 5f1150f..0343e6f 100644 --- a/libglouglou/Makefile +++ b/libglouglou/Makefile @@ -6,8 +6,8 @@ LIBDIR=$(PREFIX)/lib LIBNAME=libglouglou TARGET = ${LIBNAME}.so -SOURCES = libglouglou.c sendbuf.c utils.c libggnet.c -HEADERS = libglouglou.h libggnet.h +SOURCES = libglouglou.c sendbuf.c utils.c libggnet.c libggnet_dns.c +HEADERS = libglouglou.h libggnet.h libggnet_dns.h OBJECTS = $(SOURCES:.c=.o) all: $(TARGET) diff --git a/libglouglou/libggnet.c b/libglouglou/libggnet.c index e6df4bd..7367372 100644 --- a/libglouglou/libggnet.c +++ b/libglouglou/libggnet.c @@ -3,6 +3,7 @@ #include #include "libggnet.h" +#include "libggnet_dns.h" static struct ggnet_nodegroup *nodegroup_add(struct ggnet *, enum ggnet_grouptype, void *, @@ -38,6 +39,7 @@ ggnet_new(int manage_connid) * * Note: Must be set before any use of ggnet */ +// XXX break API to ggnet_set_grouping() void ggnet_grouping_set(struct ggnet *net, int set, void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *), @@ -48,6 +50,20 @@ ggnet_grouping_set(struct ggnet *net, int set, net->cb_delgroup = cb_delgroup; } +void +ggnet_set_dns(struct ggnet *net, int set, + struct event_base *ev_base, + void (*cb_nodename)(struct ggnet_node *)) +{ + net->use_dns = set; + if (set) { + net->ggdns = ggnet_dns_new(ev_base); + net->cb_nodename = cb_nodename; + } + else if (net->use_dns) + ggnet_dns_free(net->ggdns); +} + void ggnet_debug_set(struct ggnet *net, int set) { diff --git a/libglouglou/libggnet.h b/libglouglou/libggnet.h index 11d3534..cbcdc99 100644 --- a/libglouglou/libggnet.h +++ b/libglouglou/libggnet.h @@ -4,6 +4,10 @@ #include #include +#include +#include +#include + #if defined(__OpenBSD__) #include #else @@ -80,17 +84,25 @@ struct ggnet { u_int16_t conn_freeids[GGNET_CONN_FREEIDS_COUNT]; int conn_freeids_ptr; int manage_connid; + time_t time; + int debug; + /* grouping */ int use_grouping; void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *); void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *); - time_t time; - int debug; + /* dns */ + int use_dns; + struct ggnet_dns *ggdns; + void (*cb_nodename)(struct ggnet_node *); }; struct ggnet *ggnet_new(int); void ggnet_grouping_set(struct ggnet *, int, void (*cb_addgroup)(struct ggnet *, struct ggnet_nodegroup *, struct ggnet_nodegroup *), void (*cb_delgroup)(struct ggnet *, struct ggnet_nodegroup *)); +void ggnet_set_dns(struct ggnet *net, int set, + struct event_base *ev_base, + void (*cb_nodename)(struct ggnet_node *)); void ggnet_debug_set(struct ggnet *, int); void ggnet_free(struct ggnet *); struct ggnet_node *ggnet_node_add(struct ggnet *, struct in_addr *); diff --git a/libglouglou/libggnet_dns.c b/libglouglou/libggnet_dns.c new file mode 100644 index 0000000..9685cde --- /dev/null +++ b/libglouglou/libggnet_dns.c @@ -0,0 +1,113 @@ +#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 *dns = NULL; + + dns = calloc(1, sizeof(struct ggnet_dns)); + if (!dns) { + printf("could not allocate ggnet_dns\n"); + exit(1); + } + dns->ev_base = ev_base; + dns->evdns_base = evdns_base_new(ev_base, 1); + if (!dns->evdns_base) + goto err; + return dns; + +err: + if (dns) + free(dns); + return NULL; +} + +void +ggnet_dns_free(struct ggnet_dns *dns) +{ + evdns_base_free(dns->evdns_base, 1); + free(dns); +} + +int +ggnet_dns_reverse(struct ggnet_dns *dns, + 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 = dns; + memcpy(&req->ip, ip, sizeof(struct in_addr)); + req->cb_usr = cb_usr; + req->data = data; + + LIST_INSERT_HEAD(&dns->req_reverse_list, req, entry); + dns->req_reverse_pending++; + ereq = evdns_base_resolve_reverse(dns->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); +} diff --git a/libglouglou/libggnet_dns.h b/libglouglou/libggnet_dns.h new file mode 100644 index 0000000..f74f696 --- /dev/null +++ b/libglouglou/libggnet_dns.h @@ -0,0 +1,22 @@ +#include +#include +#include + +#if defined(__OpenBSD__) +#include +#else +#include +#endif + +struct ggnet_dns { + struct event_base *ev_base; + struct evdns_base *evdns_base; + int req_reverse_pending; + LIST_HEAD(, req_reverse) req_reverse_list; /* XXX for now unused. remove ? */ +}; + +struct ggnet_dns *ggnet_dns_new(struct event_base *); +void ggnet_dns_free(struct ggnet_dns *); +int ggnet_dns_reverse(struct ggnet_dns *, struct in_addr *, + void (*cb_usr)(struct in_addr *, char *, void *), + void *); -- cgit v1.2.3-59-g8ed1b