aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/util/netevent.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/util/netevent.c')
-rw-r--r--contrib/unbound/util/netevent.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/contrib/unbound/util/netevent.c b/contrib/unbound/util/netevent.c
index 0d0fff429c03..aedcb5e07a30 100644
--- a/contrib/unbound/util/netevent.c
+++ b/contrib/unbound/util/netevent.c
@@ -1083,6 +1083,11 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
} else if( cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMP) {
memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval));
+#elif defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
+ } else if( cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_TIMESTAMP) {
+ /* FreeBSD and also Linux. */
+ memmove(&rep.c->recv_tv, CMSG_DATA(cmsg), sizeof(struct timeval));
#endif /* HAVE_LINUX_NET_TSTAMP_H */
}
}
@@ -3213,6 +3218,9 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
}
/* accept incoming connection. */
c_hdl = c->tcp_free;
+ /* Should not happen: inconsistent tcp_free state in
+ * accept_callback. */
+ log_assert(c_hdl->is_in_tcp_free);
/* clear leftover flags from previous use, and then set the
* correct event base for the event structure for libevent */
ub_event_free(c_hdl->ev->ev);
@@ -3287,10 +3295,15 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
#endif
}
+ /* Paranoia: Check that the state has not changed from above: */
+ /* Should not happen: tcp_free state changed within accept_callback. */
+ log_assert(c_hdl == c->tcp_free);
+ log_assert(c_hdl->is_in_tcp_free);
/* grab the tcp handler buffers */
c->cur_tcp_count++;
c->tcp_free = c_hdl->tcp_free;
c_hdl->tcp_free = NULL;
+ c_hdl->is_in_tcp_free = 0;
if(!c->tcp_free) {
/* stop accepting incoming queries for now. */
comm_point_stop_listening(c);
@@ -3311,12 +3324,14 @@ reclaim_tcp_handler(struct comm_point* c)
#endif
}
comm_point_close(c);
- if(c->tcp_parent) {
- if(c != c->tcp_parent->tcp_free) {
- c->tcp_parent->cur_tcp_count--;
- c->tcp_free = c->tcp_parent->tcp_free;
- c->tcp_parent->tcp_free = c;
- }
+ if(c->tcp_parent && !c->is_in_tcp_free) {
+ /* Should not happen: bad tcp_free state in reclaim_tcp. */
+ log_assert(c->tcp_free == NULL);
+ log_assert(c->tcp_parent->cur_tcp_count > 0);
+ c->tcp_parent->cur_tcp_count--;
+ c->tcp_free = c->tcp_parent->tcp_free;
+ c->tcp_parent->tcp_free = c;
+ c->is_in_tcp_free = 1;
if(!c->tcp_free) {
/* re-enable listening on accept socket */
comm_point_start_listening(c->tcp_parent, -1, -1);
@@ -4630,7 +4645,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
#endif
- if(event&UB_EV_TIMEOUT) {
+ if((event&UB_EV_TIMEOUT)) {
verbose(VERB_QUERY, "tcp took too long, dropped");
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
@@ -4640,7 +4655,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&UB_EV_READ
+ if((event&UB_EV_READ)
#ifdef USE_MSG_FASTOPEN
&& !(c->tcp_do_fastopen && (event&UB_EV_WRITE))
#endif
@@ -4665,7 +4680,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
tcp_more_read_again(fd, c);
return;
}
- if(event&UB_EV_WRITE) {
+ if((event&UB_EV_WRITE)) {
int has_tcpq = (c->tcp_req_info != NULL);
int* morewrite = c->tcp_more_write_again;
if(!comm_point_tcp_handle_write(fd, c)) {
@@ -4702,12 +4717,14 @@ reclaim_http_handler(struct comm_point* c)
#endif
}
comm_point_close(c);
- if(c->tcp_parent) {
- if(c != c->tcp_parent->tcp_free) {
- c->tcp_parent->cur_tcp_count--;
- c->tcp_free = c->tcp_parent->tcp_free;
- c->tcp_parent->tcp_free = c;
- }
+ if(c->tcp_parent && !c->is_in_tcp_free) {
+ /* Should not happen: bad tcp_free state in reclaim_http. */
+ log_assert(c->tcp_free == NULL);
+ log_assert(c->tcp_parent->cur_tcp_count > 0);
+ c->tcp_parent->cur_tcp_count--;
+ c->tcp_free = c->tcp_parent->tcp_free;
+ c->tcp_parent->tcp_free = c;
+ c->is_in_tcp_free = 1;
if(!c->tcp_free) {
/* re-enable listening on accept socket */
comm_point_start_listening(c->tcp_parent, -1, -1);
@@ -5144,6 +5161,15 @@ ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
log_assert(h2_session->c->type == comm_http);
log_assert(h2_session->c->h2_session);
+ if(++h2_session->reads_count > h2_session->c->http2_max_streams) {
+ /* We are somewhat arbitrarily capping the amount of
+ * consecutive reads on the HTTP2 session to the number of max
+ * allowed streams.
+ * When we reach the cap, error out with NGHTTP2_ERR_WOULDBLOCK
+ * to signal nghttp2_session_recv() to stop reading for now. */
+ h2_session->reads_count = 0;
+ return NGHTTP2_ERR_WOULDBLOCK;
+ }
#ifdef HAVE_SSL
if(h2_session->c->ssl) {
@@ -5177,7 +5203,7 @@ ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
}
#endif /* HAVE_SSL */
- ret = recv(h2_session->c->fd, buf, len, MSG_DONTWAIT);
+ ret = recv(h2_session->c->fd, (void*)buf, len, MSG_DONTWAIT);
if(ret == 0) {
return NGHTTP2_ERR_EOF;
} else if(ret < 0) {
@@ -5505,7 +5531,7 @@ ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
}
#endif /* HAVE_SSL */
- ret = send(h2_session->c->fd, buf, len, 0);
+ ret = send(h2_session->c->fd, (void*)buf, len, 0);
if(ret == 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(ret < 0) {
@@ -5648,7 +5674,7 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_http);
ub_comm_base_now(c->ev->base);
- if(event&UB_EV_TIMEOUT) {
+ if((event&UB_EV_TIMEOUT)) {
verbose(VERB_QUERY, "http took too long, dropped");
reclaim_http_handler(c);
if(!c->tcp_do_close) {
@@ -5658,7 +5684,7 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&UB_EV_READ) {
+ if((event&UB_EV_READ)) {
if(!comm_point_http_handle_read(fd, c)) {
reclaim_http_handler(c);
if(!c->tcp_do_close) {
@@ -5670,7 +5696,7 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
}
return;
}
- if(event&UB_EV_WRITE) {
+ if((event&UB_EV_WRITE)) {
if(!comm_point_http_handle_write(fd, c)) {
reclaim_http_handler(c);
if(!c->tcp_do_close) {
@@ -5691,7 +5717,7 @@ void comm_point_local_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_local);
ub_comm_base_now(c->ev->base);
- if(event&UB_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,
@@ -5710,7 +5736,7 @@ void comm_point_raw_handle_callback(int ATTR_UNUSED(fd),
log_assert(c->type == comm_raw);
ub_comm_base_now(c->ev->base);
- if(event&UB_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);
@@ -5743,6 +5769,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_udp;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -5807,6 +5834,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_udp;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -5874,6 +5902,7 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_doq;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -5974,6 +6003,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_tcp;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -6011,6 +6041,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
+ c->is_in_tcp_free = 1;
/* 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,
@@ -6073,6 +6104,7 @@ comm_point_create_http_handler(struct comm_base *base,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_http;
c->tcp_do_close = 1;
c->do_not_close = 0;
@@ -6131,6 +6163,7 @@ comm_point_create_http_handler(struct comm_base *base,
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
+ c->is_in_tcp_free = 1;
/* 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,
@@ -6192,6 +6225,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
return NULL;
}
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_tcp_accept;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -6286,6 +6320,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_tcp;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -6350,6 +6385,7 @@ comm_point_create_http_out(struct comm_base *base, size_t bufsize,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_http;
c->tcp_do_close = 0;
c->do_not_close = 0;
@@ -6420,6 +6456,7 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_local;
c->tcp_do_close = 0;
c->do_not_close = 1;
@@ -6483,6 +6520,7 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
+ c->is_in_tcp_free = 0;
c->type = comm_raw;
c->tcp_do_close = 0;
c->do_not_close = 1;