summaryrefslogtreecommitdiff
path: root/util/netevent.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/netevent.c')
-rw-r--r--util/netevent.c123
1 files changed, 103 insertions, 20 deletions
diff --git a/util/netevent.c b/util/netevent.c
index 8e66b9045fa1..2084cea3ec01 100644
--- a/util/netevent.c
+++ b/util/netevent.c
@@ -47,6 +47,7 @@
#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
@@ -665,6 +666,7 @@ 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);
@@ -701,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
@@ -717,6 +724,10 @@ 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;
c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
@@ -1310,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);
@@ -1364,15 +1381,15 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
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(c->buffer));
+ 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(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);
msg.msg_name = &c->repinfo.addr;
@@ -1400,9 +1417,9 @@ 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;
}
@@ -1411,13 +1428,13 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#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);
@@ -1459,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)
@@ -1487,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);
}
@@ -1503,6 +1520,20 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_tcp);
ub_comm_base_now(c->ev->base);
+#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);
@@ -1605,6 +1636,10 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
#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;
@@ -1655,6 +1690,10 @@ 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;
@@ -1726,6 +1765,12 @@ comm_point_create_tcp_handler(struct comm_base *base,
#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;
@@ -1789,6 +1834,10 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
#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 = UB_EV_READ | UB_EV_PERSIST;
@@ -1857,6 +1906,10 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
#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;
@@ -1914,6 +1967,10 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
#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;
/* ub_event stuff */
@@ -1970,6 +2027,10 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
#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;
/* ub_event stuff */
@@ -2034,8 +2095,14 @@ 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);
@@ -2044,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 &&
@@ -2160,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++)