diff options
author | Erik de Castro Lopo <erikd@mega-nerd.com> | 2017-06-16 20:16:05 +1000 |
---|---|---|
committer | Erik de Castro Lopo <erikd@mega-nerd.com> | 2017-06-17 23:04:00 +1000 |
commit | a85b5759f34c0c4110a479a8b5fa606f15ed9b23 (patch) | |
tree | 518cb8346249a42fd2aa8a78c09c3631e14db6aa /external/unbound/util/netevent.c | |
parent | Merge pull request #2059 (diff) | |
download | monero-a85b5759f34c0c4110a479a8b5fa606f15ed9b23.tar.xz |
Upgrade unbound library
These files were pulled from the 1.6.3 release tarball.
This new version builds against OpenSSL version 1.1 which will be
the default in the new Debian Stable which is due to be released
RealSoonNow (tm).
Diffstat (limited to 'external/unbound/util/netevent.c')
-rw-r--r-- | external/unbound/util/netevent.c | 685 |
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; } |