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
This commit is contained in:
Willem Toorop 2016-07-13 14:50:44 +02:00
parent 69b607176c
commit be97bd1d71
9 changed files with 176 additions and 142 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -26,11 +26,13 @@
*/
#include "config.h"
#include "getdns_context_set_listen_addresses.h"
#include <netdb.h>
#include "getdns/getdns_extra.h"
#include "context.h"
#include "types-internal.h"
#include "debug.h"
#include <netdb.h>
#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;
}

View File

@ -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_ */

View File

@ -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

View File

@ -27,7 +27,6 @@
#include "config.h"
#include "debug.h"
#include "getdns_context_set_listen_addresses.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -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)