From be97bd1d71a16ab5757eb8c29fa5f5b6aac410a1 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 13 Jul 2016 14:50:44 +0200 Subject: [PATCH] Mv getdns_context_set_listen_addresses in the lib Also, check for request_id + cancel a reply by specifying NULL as response to getdns_reply --- src/Makefile.in | 48 +++-- src/context.c | 5 + src/context.h | 3 + src/getdns/getdns_extra.h.in | 13 ++ src/libgetdns.symbols | 2 + ...ontext_set_listen_addresses.c => server.c} | 177 ++++++++++-------- ...ontext_set_listen_addresses.h => server.h} | 32 ++-- src/test/Makefile.in | 19 +- src/test/getdns_query.c | 19 +- 9 files changed, 176 insertions(+), 142 deletions(-) rename src/{test/getdns_context_set_listen_addresses.c => server.c} (86%) rename src/{test/getdns_context_set_listen_addresses.h => server.h} (70%) diff --git a/src/Makefile.in b/src/Makefile.in index 5960c7ff..c9ff78db 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -65,7 +65,7 @@ C99COMPATFLAGS=@C99COMPATFLAGS@ GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \ list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \ - rr-iter.lo stub.lo sync.lo ub_loop.lo util-internal.lo + rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \ str2wire.lo @@ -237,70 +237,78 @@ context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/debug.h $(srcdir)/g $(srcdir)/gldns/wire2str.h $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h + $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h \ + $(srcdir)/pubkey-pinning.h convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h \ $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \ $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h \ - $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h + $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ - $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \ - $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \ - $(srcdir)/util/val_secalgo.h + $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ + $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h \ + $(srcdir)/list.h $(srcdir)/util/val_secalgo.h general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \ $(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - getdns/getdns_extra.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + getdns/getdns_extra.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h + $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ + $(srcdir)/list.h $(srcdir)/dict.h pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \ $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \ $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ - $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h + getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \ + $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \ getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \ $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \ $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \ $(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \ - getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h + getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h \ + $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h +server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \ + $(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ + $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ + $(srcdir)/debug.h $(srcdir)/server.h stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \ $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h + $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \ getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \ - $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ - $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h + $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \ + $(srcdir)/gldns/wire2str.h ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ $(srcdir)/debug.h util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \ $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h \ $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \ - getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ + getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h \ $(srcdir)/gldns/rrdef.h version.lo version.o: version.c diff --git a/src/context.c b/src/context.c index 0618814a..a47124de 100644 --- a/src/context.c +++ b/src/context.c @@ -1216,6 +1216,8 @@ getdns_context_create_with_extended_memory_functions( _getdns_rbtree_init(&result->outbound_requests, transaction_id_cmp); _getdns_rbtree_init(&result->local_hosts, local_host_cmp); + result->server = NULL; + #ifdef HAVE_LIBUNBOUND result->resolution_type = GETDNS_RESOLUTION_RECURSING; #else @@ -1389,6 +1391,9 @@ getdns_context_destroy(struct getdns_context *context) /* cancel all outstanding requests */ cancel_outstanding_requests(context, 1); + /* Destroy listening addresses */ + (void) getdns_context_set_listen_addresses(context, NULL, NULL); + /* This needs to be done before cleaning the extension, because there * might be an idle_timeout schedules, which will not get unscheduled * with cancel_outstanding_requests. diff --git a/src/context.h b/src/context.h index 2ccea5c4..fd603b6d 100644 --- a/src/context.h +++ b/src/context.h @@ -44,6 +44,7 @@ #include "extension/default_eventloop.h" #include "util/rbtree.h" #include "ub_loop.h" +#include "server.h" struct getdns_dns_req; struct ub_ctx; @@ -260,6 +261,8 @@ struct getdns_context { */ _getdns_rbtree_t outbound_requests; + struct listen_set *server; + /* Event loop extension. */ getdns_eventloop *extension; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index 011275cd..d2bcd290 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -830,6 +830,19 @@ getdns_return_t getdns_str2int(const char *str, uint32_t *value); getdns_return_t getdns_context_config(getdns_context *context, const getdns_dict *config_dict); +typedef void (*getdns_request_handler_t)( + getdns_context *context, + getdns_dict *request, + getdns_transaction_t request_id +); + +getdns_return_t +getdns_context_set_listen_addresses(getdns_context *context, + getdns_request_handler_t handler, const getdns_list *listen_addresses); + +getdns_return_t getdns_reply(getdns_context *context, + getdns_transaction_t request_id, getdns_dict *reply); + #ifdef __cplusplus } #endif diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 6b5a28fe..6e3cb128 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -51,6 +51,7 @@ getdns_context_set_extended_memory_functions getdns_context_set_follow_redirects getdns_context_set_idle_timeout getdns_context_set_limit_outstanding_queries +getdns_context_set_listen_addresses getdns_context_set_memory_functions getdns_context_set_namespaces getdns_context_set_resolution_type @@ -124,6 +125,7 @@ getdns_print_json_dict getdns_print_json_list getdns_pubkey_pin_create_from_string getdns_pubkey_pinset_sanity_check +getdns_reply getdns_root_trust_anchor getdns_rr_dict2str getdns_rr_dict2str_buf diff --git a/src/test/getdns_context_set_listen_addresses.c b/src/server.c similarity index 86% rename from src/test/getdns_context_set_listen_addresses.c rename to src/server.c index 3b05e803..c42008dd 100644 --- a/src/test/getdns_context_set_listen_addresses.c +++ b/src/server.c @@ -26,11 +26,13 @@ */ #include "config.h" -#include "getdns_context_set_listen_addresses.h" +#include #include "getdns/getdns_extra.h" +#include "context.h" #include "types-internal.h" #include "debug.h" -#include +#include "util/rbtree.h" +#include "server.h" #define DNS_REQUEST_SZ 4096 #define DOWNSTREAM_IDLE_TIMEOUT 5000 @@ -63,9 +65,9 @@ struct listener { */ struct listen_set { getdns_context *context; - listen_set *next; getdns_request_handler_t handler; + _getdns_rbtree_t connections_set; size_t count; listener items[]; }; @@ -79,6 +81,9 @@ struct tcp_to_write { }; struct connection { + /* struct connection is a sub struct of _getdns_rbnode_t */ + _getdns_rbnode_t super; + listener *l; struct sockaddr_storage remote_in; socklen_t addrlen; @@ -88,14 +93,8 @@ struct connection { }; typedef struct tcp_connection { - /* A TCP connection is a connection */ - listener *l; - struct sockaddr_storage remote_in; - socklen_t addrlen; - - connection *next; - connection **prev_next; - /************************************/ + /* struct tcp_connection is a sub struct of connection */ + connection super; int fd; getdns_eventloop_event event; @@ -118,10 +117,10 @@ static void tcp_connection_destroy(tcp_connection *conn) tcp_to_write *cur, *next; - if (!(mf = priv_getdns_context_mf(conn->l->set->context))) + if (!(mf = &conn->super.l->set->context->mf)) return; - if (getdns_context_get_eventloop(conn->l->set->context, &loop)) + if (getdns_context_get_eventloop(conn->super.l->set->context, &loop)) return; if (conn->event.read_cb||conn->event.write_cb||conn->event.timeout_cb) @@ -139,10 +138,14 @@ static void tcp_connection_destroy(tcp_connection *conn) return; /* Unlink this connection */ - if ((*conn->prev_next = conn->next)) - conn->next->prev_next = conn->prev_next; + (void) _getdns_rbtree_delete( + &conn->super.l->set->connections_set, conn); + DEBUG_SERVER("[connection del] count: %d\n", + (int)conn->super.l->set->connections_set.count); + if ((*conn->super.prev_next = conn->super.next)) + conn->super.next->prev_next = conn->super.prev_next; - free_listen_set_when_done(conn->l->set); + free_listen_set_when_done(conn->super.l->set); GETDNS_FREE(*mf, conn); } @@ -157,10 +160,10 @@ static void tcp_write_cb(void *userarg) assert(userarg); - if (!(mf = priv_getdns_context_mf(conn->l->set->context))) + if (!(mf = &conn->super.l->set->context->mf)) return; - if (getdns_context_get_eventloop(conn->l->set->context, &loop)) + if (getdns_context_get_eventloop(conn->super.l->set->context, &loop)) return; /* Reset tcp_connection idle timeout */ @@ -195,28 +198,30 @@ static void tcp_write_cb(void *userarg) DOWNSTREAM_IDLE_TIMEOUT, &conn->event); } -void -_getdns_cancel_reply(getdns_context *context, getdns_transaction_t request_id) +static void +_getdns_cancel_reply(getdns_context *context, connection *conn) { - /* TODO: Check request_id at context->outbound_requests */ - connection *conn = (connection *)(intptr_t)request_id; struct mem_funcs *mf; if (!context || !conn) return; if (conn->l->transport == GETDNS_TRANSPORT_TCP) { - tcp_connection *conn = (tcp_connection *)(intptr_t)request_id; + tcp_connection *conn = (tcp_connection *)conn; if (conn->to_answer > 0 && --conn->to_answer == 0 && conn->fd == -1) tcp_connection_destroy(conn); } else if (conn->l->transport == GETDNS_TRANSPORT_UDP && - (mf = priv_getdns_context_mf(conn->l->set->context))) { + (mf = &conn->l->set->context->mf)) { listen_set *set = conn->l->set; /* Unlink this connection */ + (void) _getdns_rbtree_delete( + &set->connections_set, conn); + DEBUG_SERVER("[connection del] count: %d\n", + (int)set->connections_set.count); if ((*conn->prev_next = conn->next)) conn->next->prev_next = conn->prev_next; GETDNS_FREE(*mf, conn); @@ -236,10 +241,21 @@ getdns_reply( size_t len; getdns_return_t r; - if (!context || !reply || !conn) + if (!context || !conn) return GETDNS_RETURN_INVALID_PARAMETER; - if (!(mf = priv_getdns_context_mf(conn->l->set->context))) + if (!context->server) + return GETDNS_RETURN_GENERIC_ERROR;; + + if (_getdns_rbtree_search(&context->server->connections_set, conn) + != &conn->super) + return GETDNS_RETURN_NO_SUCH_LIST_ITEM; + + if (!reply) { + _getdns_cancel_reply(context, conn); + return GETDNS_RETURN_GOOD; + } + if (!(mf = &conn->l->set->context->mf)) return GETDNS_RETURN_GENERIC_ERROR;; if ((r = getdns_context_get_eventloop(conn->l->set->context, &loop))) @@ -260,6 +276,10 @@ getdns_reply( conn->l->fd = -1; } /* Unlink this connection */ + (void) _getdns_rbtree_delete( + &l->set->connections_set, conn); + DEBUG_SERVER("[connection del] count: %d\n", + (int)l->set->connections_set.count); if ((*conn->prev_next = conn->next)) conn->next->prev_next = conn->prev_next; @@ -320,10 +340,10 @@ static void tcp_read_cb(void *userarg) assert(userarg); - if (!(mf = priv_getdns_context_mf(conn->l->set->context))) + if (!(mf = &conn->super.l->set->context->mf)) return; - if ((r = getdns_context_get_eventloop(conn->l->set->context, &loop))) + if ((r = getdns_context_get_eventloop(conn->super.l->set->context, &loop))) return; /* Reset tcp_connection idle timeout */ @@ -381,8 +401,8 @@ static void tcp_read_cb(void *userarg) conn->to_answer++; /* Call request handler */ - conn->l->set->handler( - conn->l->set->context, request_dict, (intptr_t)conn); + conn->super.l->set->handler( + conn->super.l->set->context, request_dict, (intptr_t)conn); conn->read_pos = conn->read_buf; conn->to_read = 2; @@ -402,7 +422,8 @@ static void tcp_timeout_cb(void *userarg) if (conn->to_answer) { getdns_eventloop *loop; - if (getdns_context_get_eventloop(conn->l->set->context, &loop)) + if (getdns_context_get_eventloop( + conn->super.l->set->context, &loop)) return; loop->vmt->clear(loop, &conn->event); @@ -423,7 +444,7 @@ static void tcp_accept_cb(void *userarg) assert(userarg); - if (!(mf = priv_getdns_context_mf(l->set->context))) + if (!(mf = &l->set->context->mf)) return; if ((r = getdns_context_get_eventloop(l->set->context, &loop))) @@ -433,11 +454,10 @@ static void tcp_accept_cb(void *userarg) return; (void) memset(conn, 0, sizeof(tcp_connection)); - - conn->l = l; - conn->addrlen = sizeof(conn->remote_in); - if ((conn->fd = accept(l->fd, - (struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) { + conn->super.l = l; + conn->super.addrlen = sizeof(conn->super.remote_in); + if ((conn->fd = accept(l->fd, (struct sockaddr *) + &conn->super.remote_in, &conn->super.addrlen)) == -1) { /* IO error, cleanup this listener */ loop->vmt->clear(loop, &l->event); close(l->fd); @@ -458,10 +478,20 @@ static void tcp_accept_cb(void *userarg) conn->event.timeout_cb = tcp_timeout_cb; /* Insert connection */ - if ((conn->next = l->connections)) - conn->next->prev_next = &conn->next; - conn->prev_next = &l->connections; + conn->super.super.key = conn; + if (!_getdns_rbtree_insert( + &l->set->connections_set, &conn->super.super)) { + /* Memory error */ + GETDNS_FREE(*mf, conn); + return; + } + DEBUG_SERVER("[connection add] count: %d\n", + (int)l->set->connections_set.count); + if ((conn->super.next = l->connections)) + conn->super.next->prev_next = &conn->super.next; + conn->super.prev_next = &l->connections; l->connections = (connection *)conn; + (void) loop->vmt->schedule(loop, conn->fd, DOWNSTREAM_IDLE_TIMEOUT, &conn->event); @@ -485,7 +515,7 @@ static void udp_read_cb(void *userarg) if (l->fd == -1) return; - if (!(mf = priv_getdns_context_mf(l->set->context))) + if (!(mf = &l->set->context->mf)) return; if ((r = getdns_context_get_eventloop(l->set->context, &loop))) @@ -574,6 +604,15 @@ static void udp_read_cb(void *userarg) else { /* Insert connection */ + conn->super.key = conn; + if (!_getdns_rbtree_insert( + &l->set->connections_set, &conn->super)) { + /* Memory error */ + GETDNS_FREE(*mf, conn); + return; + } + DEBUG_SERVER("[connection add] count: %d\n", + (int)l->set->connections_set.count); if ((conn->next = l->connections)) conn->next->prev_next = &conn->next; conn->prev_next = &l->connections; @@ -586,25 +625,6 @@ static void udp_read_cb(void *userarg) GETDNS_FREE(*mf, conn); } -static void rm_listen_set(listen_set **root, listen_set *set) -{ - assert(root); - - while (*root && *root != set) - root = &(*root)->next; - - *root = set->next; - set->next = NULL; -} - -static listen_set *lookup_listen_set(listen_set *root, getdns_context *key) -{ - while (root && root->context != key) - root = root->next; - - return root; -} - static void free_listen_set_when_done(listen_set *set) { struct mem_funcs *mf; @@ -613,7 +633,7 @@ static void free_listen_set_when_done(listen_set *set) assert(set); assert(set->context); - if (!(mf = priv_getdns_context_mf(set->context))) + if (!(mf = &set->context->mf)) return; DEBUG_SERVER("To free listen set: %p\n", set); @@ -639,7 +659,7 @@ static void remove_listeners(listen_set *set) assert(set); assert(set->context); - if (!(mf = priv_getdns_context_mf(set->context))) + if (!(mf = &set->context->mf)) return; if (getdns_context_get_eventloop(set->context, &loop)) @@ -663,7 +683,8 @@ static void remove_listeners(listen_set *set) while (*conn_p) { tcp_connection_destroy(*conn_p); if (*conn_p && (*conn_p)->to_answer > 0) - conn_p = (tcp_connection **)&(*conn_p)->next; + conn_p = (tcp_connection **) + &(*conn_p)->super.next; } } free_listen_set_when_done(set); @@ -681,7 +702,7 @@ static getdns_return_t add_listeners(listen_set *set) assert(set); assert(set->context); - if (!(mf = priv_getdns_context_mf(set->context))) + if (!(mf = &set->context->mf)) return GETDNS_RETURN_GENERIC_ERROR; if ((r = getdns_context_get_eventloop(set->context, &loop))) @@ -738,6 +759,12 @@ static getdns_return_t add_listeners(listen_set *set) return GETDNS_RETURN_GOOD; } +static int +ptr_cmp(const void *a, const void *b) +{ + return a == b ? 0 : (a < b ? -1 : 1); +} + getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, getdns_request_handler_t request_handler, const getdns_list *listen_addresses) @@ -747,8 +774,6 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, static const uint32_t transport_ports[] = { 53, 53 }; static const size_t n_transports = sizeof( listen_transports) / sizeof(*listen_transports); - static listen_set *root = NULL; - listen_set *current_set; listen_set *new_set; size_t new_set_count; @@ -761,9 +786,11 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, size_t i; struct addrinfo hints; - DEBUG_SERVER("getdns_context_set_listen_addresses(%p, %p, %p)\n", context, request_handler, + DEBUG_SERVER("getdns_context_set_listen_addresses(%p, %p, %p)\n", + context, request_handler, + listen_addresses); - if (!(mf = priv_getdns_context_mf(context))) + if (!(mf = &context->mf)) return GETDNS_RETURN_GENERIC_ERROR; if ((r = getdns_context_get_eventloop(context, &loop))) @@ -775,7 +802,7 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, else if ((r = getdns_list_get_length(listen_addresses, &new_set_count))) return r; - if ((current_set = lookup_listen_set(root, context))) { + if ((current_set = context->server)) { for (i = 0; i < current_set->count; i++) current_set->items[i].action = to_remove; } @@ -783,7 +810,7 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, if (!current_set) return GETDNS_RETURN_GOOD; - rm_listen_set(&root, current_set); + context->server = NULL; /* action is already to_remove */ remove_listeners(current_set); return GETDNS_RETURN_GOOD; @@ -796,10 +823,12 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, sizeof(listener) * new_set_count * n_transports))) return GETDNS_RETURN_MEMORY_ERROR; - DEBUG_SERVER("New listen set: %p, current_set: %p\n", new_set, current_set); + _getdns_rbtree_init(&new_set->connections_set, ptr_cmp); + + DEBUG_SERVER("New listen set: %p, current_set: %p\n", + new_set, current_set); new_set->context = context; - new_set->next = root; new_set->handler = request_handler; new_set->count = new_set_count * n_transports; (void) memset(new_set->items, 0, @@ -938,10 +967,10 @@ getdns_return_t getdns_context_set_listen_addresses(getdns_context *context, } } if (current_set) { - rm_listen_set(&root, current_set); + context->server = NULL; remove_listeners(current_set); /* Is already remove */ } - root = new_set; + context->server = new_set; return GETDNS_RETURN_GOOD; } diff --git a/src/test/getdns_context_set_listen_addresses.h b/src/server.h similarity index 70% rename from src/test/getdns_context_set_listen_addresses.h rename to src/server.h index fac16f48..f60f267e 100644 --- a/src/test/getdns_context_set_listen_addresses.h +++ b/src/server.h @@ -1,3 +1,11 @@ +/** + * \file server.h + * @brief Functions for serving requests + * + * getdns_context_set_listen_addresses() and getdns_reply() are implemented + * here. + */ + /* * Copyright (c) 2013, NLNet Labs, Verisign, Inc. * All rights reserved. @@ -24,25 +32,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _GETDNS_SERVER_H_ +#define _GETDNS_SERVER_H_ -#ifndef GETDNS_CONTEXT_SET_LISTEN_ADDRESSES_H_ -#define GETDNS_CONTEXT_SET_LISTEN_ADDRESSES_H_ -#include "getdns/getdns.h" +struct listen_set; -typedef void (*getdns_request_handler_t)( - getdns_context *context, - getdns_dict *request, - getdns_transaction_t request_id -); - -getdns_return_t getdns_context_set_listen_addresses( - getdns_context *context, getdns_request_handler_t request_handler, - const getdns_list *listen_addresses); - -getdns_return_t getdns_reply(getdns_context *context, - getdns_transaction_t request_id, getdns_dict *reply); - -void _getdns_cancel_reply(getdns_context *context, - getdns_transaction_t request_id); - -#endif +#endif /* _GETDNS_SERVER_H_ */ diff --git a/src/test/Makefile.in b/src/test/Makefile.in index e3906eb8..a33ec15f 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -66,13 +66,10 @@ CHECK_CFLAGS=@CHECK_CFLAGS@ CHECK_OBJS=check_getdns_common.lo check_getdns_context_set_timeout.lo \ check_getdns.lo check_getdns_transport.lo -DECOMPOSED_OBJS=getdns_context_set_listen_addresses.lo - ALL_OBJS=$(CHECK_OBJS) check_getdns_libevent.lo check_getdns_libev.lo \ check_getdns_selectloop.lo getdns_query.lo scratchpad.lo \ testmessages.lo tests_dict.lo tests_list.lo tests_namespaces.lo \ - tests_stub_async.lo tests_stub_sync.lo \ - $(DECOMPOSED_OBJS) + tests_stub_async.lo tests_stub_sync.lo NON_C99_OBJS=check_getdns_libuv.lo @@ -127,8 +124,8 @@ check_getdns_uv: check_getdns.lo check_getdns_common.lo check_getdns_context_set check_getdns_ev: check_getdns.lo check_getdns_common.lo check_getdns_context_set_timeout.lo check_getdns_transport.lo check_getdns_libev.lo ../libgetdns_ext_ev.la $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ check_getdns.lo check_getdns_common.lo check_getdns_context_set_timeout.lo check_getdns_transport.lo check_getdns_libev.lo $(LDFLAGS) $(LDLIBS) $(CHECK_CFLAGS) $(CHECK_LIBS) ../libgetdns_ext_ev.la $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -getdns_query: getdns_query.lo $(DECOMPOSED_OBJS) - $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ getdns_query.lo $(DECOMPOSED_OBJS) $(LDFLAGS) $(LDLIBS) +getdns_query: getdns_query.lo + $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ getdns_query.lo $(LDFLAGS) $(LDLIBS) scratchpad: scratchpad.lo $(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ scratchpad.lo $(LDFLAGS) $(LDLIBS) @@ -266,16 +263,8 @@ check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_sel check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \ $(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \ ../getdns/getdns_extra.h -getdns_context_config.lo getdns_context_config.o: $(srcdir)/getdns_context_config.c $(srcdir)/getdns_context_config.h \ - ../getdns/getdns.h ../getdns/getdns_extra.h -getdns_context_set_listen_addresses.lo getdns_context_set_listen_addresses.o: \ - $(srcdir)/getdns_context_set_listen_addresses.c ../config.h \ - $(srcdir)/getdns_context_set_listen_addresses.h ../getdns/getdns.h \ - ../getdns/getdns_extra.h $(srcdir)/../types-internal.h ../getdns/getdns.h \ - ../getdns/getdns_extra.h $(srcdir)/../util/rbtree.h $(srcdir)/../debug.h ../config.h getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \ - $(srcdir)/getdns_context_set_listen_addresses.h ../getdns/getdns.h \ - ../getdns/getdns_extra.h + ../getdns/getdns.h ../getdns/getdns_extra.h scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \ ../getdns/getdns_extra.h testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h diff --git a/src/test/getdns_query.c b/src/test/getdns_query.c index 6df3fdc9..2bc21332 100644 --- a/src/test/getdns_query.c +++ b/src/test/getdns_query.c @@ -27,7 +27,6 @@ #include "config.h" #include "debug.h" -#include "getdns_context_set_listen_addresses.h" #include #include #include @@ -1346,14 +1345,11 @@ static void request_cb( else if (n == 0) SERVFAIL("Recursion not available", 0, msg, &response); - if (!response) - /* No response, no reply */ - _getdns_cancel_reply(context, msg->request_id); - - else if ((r = getdns_reply(context, msg->request_id, response))) { + if ((r = getdns_reply(context, msg->request_id, response))) { fprintf(stderr, "Could not reply: %s\n", getdns_get_errorstr_by_id(r)); - _getdns_cancel_reply(context, msg->request_id); + /* Cancel reply */ + (void) getdns_reply(context, msg->request_id, NULL); } if (msg) { getdns_dict_destroy(msg->request); @@ -1510,14 +1506,11 @@ error: free(request_str); } while(0); #endif - if (!response) - /* No response, no reply */ - _getdns_cancel_reply(context, request_id); - - else if ((r = getdns_reply(context, request_id, response))) { + if ((r = getdns_reply(context, request_id, response))) { fprintf(stderr, "Could not reply: %s\n", getdns_get_errorstr_by_id(r)); - _getdns_cancel_reply(context, request_id); + /* Cancel reply */ + getdns_reply(context, request_id, NULL); } if (msg) { if (msg->request)