diff options
Diffstat (limited to 'contrib/unbound/util/netevent.c')
| -rw-r--r-- | contrib/unbound/util/netevent.c | 82 | 
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; | 
