diff options
Diffstat (limited to 'services/outside_network.c')
| -rw-r--r-- | services/outside_network.c | 25 | 
1 files changed, 21 insertions, 4 deletions
diff --git a/services/outside_network.c b/services/outside_network.c index 426e87b3e246..9b1490e643f8 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -204,6 +204,9 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)  {  	struct pending_tcp* pend = w->outnet->tcp_free;  	int s; +#ifdef SO_REUSEADDR +	int on = 1; +#endif  	log_assert(pend);  	log_assert(pkt);  	log_assert(w->addrlen > 0); @@ -225,13 +228,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)  		return 0;  	} +#ifdef SO_REUSEADDR +	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, +		(socklen_t)sizeof(on)) < 0) { +		verbose(VERB_ALGO, "outgoing tcp:" +			" setsockopt(.. SO_REUSEADDR ..) failed"); +	} +#endif  	if (w->outnet->tcp_mss > 0) {  #if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)  		if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,  			(void*)&w->outnet->tcp_mss,  			(socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {  			verbose(VERB_ALGO, "outgoing tcp:" -				" setsockopt(.. SO_REUSEADDR ..) failed"); +				" setsockopt(.. TCP_MAXSEG ..) failed");  		}  #else  		verbose(VERB_ALGO, "outgoing tcp:" @@ -1538,18 +1548,22 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)  static int  serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)  { -	uint8_t* d1 = sldns_buffer_at(pkt, 12); +	uint8_t* d1 = sldns_buffer_begin(pkt)+12;  	uint8_t* d2 = qbuf+10;  	uint8_t len1, len2;  	int count = 0; +	if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */ +		return 0;  	log_assert(qbuflen >= 15 /* 10 header, root, type, class */);  	len1 = *d1++;  	len2 = *d2++; -	if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */ -		return 0;  	while(len1 != 0 || len2 != 0) {  		if(LABEL_IS_PTR(len1)) { +			/* check if we can read *d1 with compression ptr rest */ +			if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt))) +				return 0;  			d1 = sldns_buffer_begin(pkt)+PTR_OFFSET(len1, *d1); +			/* check if we can read the destination *d1 */  			if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))  				return 0;  			len1 = *d1++; @@ -1563,6 +1577,9 @@ serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)  			return 0;  		if(len1 > LDNS_MAX_LABELLEN)  			return 0; +		/* check len1 + 1(next length) are okay to read */ +		if(d1+len1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt))) +			return 0;  		log_assert(len1 <= LDNS_MAX_LABELLEN);  		log_assert(len2 <= LDNS_MAX_LABELLEN);  		log_assert(len1 == len2 && len1 != 0);  | 
