aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/util/netevent.c
diff options
context:
space:
mode:
Diffstat (limited to 'external/unbound/util/netevent.c')
-rw-r--r--external/unbound/util/netevent.c685
1 files changed, 431 insertions, 254 deletions
diff --git a/external/unbound/util/netevent.c b/external/unbound/util/netevent.c
index 3bb894888..2084cea3e 100644
--- a/external/unbound/util/netevent.c
+++ b/external/unbound/util/netevent.c
@@ -40,12 +40,14 @@
*/
#include "config.h"
#include "util/netevent.h"
+#include "util/ub_event.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/fptr_wlist.h"
#include "sldns/pkthdr.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
+#include "dnscrypt/dnscrypt.h"
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
@@ -56,7 +58,9 @@
/* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */
#ifndef CMSG_ALIGN
-# ifdef _CMSG_DATA_ALIGN
+# ifdef __CMSG_ALIGN
+# define CMSG_ALIGN(n) __CMSG_ALIGN(n)
+# elif defined(CMSG_DATA_ALIGN)
# define CMSG_ALIGN _CMSG_DATA_ALIGN
# else
# define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
@@ -77,8 +81,10 @@
# endif
#endif
-/** The TCP reading or writing query timeout in seconds */
-#define TCP_QUERY_TIMEOUT 120
+/** The TCP reading or writing query timeout in milliseconds */
+#define TCP_QUERY_TIMEOUT 120000
+/** The TCP timeout in msec for fast queries, above half are used */
+#define TCP_QUERY_TIMEOUT_FAST 200
#ifndef NONBLOCKING_IS_BROKEN
/** number of UDP reads to perform per read indication from select */
@@ -87,48 +93,29 @@
#define NUM_UDP_PER_SELECT 1
#endif
-/* We define libevent structures here to hide the libevent stuff. */
-
-#ifdef USE_MINI_EVENT
-# ifdef USE_WINSOCK
-# include "util/winsock_event.h"
-# else
-# include "util/mini_event.h"
-# endif /* USE_WINSOCK */
-#else /* USE_MINI_EVENT */
- /* we use libevent */
-# ifdef HAVE_EVENT_H
-# include <event.h>
-# else
-# include "event2/event.h"
-# include "event2/event_struct.h"
-# include "event2/event_compat.h"
-# endif
-#endif /* USE_MINI_EVENT */
-
/**
- * The internal event structure for keeping libevent info for the event.
+ * The internal event structure for keeping ub_event info for the event.
* Possibly other structures (list, tree) this is part of.
*/
struct internal_event {
/** the comm base */
struct comm_base* base;
- /** libevent event type, alloced here */
- struct event ev;
+ /** ub_event event type */
+ struct ub_event* ev;
};
/**
* Internal base structure, so that every thread has its own events.
*/
struct internal_base {
- /** libevent event_base type. */
- struct event_base* base;
+ /** ub_event event_base type. */
+ struct ub_event_base* base;
/** seconds time pointer points here */
time_t secs;
/** timeval with current time */
struct timeval now;
/** the event used for slow_accept timeouts */
- struct event slow_accept;
+ struct ub_event* slow_accept;
/** true if slow_accept is enabled */
int slow_accept_enabled;
};
@@ -137,10 +124,12 @@ struct internal_base {
* Internal timer structure, to store timer event in.
*/
struct internal_timer {
+ /** the super struct from which derived */
+ struct comm_timer super;
/** the comm base */
struct comm_base* base;
- /** libevent event type, alloced here */
- struct event ev;
+ /** ub_event event type */
+ struct ub_event* ev;
/** is timer enabled */
uint8_t enabled;
};
@@ -149,8 +138,8 @@ struct internal_timer {
* Internal signal structure, to store signal event in.
*/
struct internal_signal {
- /** libevent event type, alloced here */
- struct event ev;
+ /** ub_event event type */
+ struct ub_event* ev;
/** next in signal list */
struct internal_signal* next;
};
@@ -158,30 +147,17 @@ struct internal_signal {
/** create a tcp handler with a parent */
static struct comm_point* comm_point_create_tcp_handler(
struct comm_base *base, struct comm_point* parent, size_t bufsize,
- comm_point_callback_t* callback, void* callback_arg);
+ comm_point_callback_type* callback, void* callback_arg);
/* -------- End of local definitions -------- */
-#ifdef USE_MINI_EVENT
-/** minievent updates the time when it blocks. */
-#define comm_base_now(x) /* nothing to do */
-#else /* !USE_MINI_EVENT */
-/** fillup the time values in the event base */
-static void
-comm_base_now(struct comm_base* b)
-{
- if(gettimeofday(&b->eb->now, NULL) < 0) {
- log_err("gettimeofday: %s", strerror(errno));
- }
- b->eb->secs = (time_t)b->eb->now.tv_sec;
-}
-#endif /* USE_MINI_EVENT */
-
struct comm_base*
comm_base_create(int sigs)
{
struct comm_base* b = (struct comm_base*)calloc(1,
sizeof(struct comm_base));
+ const char *evnm="event", *evsys="", *evmethod="";
+
if(!b)
return NULL;
b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base));
@@ -189,55 +165,20 @@ comm_base_create(int sigs)
free(b);
return NULL;
}
-#ifdef USE_MINI_EVENT
- (void)sigs;
- /* use mini event time-sharing feature */
- b->eb->base = event_init(&b->eb->secs, &b->eb->now);
-#else
-# if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
- /* libev */
- if(sigs)
- b->eb->base=(struct event_base *)ev_default_loop(EVFLAG_AUTO);
- else
- b->eb->base=(struct event_base *)ev_loop_new(EVFLAG_AUTO);
-# else
- (void)sigs;
-# ifdef HAVE_EVENT_BASE_NEW
- b->eb->base = event_base_new();
-# else
- b->eb->base = event_init();
-# endif
-# endif
-#endif
+ b->eb->base = ub_default_event_base(sigs, &b->eb->secs, &b->eb->now);
if(!b->eb->base) {
free(b->eb);
free(b);
return NULL;
}
- comm_base_now(b);
- /* avoid event_get_method call which causes crashes even when
- * not printing, because its result is passed */
- verbose(VERB_ALGO,
-#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
- "libev"
-#elif defined(USE_MINI_EVENT)
- "event "
-#else
- "libevent "
-#endif
- "%s uses %s method.",
- event_get_version(),
-#ifdef HAVE_EVENT_BASE_GET_METHOD
- event_base_get_method(b->eb->base)
-#else
- "not_obtainable"
-#endif
- );
+ ub_comm_base_now(b);
+ ub_get_event_sys(b->eb->base, &evnm, &evsys, &evmethod);
+ verbose(VERB_ALGO, "%s %s user %s method.", evnm, evsys, evmethod);
return b;
}
struct comm_base*
-comm_base_create_event(struct event_base* base)
+comm_base_create_event(struct ub_event_base* base)
{
struct comm_base* b = (struct comm_base*)calloc(1,
sizeof(struct comm_base));
@@ -249,7 +190,7 @@ comm_base_create_event(struct event_base* base)
return NULL;
}
b->eb->base = base;
- comm_base_now(b);
+ ub_comm_base_now(b);
return b;
}
@@ -259,18 +200,12 @@ comm_base_delete(struct comm_base* b)
if(!b)
return;
if(b->eb->slow_accept_enabled) {
- if(event_del(&b->eb->slow_accept) != 0) {
+ if(ub_event_del(b->eb->slow_accept) != 0) {
log_err("could not event_del slow_accept");
}
+ ub_event_free(b->eb->slow_accept);
}
-#ifdef USE_MINI_EVENT
- event_base_free(b->eb->base);
-#elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE)
- /* only libevent 1.2+ has it, but in 1.2 it is broken -
- assertion fails on signal handling ev that is not deleted
- in libevent 1.3c (event_base_once appears) this is fixed. */
- event_base_free(b->eb->base);
-#endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */
+ ub_event_base_free(b->eb->base);
b->eb->base = NULL;
free(b->eb);
free(b);
@@ -282,9 +217,10 @@ comm_base_delete_no_base(struct comm_base* b)
if(!b)
return;
if(b->eb->slow_accept_enabled) {
- if(event_del(&b->eb->slow_accept) != 0) {
+ if(ub_event_del(b->eb->slow_accept) != 0) {
log_err("could not event_del slow_accept");
}
+ ub_event_free(b->eb->slow_accept);
}
b->eb->base = NULL;
free(b->eb);
@@ -302,8 +238,8 @@ void
comm_base_dispatch(struct comm_base* b)
{
int retval;
- retval = event_base_dispatch(b->eb->base);
- if(retval != 0) {
+ retval = ub_event_base_dispatch(b->eb->base);
+ if(retval < 0) {
fatal_exit("event_dispatch returned error %d, "
"errno is %s", retval, strerror(errno));
}
@@ -311,7 +247,7 @@ comm_base_dispatch(struct comm_base* b)
void comm_base_exit(struct comm_base* b)
{
- if(event_base_loopexit(b->eb->base, NULL) != 0) {
+ if(ub_event_base_loopexit(b->eb->base) != 0) {
log_err("Could not loopexit");
}
}
@@ -324,7 +260,7 @@ void comm_base_set_slow_accept_handlers(struct comm_base* b,
b->cb_arg = arg;
}
-struct event_base* comm_base_internal(struct comm_base* b)
+struct ub_event_base* comm_base_internal(struct comm_base* b)
{
return b->eb->base;
}
@@ -356,7 +292,12 @@ udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
#endif
/* permission denied is gotten for every send if the
* network is disconnected (on some OS), squelch it */
- if(errno == EPERM && verbosity < VERB_DETAIL)
+ if( ((errno == EPERM)
+# ifdef EADDRNOTAVAIL
+ /* 'Cannot assign requested address' also when disconnected */
+ || (errno == EADDRNOTAVAIL)
+# endif
+ ) && verbosity < VERB_DETAIL)
return 0;
/* squelch errors where people deploy AAAA ::ffff:bla for
* authority servers, which we try for intranets. */
@@ -394,6 +335,31 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
sldns_buffer_remaining(packet), 0,
addr, addrlen);
if(sent == -1) {
+ /* try again and block, waiting for IO to complete,
+ * we want to send the answer, and we will wait for
+ * the ethernet interface buffer to have space. */
+#ifndef USE_WINSOCK
+ if(errno == EAGAIN ||
+# ifdef EWOULDBLOCK
+ errno == EWOULDBLOCK ||
+# endif
+ errno == ENOBUFS) {
+#else
+ if(WSAGetLastError() == WSAEINPROGRESS ||
+ WSAGetLastError() == WSAENOBUFS ||
+ WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+ int e;
+ fd_set_block(c->fd);
+ sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
+ sldns_buffer_remaining(packet), 0,
+ addr, addrlen);
+ e = errno;
+ fd_set_nonblock(c->fd);
+ errno = e;
+ }
+ }
+ if(sent == -1) {
if(!udp_send_errno_needs_log(addr, addrlen))
return 0;
#ifndef USE_WINSOCK
@@ -547,11 +513,40 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
p_ancil("send_udp over interface", r);
sent = sendmsg(c->fd, &msg, 0);
if(sent == -1) {
+ /* try again and block, waiting for IO to complete,
+ * we want to send the answer, and we will wait for
+ * the ethernet interface buffer to have space. */
+#ifndef USE_WINSOCK
+ if(errno == EAGAIN ||
+# ifdef EWOULDBLOCK
+ errno == EWOULDBLOCK ||
+# endif
+ errno == ENOBUFS) {
+#else
+ if(WSAGetLastError() == WSAEINPROGRESS ||
+ WSAGetLastError() == WSAENOBUFS ||
+ WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+ int e;
+ fd_set_block(c->fd);
+ sent = sendmsg(c->fd, &msg, 0);
+ e = errno;
+ fd_set_nonblock(c->fd);
+ errno = e;
+ }
+ }
+ if(sent == -1) {
if(!udp_send_errno_needs_log(addr, addrlen))
return 0;
verbose(VERB_OPS, "sendmsg failed: %s", strerror(errno));
log_addr(VERB_OPS, "remote address is",
(struct sockaddr_storage*)addr, addrlen);
+#ifdef __NetBSD__
+ /* netbsd 7 has IP_PKTINFO for recv but not send */
+ if(errno == EINVAL && r->srctype == 4)
+ log_err("sendmsg: No support for sendmsg(IP_PKTINFO). "
+ "Please disable interface-automatic");
+#endif
return 0;
} else if((size_t)sent != sldns_buffer_remaining(packet)) {
log_err("sent %d in place of %d bytes",
@@ -587,10 +582,10 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
- if(!(event&EV_READ))
+ if(!(event&UB_EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
- comm_base_now(rep.c->ev->base);
+ ub_comm_base_now(rep.c->ev->base);
for(i=0; i<NUM_UDP_PER_SELECT; i++) {
sldns_buffer_clear(rep.c->buffer);
rep.addrlen = (socklen_t)sizeof(rep.addr);
@@ -660,7 +655,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
(void)fd;
(void)event;
(void)arg;
- fatal_exit("recvmsg: No support for IPV6_PKTINFO. "
+ fatal_exit("recvmsg: No support for IPV6_PKTINFO; IP_PKTINFO or IP_RECVDSTADDR. "
"Please disable interface-automatic");
#endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG */
}
@@ -671,14 +666,15 @@ comm_point_udp_callback(int fd, short event, void* arg)
struct comm_reply rep;
ssize_t rcv;
int i;
+ struct sldns_buffer *buffer;
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
- if(!(event&EV_READ))
+ if(!(event&UB_EV_READ))
return;
log_assert(rep.c && rep.c->buffer && rep.c->fd == fd);
- comm_base_now(rep.c->ev->base);
+ ub_comm_base_now(rep.c->ev->base);
for(i=0; i<NUM_UDP_PER_SELECT; i++) {
sldns_buffer_clear(rep.c->buffer);
rep.addrlen = (socklen_t)sizeof(rep.addr);
@@ -707,7 +703,12 @@ comm_point_udp_callback(int fd, short event, void* arg)
fptr_ok(fptr_whitelist_comm_point(rep.c->callback));
if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) {
/* send back immediate reply */
- (void)comm_point_send_udp_msg(rep.c, rep.c->buffer,
+#ifdef USE_DNSCRYPT
+ buffer = rep.c->dnscrypt_buffer;
+#else
+ buffer = rep.c->buffer;
+#endif
+ (void)comm_point_send_udp_msg(rep.c, buffer,
(struct sockaddr*)&rep.addr, rep.addrlen);
}
if(rep.c->fd != fd) /* commpoint closed to -1 or reused for
@@ -718,14 +719,24 @@ comm_point_udp_callback(int fd, short event, void* arg)
/** Use a new tcp handler for new query fd, set to read query */
static void
-setup_tcp_handler(struct comm_point* c, int fd)
+setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
{
log_assert(c->type == comm_tcp);
log_assert(c->fd == -1);
sldns_buffer_clear(c->buffer);
+#ifdef USE_DNSCRYPT
+ if (c->dnscrypt)
+ sldns_buffer_clear(c->dnscrypt_buffer);
+#endif
c->tcp_is_reading = 1;
c->tcp_byte_count = 0;
- comm_point_start_listening(c, fd, TCP_QUERY_TIMEOUT);
+ c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
+ /* if more than half the tcp handlers are in use, use a shorter
+ * timeout for this TCP connection, we need to make space for
+ * other connections to be able to get attention */
+ if(cur > max/2)
+ c->tcp_timeout_msec = TCP_QUERY_TIMEOUT_FAST;
+ comm_point_start_listening(c, fd, c->tcp_timeout_msec);
}
void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
@@ -777,16 +788,17 @@ int comm_point_perform_accept(struct comm_point* c,
(*b->stop_accept)(b->cb_arg);
/* set timeout, no mallocs */
tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000;
- tv.tv_usec = NETEVENT_SLOW_ACCEPT_TIME%1000;
- event_set(&b->eb->slow_accept, -1, EV_TIMEOUT,
+ tv.tv_usec = (NETEVENT_SLOW_ACCEPT_TIME%1000)*1000;
+ b->eb->slow_accept = ub_event_new(b->eb->base,
+ -1, UB_EV_TIMEOUT,
comm_base_handle_slow_accept, b);
- if(event_base_set(b->eb->base,
- &b->eb->slow_accept) != 0) {
+ if(b->eb->slow_accept == NULL) {
/* we do not want to log here, because
* that would spam the logfiles.
* error: "event_base_set failed." */
}
- if(event_add(&b->eb->slow_accept, &tv) != 0) {
+ else if(ub_event_add(b->eb->slow_accept, &tv)
+ != 0) {
/* we do not want to log here,
* error: "event_add failed." */
}
@@ -800,7 +812,7 @@ int comm_point_perform_accept(struct comm_point* c,
WSAGetLastError() == WSAECONNRESET)
return -1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return -1;
}
log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
@@ -824,14 +836,14 @@ static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp),
if( (oper == (BIO_CB_READ|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_GETS|BIO_CB_RETURN) && argl == 0)) {
if(WSAGetLastError() == WSAEWOULDBLOCK)
- winsock_tcp_wouldblock((struct event*)
- BIO_get_callback_arg(b), EV_READ);
+ ub_winsock_tcp_wouldblock((struct ub_event*)
+ BIO_get_callback_arg(b), UB_EV_READ);
}
if( (oper == (BIO_CB_WRITE|BIO_CB_RETURN) && argl == 0) ||
(oper == (BIO_CB_PUTS|BIO_CB_RETURN) && argl == 0)) {
if(WSAGetLastError() == WSAEWOULDBLOCK)
- winsock_tcp_wouldblock((struct event*)
- BIO_get_callback_arg(b), EV_WRITE);
+ ub_winsock_tcp_wouldblock((struct ub_event*)
+ BIO_get_callback_arg(b), UB_EV_WRITE);
}
/* return original return value */
return retvalue;
@@ -844,9 +856,9 @@ comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
SSL* ssl = (SSL*)thessl;
/* set them both just in case, but usually they are the same BIO */
BIO_set_callback(SSL_get_rbio(ssl), &win_bio_cb);
- BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)&c->ev->ev);
+ BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)c->ev->ev);
BIO_set_callback(SSL_get_wbio(ssl), &win_bio_cb);
- BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)&c->ev->ev);
+ BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)c->ev->ev);
}
#endif
@@ -856,11 +868,11 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
struct comm_point* c = (struct comm_point*)arg, *c_hdl;
int new_fd;
log_assert(c->type == comm_tcp_accept);
- if(!(event & EV_READ)) {
+ if(!(event & UB_EV_READ)) {
log_info("ignoring tcp accept event %d", (int)event);
return;
}
- comm_base_now(c->ev->base);
+ ub_comm_base_now(c->ev->base);
/* find free tcp handler. */
if(!c->tcp_free) {
log_warn("accepted too many tcp, connections full");
@@ -869,6 +881,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* accept incoming connection. */
c_hdl = c->tcp_free;
log_assert(fd != -1);
+ (void)fd;
new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr,
&c_hdl->repinfo.addrlen);
if(new_fd == -1)
@@ -893,7 +906,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* stop accepting incoming queries for now. */
comm_point_stop_listening(c);
}
- setup_tcp_handler(c_hdl, new_fd);
+ setup_tcp_handler(c_hdl, new_fd, c->cur_tcp_count, c->max_tcp_count);
}
/** Make tcp handler free for next assignment */
@@ -947,7 +960,7 @@ tcp_callback_reader(struct comm_point* c)
comm_point_stop_listening(c);
fptr_ok(fptr_whitelist_comm_point(c->callback));
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
- comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT);
+ comm_point_start_listening(c, -1, c->tcp_timeout_msec);
}
}
@@ -1236,7 +1249,8 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
+ ub_winsock_tcp_wouldblock(c->ev->ev,
+ UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp s)",
@@ -1281,7 +1295,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_READ);
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp r)",
@@ -1307,7 +1321,13 @@ static int
comm_point_tcp_handle_write(int fd, struct comm_point* c)
{
ssize_t r;
+ struct sldns_buffer *buffer;
log_assert(c->type == comm_tcp);
+#ifdef USE_DNSCRYPT
+ buffer = c->dnscrypt_buffer;
+#else
+ buffer = c->buffer;
+#endif
if(c->tcp_is_reading && !c->ssl)
return 0;
log_assert(fd != -1);
@@ -1340,7 +1360,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(error == WSAEINPROGRESS)
return 1;
else if(error == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
} else if(error != 0 && verbosity < 2)
return 0;
@@ -1354,14 +1374,67 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(c->ssl)
return ssl_handle_it(c);
+#ifdef USE_MSG_FASTOPEN
+ /* Only try this on first use of a connection that uses tfo,
+ otherwise fall through to normal write */
+ /* Also, TFO support on WINDOWS not implemented at the moment */
+ if(c->tcp_do_fastopen == 1) {
+ /* this form of sendmsg() does both a connect() and send() so need to
+ look for various flavours of error*/
+ uint16_t len = htons(sldns_buffer_limit(buffer));
+ struct msghdr msg;
+ struct iovec iov[2];
+ c->tcp_do_fastopen = 0;
+ memset(&msg, 0, sizeof(msg));
+ iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
+ iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
+ iov[1].iov_base = sldns_buffer_begin(buffer);
+ iov[1].iov_len = sldns_buffer_limit(buffer);
+ log_assert(iov[0].iov_len > 0);
+ log_assert(iov[1].iov_len > 0);
+ msg.msg_name = &c->repinfo.addr;
+ msg.msg_namelen = c->repinfo.addrlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+ r = sendmsg(fd, &msg, MSG_FASTOPEN);
+ if (r == -1) {
+#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
+ /* Handshake is underway, maybe because no TFO cookie available.
+ Come back to write the messsage*/
+ if(errno == EINPROGRESS || errno == EWOULDBLOCK)
+ return 1;
+#endif
+ if(errno == EINTR || errno == EAGAIN)
+ return 1;
+ /* Not handling EISCONN here as shouldn't ever hit that case.*/
+ if(errno != 0 && verbosity < 2)
+ return 0; /* silence lots of chatter in the logs */
+ else if(errno != 0)
+ log_err_addr("tcp sendmsg", strerror(errno),
+ &c->repinfo.addr, c->repinfo.addrlen);
+ return 0;
+ } else {
+ c->tcp_byte_count += r;
+ if(c->tcp_byte_count < sizeof(uint16_t))
+ return 1;
+ sldns_buffer_set_position(buffer, c->tcp_byte_count -
+ sizeof(uint16_t));
+ if(sldns_buffer_remaining(buffer) == 0) {
+ tcp_callback_writer(c);
+ return 1;
+ }
+ }
+ }
+#endif /* USE_MSG_FASTOPEN */
+
if(c->tcp_byte_count < sizeof(uint16_t)) {
- uint16_t len = htons(sldns_buffer_limit(c->buffer));
+ uint16_t len = htons(sldns_buffer_limit(buffer));
#ifdef HAVE_WRITEV
struct iovec iov[2];
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
- iov[1].iov_base = sldns_buffer_begin(c->buffer);
- iov[1].iov_len = sldns_buffer_limit(c->buffer);
+ iov[1].iov_base = sldns_buffer_begin(buffer);
+ iov[1].iov_len = sldns_buffer_limit(buffer);
log_assert(iov[0].iov_len > 0);
log_assert(iov[1].iov_len > 0);
r = writev(fd, iov, 2);
@@ -1390,7 +1463,8 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
+ ub_winsock_tcp_wouldblock(c->ev->ev,
+ UB_EV_WRITE);
return 1;
}
log_err_addr("tcp send s",
@@ -1402,16 +1476,16 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
c->tcp_byte_count += r;
if(c->tcp_byte_count < sizeof(uint16_t))
return 1;
- sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
+ sldns_buffer_set_position(buffer, c->tcp_byte_count -
sizeof(uint16_t));
- if(sldns_buffer_remaining(c->buffer) == 0) {
+ if(sldns_buffer_remaining(buffer) == 0) {
tcp_callback_writer(c);
return 1;
}
}
- log_assert(sldns_buffer_remaining(c->buffer) > 0);
- r = send(fd, (void*)sldns_buffer_current(c->buffer),
- sldns_buffer_remaining(c->buffer), 0);
+ log_assert(sldns_buffer_remaining(buffer) > 0);
+ r = send(fd, (void*)sldns_buffer_current(buffer),
+ sldns_buffer_remaining(buffer), 0);
if(r == -1) {
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
@@ -1422,7 +1496,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
- winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
+ ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
}
log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
@@ -1430,9 +1504,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#endif
return 0;
}
- sldns_buffer_skip(c->buffer, r);
+ sldns_buffer_skip(buffer, r);
- if(sldns_buffer_remaining(c->buffer) == 0) {
+ if(sldns_buffer_remaining(buffer) == 0) {
tcp_callback_writer(c);
}
@@ -1444,9 +1518,23 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg;
log_assert(c->type == comm_tcp);
- comm_base_now(c->ev->base);
+ ub_comm_base_now(c->ev->base);
- if(event&EV_READ) {
+#ifdef USE_DNSCRYPT
+ /* Initialize if this is a dnscrypt socket */
+ if(c->tcp_parent) {
+ c->dnscrypt = c->tcp_parent->dnscrypt;
+ }
+ if(c->dnscrypt && c->dnscrypt_buffer == c->buffer) {
+ c->dnscrypt_buffer = sldns_buffer_new(sldns_buffer_capacity(c->buffer));
+ if(!c->dnscrypt_buffer) {
+ log_err("Could not allocate dnscrypt buffer");
+ return;
+ }
+ }
+#endif
+
+ if(event&UB_EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 0)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -1458,7 +1546,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&EV_WRITE) {
+ if(event&UB_EV_WRITE) {
if(!comm_point_tcp_handle_write(fd, c)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -1470,7 +1558,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&EV_TIMEOUT) {
+ if(event&UB_EV_TIMEOUT) {
verbose(VERB_QUERY, "tcp took too long, dropped");
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -1487,9 +1575,9 @@ void comm_point_local_handle_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg;
log_assert(c->type == comm_local);
- comm_base_now(c->ev->base);
+ ub_comm_base_now(c->ev->base);
- if(event&EV_READ) {
+ if(event&UB_EV_READ) {
if(!comm_point_tcp_handle_read(fd, c, 1)) {
fptr_ok(fptr_whitelist_comm_point(c->callback));
(void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED,
@@ -1506,9 +1594,9 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
struct comm_point* c = (struct comm_point*)arg;
int err = NETEVENT_NOERROR;
log_assert(c->type == comm_raw);
- comm_base_now(c->ev->base);
+ ub_comm_base_now(c->ev->base);
- if(event&EV_TIMEOUT)
+ if(event&UB_EV_TIMEOUT)
err = NETEVENT_TIMEOUT;
fptr_ok(fptr_whitelist_comm_point_raw(c->callback));
(void)(*c->callback)(c, c->cb_arg, err, NULL);
@@ -1516,7 +1604,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
struct comm_point*
comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1545,18 +1633,26 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = buffer;
+#endif
c->inuse = 0;
c->callback = callback;
c->cb_arg = callback_arg;
- evbits = EV_READ | EV_PERSIST;
- /* libevent stuff */
- event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_callback, c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0) {
+ evbits = UB_EV_READ | UB_EV_PERSIST;
+ /* ub_event stuff */
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_udp_callback, c);
+ if(c->ev->ev == NULL) {
log_err("could not baseset udp event");
comm_point_delete(c);
return NULL;
}
- if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) {
+ if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
log_err("could not add udp event");
comm_point_delete(c);
return NULL;
@@ -1567,7 +1663,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
struct comm_point*
comm_point_create_udp_ancil(struct comm_base *base, int fd,
sldns_buffer* buffer,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1594,20 +1690,28 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
c->type = comm_udp;
c->tcp_do_close = 0;
c->do_not_close = 0;
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = buffer;
+#endif
c->inuse = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
- evbits = EV_READ | EV_PERSIST;
- /* libevent stuff */
- event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_ancil_callback, c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0) {
+ evbits = UB_EV_READ | UB_EV_PERSIST;
+ /* ub_event stuff */
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_udp_ancil_callback, c);
+ if(c->ev->ev == NULL) {
log_err("could not baseset udp event");
comm_point_delete(c);
return NULL;
}
- if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) {
+ if(fd!=-1 && ub_event_add(c->ev->ev, c->timeout) != 0 ) {
log_err("could not add udp event");
comm_point_delete(c);
return NULL;
@@ -1618,7 +1722,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
static struct comm_point*
comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1658,16 +1762,26 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ // We don't know just yet if this is a dnscrypt channel. Allocation
+ // will be done when handling the callback.
+ c->dnscrypt_buffer = c->buffer;
+#endif
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
- /* libevent stuff */
- evbits = EV_PERSIST | EV_READ | EV_TIMEOUT;
- event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0)
+ /* ub_event stuff */
+ evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_tcp_handle_callback, c);
+ if(c->ev->ev == NULL)
{
log_err("could not basetset tcphdl event");
parent->tcp_free = c->tcp_free;
@@ -1680,7 +1794,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
struct comm_point*
comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1717,19 +1831,29 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = NULL;
+#endif
c->callback = NULL;
c->cb_arg = NULL;
- evbits = EV_READ | EV_PERSIST;
- /* libevent stuff */
- event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_accept_callback, c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
- event_add(&c->ev->ev, c->timeout) != 0 )
- {
+ evbits = UB_EV_READ | UB_EV_PERSIST;
+ /* ub_event stuff */
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_tcp_accept_callback, c);
+ if(c->ev->ev == NULL) {
+ log_err("could not baseset tcpacc event");
+ comm_point_delete(c);
+ return NULL;
+ }
+ if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add tcpacc event");
comm_point_delete(c);
return NULL;
}
-
/* now prealloc the tcp handlers */
for(i=0; i<num; i++) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
@@ -1745,7 +1869,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
struct comm_point*
comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1779,14 +1903,22 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 1;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 1;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = c->buffer;
+#endif
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
- evbits = EV_PERSIST | EV_WRITE;
- event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0)
+ evbits = UB_EV_PERSIST | UB_EV_WRITE;
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_tcp_handle_callback, c);
+ if(c->ev->ev == NULL)
{
- log_err("could not basetset tcpout event");
+ log_err("could not baseset tcpout event");
sldns_buffer_free(c->buffer);
free(c->ev);
free(c);
@@ -1798,7 +1930,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
struct comm_point*
comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1832,16 +1964,28 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
c->do_not_close = 1;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = c->buffer;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
- /* libevent stuff */
- evbits = EV_PERSIST | EV_READ;
- event_set(&c->ev->ev, c->fd, evbits, comm_point_local_handle_callback,
- c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
- event_add(&c->ev->ev, c->timeout) != 0 )
- {
+ /* ub_event stuff */
+ evbits = UB_EV_PERSIST | UB_EV_READ;
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_local_handle_callback, c);
+ if(c->ev->ev == NULL) {
+ log_err("could not baseset localhdl event");
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+ if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add localhdl event");
+ ub_event_free(c->ev->ev);
free(c->ev);
free(c);
return NULL;
@@ -1851,7 +1995,7 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
struct comm_point*
comm_point_create_raw(struct comm_base* base, int fd, int writing,
- comm_point_callback_t* callback, void* callback_arg)
+ comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@@ -1880,18 +2024,30 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
c->do_not_close = 1;
c->tcp_do_toggle_rw = 0;
c->tcp_check_nb_connect = 0;
+#ifdef USE_MSG_FASTOPEN
+ c->tcp_do_fastopen = 0;
+#endif
+#ifdef USE_DNSCRYPT
+ c->dnscrypt = 0;
+ c->dnscrypt_buffer = c->buffer;
+#endif
c->callback = callback;
c->cb_arg = callback_arg;
- /* libevent stuff */
+ /* ub_event stuff */
if(writing)
- evbits = EV_PERSIST | EV_WRITE;
- else evbits = EV_PERSIST | EV_READ;
- event_set(&c->ev->ev, c->fd, evbits, comm_point_raw_handle_callback,
- c);
- if(event_base_set(base->eb->base, &c->ev->ev) != 0 ||
- event_add(&c->ev->ev, c->timeout) != 0 )
- {
+ evbits = UB_EV_PERSIST | UB_EV_WRITE;
+ else evbits = UB_EV_PERSIST | UB_EV_READ;
+ c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
+ comm_point_raw_handle_callback, c);
+ if(c->ev->ev == NULL) {
+ log_err("could not baseset rawhdl event");
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+ if (ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("could not add rawhdl event");
+ ub_event_free(c->ev->ev);
free(c->ev);
free(c);
return NULL;
@@ -1905,7 +2061,7 @@ comm_point_close(struct comm_point* c)
if(!c)
return;
if(c->fd != -1)
- if(event_del(&c->ev->ev) != 0) {
+ if(ub_event_del(c->ev->ev) != 0) {
log_err("could not event_del on close");
}
/* close fd after removing from event lists, or epoll.. is messed up */
@@ -1939,8 +2095,15 @@ comm_point_delete(struct comm_point* c)
free(c->tcp_handlers);
}
free(c->timeout);
- if(c->type == comm_tcp || c->type == comm_local)
+ if(c->type == comm_tcp || c->type == comm_local) {
sldns_buffer_free(c->buffer);
+#ifdef USE_DNSCRYPT
+ if(c->dnscrypt && c->dnscrypt_buffer != c->buffer) {
+ sldns_buffer_free(c->dnscrypt_buffer);
+ }
+#endif
+ }
+ ub_event_free(c->ev->ev);
free(c->ev);
free(c);
}
@@ -1948,14 +2111,23 @@ comm_point_delete(struct comm_point* c)
void
comm_point_send_reply(struct comm_reply *repinfo)
{
+ struct sldns_buffer* buffer;
log_assert(repinfo && repinfo->c);
+#ifdef USE_DNSCRYPT
+ buffer = repinfo->c->dnscrypt_buffer;
+ if(!dnsc_handle_uncurved_request(repinfo)) {
+ return;
+ }
+#else
+ buffer = repinfo->c->buffer;
+#endif
if(repinfo->c->type == comm_udp) {
if(repinfo->srctype)
comm_point_send_udp_msg_if(repinfo->c,
- repinfo->c->buffer, (struct sockaddr*)&repinfo->addr,
+ buffer, (struct sockaddr*)&repinfo->addr,
repinfo->addrlen, repinfo);
else
- comm_point_send_udp_msg(repinfo->c, repinfo->c->buffer,
+ comm_point_send_udp_msg(repinfo->c, buffer,
(struct sockaddr*)&repinfo->addr, repinfo->addrlen);
#ifdef USE_DNSTAP
if(repinfo->c->dtenv != NULL &&
@@ -1970,7 +2142,8 @@ comm_point_send_reply(struct comm_reply *repinfo)
dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
&repinfo->addr, repinfo->c->type, repinfo->c->buffer);
#endif
- comm_point_start_listening(repinfo->c, -1, TCP_QUERY_TIMEOUT);
+ comm_point_start_listening(repinfo->c, -1,
+ repinfo->c->tcp_timeout_msec);
}
}
@@ -1990,13 +2163,13 @@ void
comm_point_stop_listening(struct comm_point* c)
{
verbose(VERB_ALGO, "comm point stop listening %d", c->fd);
- if(event_del(&c->ev->ev) != 0) {
+ if(ub_event_del(c->ev->ev) != 0) {
log_err("event_del error to stoplisten");
}
}
void
-comm_point_start_listening(struct comm_point* c, int newfd, int sec)
+comm_point_start_listening(struct comm_point* c, int newfd, int msec)
{
verbose(VERB_ALGO, "comm point start listening %d",
c->fd==-1?newfd:c->fd);
@@ -2004,7 +2177,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
/* no use to start listening no free slots. */
return;
}
- if(sec != -1 && sec != 0) {
+ if(msec != -1 && msec != 0) {
if(!c->timeout) {
c->timeout = (struct timeval*)malloc(sizeof(
struct timeval));
@@ -2013,17 +2186,17 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
return;
}
}
- c->ev->ev.ev_events |= EV_TIMEOUT;
+ ub_event_add_bits(c->ev->ev, UB_EV_TIMEOUT);
#ifndef S_SPLINT_S /* splint fails on struct timeval. */
- c->timeout->tv_sec = sec;
- c->timeout->tv_usec = 0;
+ c->timeout->tv_sec = msec/1000;
+ c->timeout->tv_usec = (msec%1000)*1000;
#endif /* S_SPLINT_S */
}
if(c->type == comm_tcp) {
- c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE);
+ ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
if(c->tcp_is_reading)
- c->ev->ev.ev_events |= EV_READ;
- else c->ev->ev.ev_events |= EV_WRITE;
+ ub_event_add_bits(c->ev->ev, UB_EV_READ);
+ else ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
}
if(newfd != -1) {
if(c->fd != -1) {
@@ -2034,9 +2207,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
#endif
}
c->fd = newfd;
- c->ev->ev.ev_fd = c->fd;
+ ub_event_set_fd(c->ev->ev, c->fd);
}
- if(event_add(&c->ev->ev, sec==0?NULL:c->timeout) != 0) {
+ if(ub_event_add(c->ev->ev, msec==0?NULL:c->timeout) != 0) {
log_err("event_add failed. in cpsl.");
}
}
@@ -2044,13 +2217,13 @@ comm_point_start_listening(struct comm_point* c, int newfd, int sec)
void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr)
{
verbose(VERB_ALGO, "comm point listen_for_rw %d %d", c->fd, wr);
- if(event_del(&c->ev->ev) != 0) {
+ if(ub_event_del(c->ev->ev) != 0) {
log_err("event_del error to cplf");
}
- c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE);
- if(rd) c->ev->ev.ev_events |= EV_READ;
- if(wr) c->ev->ev.ev_events |= EV_WRITE;
- if(event_add(&c->ev->ev, c->timeout) != 0) {
+ ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
+ if(rd) ub_event_add_bits(c->ev->ev, UB_EV_READ);
+ if(wr) ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
+ if(ub_event_add(c->ev->ev, c->timeout) != 0) {
log_err("event_add failed. in cplf.");
}
}
@@ -2063,8 +2236,15 @@ size_t comm_point_get_mem(struct comm_point* c)
s = sizeof(*c) + sizeof(*c->ev);
if(c->timeout)
s += sizeof(*c->timeout);
- if(c->type == comm_tcp || c->type == comm_local)
+ if(c->type == comm_tcp || c->type == comm_local) {
s += sizeof(*c->buffer) + sldns_buffer_capacity(c->buffer);
+#ifdef USE_DNSCRYPT
+ s += sizeof(*c->dnscrypt_buffer);
+ if(c->buffer != c->dnscrypt_buffer) {
+ s += sldns_buffer_capacity(c->dnscrypt_buffer);
+ }
+#endif
+ }
if(c->type == comm_tcp_accept) {
int i;
for(i=0; i<c->max_tcp_count; i++)
@@ -2076,29 +2256,24 @@ size_t comm_point_get_mem(struct comm_point* c)
struct comm_timer*
comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg)
{
- struct comm_timer *tm = (struct comm_timer*)calloc(1,
- sizeof(struct comm_timer));
- if(!tm)
- return NULL;
- tm->ev_timer = (struct internal_timer*)calloc(1,
+ struct internal_timer *tm = (struct internal_timer*)calloc(1,
sizeof(struct internal_timer));
- if(!tm->ev_timer) {
+ if(!tm) {
log_err("malloc failed");
- free(tm);
return NULL;
}
- tm->ev_timer->base = base;
- tm->callback = cb;
- tm->cb_arg = cb_arg;
- event_set(&tm->ev_timer->ev, -1, EV_TIMEOUT,
- comm_timer_callback, tm);
- if(event_base_set(base->eb->base, &tm->ev_timer->ev) != 0) {
+ tm->super.ev_timer = tm;
+ tm->base = base;
+ tm->super.callback = cb;
+ tm->super.cb_arg = cb_arg;
+ tm->ev = ub_event_new(base->eb->base, -1, UB_EV_TIMEOUT,
+ comm_timer_callback, &tm->super);
+ if(tm->ev == NULL) {
log_err("timer_create: event_base_set failed.");
- free(tm->ev_timer);
free(tm);
return NULL;
}
- return tm;
+ return &tm->super;
}
void
@@ -2106,7 +2281,7 @@ comm_timer_disable(struct comm_timer* timer)
{
if(!timer)
return;
- evtimer_del(&timer->ev_timer->ev);
+ ub_timer_del(timer->ev_timer->ev);
timer->ev_timer->enabled = 0;
}
@@ -2116,12 +2291,8 @@ comm_timer_set(struct comm_timer* timer, struct timeval* tv)
log_assert(tv);
if(timer->ev_timer->enabled)
comm_timer_disable(timer);
- event_set(&timer->ev_timer->ev, -1, EV_TIMEOUT,
- comm_timer_callback, timer);
- if(event_base_set(timer->ev_timer->base->eb->base,
- &timer->ev_timer->ev) != 0)
- log_err("comm_timer_set: set_base failed.");
- if(evtimer_add(&timer->ev_timer->ev, tv) != 0)
+ if(ub_timer_add(timer->ev_timer->ev, timer->ev_timer->base->eb->base,
+ comm_timer_callback, timer, tv) != 0)
log_err("comm_timer_set: evtimer_add failed.");
timer->ev_timer->enabled = 1;
}
@@ -2132,17 +2303,20 @@ comm_timer_delete(struct comm_timer* timer)
if(!timer)
return;
comm_timer_disable(timer);
+ /* Free the sub struct timer->ev_timer derived from the super struct timer.
+ * i.e. assert(timer == timer->ev_timer)
+ */
+ ub_event_free(timer->ev_timer->ev);
free(timer->ev_timer);
- free(timer);
}
void
comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg)
{
struct comm_timer* tm = (struct comm_timer*)arg;
- if(!(event&EV_TIMEOUT))
+ if(!(event&UB_EV_TIMEOUT))
return;
- comm_base_now(tm->ev_timer->base);
+ ub_comm_base_now(tm->ev_timer->base);
tm->ev_timer->enabled = 0;
fptr_ok(fptr_whitelist_comm_timer(tm->callback));
(*tm->callback)(tm->cb_arg);
@@ -2155,9 +2329,9 @@ comm_timer_is_set(struct comm_timer* timer)
}
size_t
-comm_timer_get_mem(struct comm_timer* timer)
+comm_timer_get_mem(struct comm_timer* ATTR_UNUSED(timer))
{
- return sizeof(*timer) + sizeof(struct internal_timer);
+ return sizeof(struct internal_timer);
}
struct comm_signal*
@@ -2181,9 +2355,9 @@ void
comm_signal_callback(int sig, short event, void* arg)
{
struct comm_signal* comsig = (struct comm_signal*)arg;
- if(!(event & EV_SIGNAL))
+ if(!(event & UB_EV_SIGNAL))
return;
- comm_base_now(comsig->base);
+ ub_comm_base_now(comsig->base);
fptr_ok(fptr_whitelist_comm_signal(comsig->callback));
(*comsig->callback)(sig, comsig->cb_arg);
}
@@ -2199,14 +2373,16 @@ comm_signal_bind(struct comm_signal* comsig, int sig)
}
log_assert(comsig);
/* add signal event */
- signal_set(&entry->ev, sig, comm_signal_callback, comsig);
- if(event_base_set(comsig->base->eb->base, &entry->ev) != 0) {
- log_err("Could not set signal base");
+ entry->ev = ub_signal_new(comsig->base->eb->base, sig,
+ comm_signal_callback, comsig);
+ if(entry->ev == NULL) {
+ log_err("Could not create signal event");
free(entry);
return 0;
}
- if(signal_add(&entry->ev, NULL) != 0) {
+ if(ub_signal_add(entry->ev, NULL) != 0) {
log_err("Could not add signal handler");
+ ub_event_free(entry->ev);
free(entry);
return 0;
}
@@ -2225,7 +2401,8 @@ comm_signal_delete(struct comm_signal* comsig)
p=comsig->ev_signal;
while(p) {
np = p->next;
- signal_del(&p->ev);
+ ub_signal_del(p->ev);
+ ub_event_free(p->ev);
free(p);
p = np;
}