summaryrefslogtreecommitdiffstats
path: root/contrib/unbound/services/outside_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/services/outside_network.c')
-rw-r--r--contrib/unbound/services/outside_network.c266
1 files changed, 153 insertions, 113 deletions
diff --git a/contrib/unbound/services/outside_network.c b/contrib/unbound/services/outside_network.c
index e1cd0fd..fedbd0f 100644
--- a/contrib/unbound/services/outside_network.c
+++ b/contrib/unbound/services/outside_network.c
@@ -21,16 +21,16 @@
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
@@ -45,7 +45,6 @@
# include <sys/types.h>
#endif
#include <sys/time.h>
-#include <ldns/wire2host.h>
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
#include "services/cache/infra.h"
@@ -58,6 +57,7 @@
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
+#include "ldns/sbuffer.h"
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
@@ -76,10 +76,10 @@
/** initiate TCP transaction for serviced query */
static void serviced_tcp_initiate(struct outside_network* outnet,
- struct serviced_query* sq, ldns_buffer* buff);
+ struct serviced_query* sq, sldns_buffer* buff);
/** with a fd available, randomize and send UDP */
static int randomize_and_send_udp(struct outside_network* outnet,
- struct pending* pend, ldns_buffer* packet, int timeout);
+ struct pending* pend, sldns_buffer* packet, int timeout);
int
pending_cmp(const void* key1, const void* key2)
@@ -263,9 +263,9 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
pend->query = w;
pend->c->repinfo.addrlen = w->addrlen;
memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen);
- ldns_buffer_clear(pend->c->buffer);
- ldns_buffer_write(pend->c->buffer, pkt, pkt_len);
- ldns_buffer_flip(pend->c->buffer);
+ sldns_buffer_clear(pend->c->buffer);
+ sldns_buffer_write(pend->c->buffer, pkt, pkt_len);
+ sldns_buffer_flip(pend->c->buffer);
pend->c->tcp_is_reading = 0;
pend->c->tcp_byte_count = 0;
comm_point_start_listening(pend->c, s, -1);
@@ -325,8 +325,8 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
/* pass error below and exit */
} else {
/* check ID */
- if(ldns_buffer_limit(c->buffer) < sizeof(uint16_t) ||
- LDNS_ID_WIRE(ldns_buffer_begin(c->buffer))!=pend->id) {
+ if(sldns_buffer_limit(c->buffer) < sizeof(uint16_t) ||
+ LDNS_ID_WIRE(sldns_buffer_begin(c->buffer))!=pend->id) {
log_addr(VERB_QUERY,
"outnettcp: bad ID in reply, from:",
&pend->query->addr, pend->query->addrlen);
@@ -372,18 +372,20 @@ outnet_send_wait_udp(struct outside_network* outnet)
pend = outnet->udp_wait_first;
outnet->udp_wait_first = pend->next_waiting;
if(!pend->next_waiting) outnet->udp_wait_last = NULL;
- ldns_buffer_clear(outnet->udp_buff);
- ldns_buffer_write(outnet->udp_buff, pend->pkt, pend->pkt_len);
- ldns_buffer_flip(outnet->udp_buff);
+ sldns_buffer_clear(outnet->udp_buff);
+ sldns_buffer_write(outnet->udp_buff, pend->pkt, pend->pkt_len);
+ sldns_buffer_flip(outnet->udp_buff);
free(pend->pkt); /* freeing now makes get_mem correct */
pend->pkt = NULL;
pend->pkt_len = 0;
if(!randomize_and_send_udp(outnet, pend, outnet->udp_buff,
pend->timeout)) {
/* callback error on pending */
- fptr_ok(fptr_whitelist_pending_udp(pend->cb));
- (void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg,
- NETEVENT_CLOSED, NULL);
+ if(pend->cb) {
+ fptr_ok(fptr_whitelist_pending_udp(pend->cb));
+ (void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg,
+ NETEVENT_CLOSED, NULL);
+ }
pending_delete(outnet, pend);
}
}
@@ -402,14 +404,14 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
verbose(VERB_QUERY, "outnetudp got udp error %d", error);
return 0;
}
- if(ldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) {
+ if(sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) {
verbose(VERB_QUERY, "outnetudp udp too short");
return 0;
}
log_assert(reply_info);
/* setup lookup key */
- key.id = (unsigned)LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
+ key.id = (unsigned)LDNS_ID_WIRE(sldns_buffer_begin(c->buffer));
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
key.addrlen = reply_info->addrlen;
verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
@@ -460,8 +462,10 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "outnet handle udp reply");
/* delete from tree first in case callback creates a retry */
(void)rbtree_delete(outnet->pending, p->node.key);
- fptr_ok(fptr_whitelist_pending_udp(p->cb));
- (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info);
+ if(p->cb) {
+ fptr_ok(fptr_whitelist_pending_udp(p->cb));
+ (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info);
+ }
portcomm_loweruse(outnet, p->pc);
pending_delete(NULL, p);
outnet_send_wait_udp(outnet);
@@ -496,6 +500,17 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
}
+void
+pending_udp_timer_delay_cb(void* arg)
+{
+ struct pending* p = (struct pending*)arg;
+ struct outside_network* outnet = p->outnet;
+ verbose(VERB_ALGO, "timeout udp with delay");
+ portcomm_loweruse(outnet, p->pc);
+ pending_delete(outnet, p);
+ outnet_send_wait_udp(outnet);
+}
+
void
pending_udp_timer_cb(void *arg)
{
@@ -503,8 +518,20 @@ pending_udp_timer_cb(void *arg)
struct outside_network* outnet = p->outnet;
/* it timed out */
verbose(VERB_ALGO, "timeout udp");
- fptr_ok(fptr_whitelist_pending_udp(p->cb));
- (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL);
+ if(p->cb) {
+ fptr_ok(fptr_whitelist_pending_udp(p->cb));
+ (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL);
+ }
+ /* if delayclose, keep port open for a longer time.
+ * But if the udpwaitlist exists, then we are struggling to
+ * keep up with demand for sockets, so do not wait, but service
+ * the customer (customer service more important than portICMPs) */
+ if(outnet->delayclose && !outnet->udp_wait_first) {
+ p->cb = NULL;
+ p->timer->callback = &pending_udp_timer_delay_cb;
+ comm_timer_set(p->timer, &outnet->delay_tv);
+ return;
+ }
portcomm_loweruse(outnet, p->pc);
pending_delete(outnet, p);
outnet_send_wait_udp(outnet);
@@ -561,7 +588,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
int numavailports, size_t unwanted_threshold,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
- void* sslctx)
+ void* sslctx, int delayclose)
{
struct outside_network* outnet = (struct outside_network*)
calloc(1, sizeof(struct outside_network));
@@ -583,6 +610,13 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->unwanted_param = unwanted_param;
outnet->use_caps_for_id = use_caps_for_id;
outnet->do_udp = do_udp;
+#ifndef S_SPLINT_S
+ if(delayclose) {
+ outnet->delayclose = 1;
+ outnet->delay_tv.tv_sec = delayclose/1000;
+ outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
+ }
+#endif
if(numavailports == 0) {
log_err("no outgoing ports available");
outside_network_delete(outnet);
@@ -609,7 +643,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
return NULL;
}
}
- if( !(outnet->udp_buff = ldns_buffer_new(bufsize)) ||
+ if( !(outnet->udp_buff = sldns_buffer_new(bufsize)) ||
!(outnet->pending = rbtree_create(pending_cmp)) ||
!(outnet->serviced = rbtree_create(serviced_cmp)) ||
!create_pending_tcp(outnet, bufsize)) {
@@ -731,7 +765,7 @@ outside_network_delete(struct outside_network* outnet)
free(outnet->serviced);
}
if(outnet->udp_buff)
- ldns_buffer_free(outnet->udp_buff);
+ sldns_buffer_free(outnet->udp_buff);
if(outnet->unused_fds) {
struct port_comm* p = outnet->unused_fds, *np;
while(p) {
@@ -849,13 +883,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
sa->sin6_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
- 0, 0);
+ 0, 0, 0, NULL);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
sa->sin_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
- 0, 0);
+ 0, 0, 0, NULL);
}
return fd;
}
@@ -863,18 +897,18 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
/** Select random ID */
static int
select_id(struct outside_network* outnet, struct pending* pend,
- ldns_buffer* packet)
+ sldns_buffer* packet)
{
int id_tries = 0;
pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
- LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
+ LDNS_ID_SET(sldns_buffer_begin(packet), pend->id);
/* insert in tree */
pend->node.key = pend;
while(!rbtree_insert(outnet->pending, &pend->node)) {
/* change ID to avoid collision */
pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
- LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
+ LDNS_ID_SET(sldns_buffer_begin(packet), pend->id);
id_tries++;
if(id_tries == MAX_ID_RETRY) {
pend->id=99999; /* non existant ID */
@@ -958,7 +992,7 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
static int
randomize_and_send_udp(struct outside_network* outnet, struct pending* pend,
- ldns_buffer* packet, int timeout)
+ sldns_buffer* packet, int timeout)
{
struct timeval tv;
@@ -997,7 +1031,7 @@ randomize_and_send_udp(struct outside_network* outnet, struct pending* pend,
}
struct pending*
-pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
+pending_udp_query(struct outside_network* outnet, sldns_buffer* packet,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
comm_point_callback_t* cb, void* cb_arg)
{
@@ -1020,8 +1054,8 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
/* no unused fd, cannot create a new port (randomly) */
verbose(VERB_ALGO, "no fds available, udp query waiting");
pend->timeout = timeout;
- pend->pkt_len = ldns_buffer_limit(packet);
- pend->pkt = (uint8_t*)memdup(ldns_buffer_begin(packet),
+ pend->pkt_len = sldns_buffer_limit(packet);
+ pend->pkt = (uint8_t*)memdup(sldns_buffer_begin(packet),
pend->pkt_len);
if(!pend->pkt) {
comm_timer_delete(pend->timer);
@@ -1080,7 +1114,7 @@ outnet_tcptimer(void* arg)
}
struct waiting_tcp*
-pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
+pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
comm_point_callback_t* callback, void* callback_arg, int ssl_upstream)
{
@@ -1090,7 +1124,7 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
uint16_t id;
/* if no buffer is free allocate space to store query */
w = (struct waiting_tcp*)malloc(sizeof(struct waiting_tcp)
- + (pend?0:ldns_buffer_limit(packet)));
+ + (pend?0:sldns_buffer_limit(packet)));
if(!w) {
return NULL;
}
@@ -1101,7 +1135,7 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
w->pkt = NULL;
w->pkt_len = 0;
id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
- LDNS_ID_SET(ldns_buffer_begin(packet), id);
+ LDNS_ID_SET(sldns_buffer_begin(packet), id);
memcpy(&w->addr, addr, addrlen);
w->addrlen = addrlen;
w->outnet = outnet;
@@ -1115,16 +1149,16 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
comm_timer_set(w->timer, &tv);
if(pend) {
/* we have a buffer available right now */
- if(!outnet_tcp_take_into_use(w, ldns_buffer_begin(packet),
- ldns_buffer_limit(packet))) {
+ if(!outnet_tcp_take_into_use(w, sldns_buffer_begin(packet),
+ sldns_buffer_limit(packet))) {
waiting_tcp_delete(w);
return NULL;
}
} else {
/* queue up */
w->pkt = (uint8_t*)w + sizeof(struct waiting_tcp);
- w->pkt_len = ldns_buffer_limit(packet);
- memmove(w->pkt, ldns_buffer_begin(packet), w->pkt_len);
+ w->pkt_len = sldns_buffer_limit(packet);
+ memmove(w->pkt, sldns_buffer_begin(packet), w->pkt_len);
w->next_waiting = NULL;
if(outnet->tcp_wait_last)
outnet->tcp_wait_last->next_waiting = w;
@@ -1136,31 +1170,31 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
/** create query for serviced queries */
static void
-serviced_gen_query(ldns_buffer* buff, uint8_t* qname, size_t qnamelen,
+serviced_gen_query(sldns_buffer* buff, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint16_t flags)
{
- ldns_buffer_clear(buff);
+ sldns_buffer_clear(buff);
/* skip id */
- ldns_buffer_write_u16(buff, flags);
- ldns_buffer_write_u16(buff, 1); /* qdcount */
- ldns_buffer_write_u16(buff, 0); /* ancount */
- ldns_buffer_write_u16(buff, 0); /* nscount */
- ldns_buffer_write_u16(buff, 0); /* arcount */
- ldns_buffer_write(buff, qname, qnamelen);
- ldns_buffer_write_u16(buff, qtype);
- ldns_buffer_write_u16(buff, qclass);
- ldns_buffer_flip(buff);
+ sldns_buffer_write_u16(buff, flags);
+ sldns_buffer_write_u16(buff, 1); /* qdcount */
+ sldns_buffer_write_u16(buff, 0); /* ancount */
+ sldns_buffer_write_u16(buff, 0); /* nscount */
+ sldns_buffer_write_u16(buff, 0); /* arcount */
+ sldns_buffer_write(buff, qname, qnamelen);
+ sldns_buffer_write_u16(buff, qtype);
+ sldns_buffer_write_u16(buff, qclass);
+ sldns_buffer_flip(buff);
}
/** lookup serviced query in serviced query rbtree */
static struct serviced_query*
-lookup_serviced(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
+lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
struct sockaddr_storage* addr, socklen_t addrlen)
{
struct serviced_query key;
key.node.key = &key;
- key.qbuf = ldns_buffer_begin(buff);
- key.qbuflen = ldns_buffer_limit(buff);
+ key.qbuf = sldns_buffer_begin(buff);
+ key.qbuflen = sldns_buffer_limit(buff);
key.dnssec = dnssec;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
@@ -1170,7 +1204,7 @@ lookup_serviced(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
/** Create new serviced entry */
static struct serviced_query*
-serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
+serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
int want_dnssec, int tcp_upstream, int ssl_upstream,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int qtype)
@@ -1182,12 +1216,12 @@ serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
if(!sq)
return NULL;
sq->node.key = sq;
- sq->qbuf = memdup(ldns_buffer_begin(buff), ldns_buffer_limit(buff));
+ sq->qbuf = memdup(sldns_buffer_begin(buff), sldns_buffer_limit(buff));
if(!sq->qbuf) {
free(sq);
return NULL;
}
- sq->qbuflen = ldns_buffer_limit(buff);
+ sq->qbuflen = sldns_buffer_limit(buff);
sq->zone = memdup(zone, zonelen);
if(!sq->zone) {
free(sq->qbuf);
@@ -1210,6 +1244,8 @@ serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec,
sq->to_be_deleted = 0;
#ifdef UNBOUND_DEBUG
ins =
+#else
+ (void)
#endif
rbtree_insert(outnet->serviced, &sq->node);
log_assert(ins != NULL); /* must not be already present */
@@ -1310,17 +1346,17 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
/** put serviced query into a buffer */
static void
-serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
+serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
{
/* if we are using 0x20 bits for ID randomness, perturb them */
if(sq->outnet->use_caps_for_id) {
serviced_perturb_qname(sq->outnet->rnd, sq->qbuf, sq->qbuflen);
}
/* generate query */
- ldns_buffer_clear(buff);
- ldns_buffer_write_u16(buff, 0); /* id placeholder */
- ldns_buffer_write(buff, sq->qbuf, sq->qbuflen);
- ldns_buffer_flip(buff);
+ sldns_buffer_clear(buff);
+ sldns_buffer_write_u16(buff, 0); /* id placeholder */
+ sldns_buffer_write(buff, sq->qbuf, sq->qbuflen);
+ sldns_buffer_flip(buff);
if(with_edns) {
/* add edns section */
struct edns_data edns;
@@ -1344,7 +1380,7 @@ serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
if(sq->dnssec & EDNS_DO)
edns.bits = EDNS_DO;
if(sq->dnssec & BIT_CD)
- LDNS_CD_SET(ldns_buffer_begin(buff));
+ LDNS_CD_SET(sldns_buffer_begin(buff));
attach_edns_record(buff, &edns);
}
}
@@ -1357,11 +1393,11 @@ serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
* @return 0 on error.
*/
static int
-serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
+serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
{
int rtt, vs;
uint8_t edns_lame_known;
- uint32_t now = *sq->outnet->now_secs;
+ time_t now = *sq->outnet->now_secs;
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone,
sq->zonelen, now, &vs, &edns_lame_known, &rtt))
@@ -1397,21 +1433,21 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
/** check that perturbed qname is identical */
static int
-serviced_check_qname(ldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
+serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen)
{
- uint8_t* d1 = ldns_buffer_at(pkt, 12);
+ uint8_t* d1 = sldns_buffer_at(pkt, 12);
uint8_t* d2 = qbuf+10;
uint8_t len1, len2;
int count = 0;
log_assert(qbuflen >= 15 /* 10 header, root, type, class */);
len1 = *d1++;
len2 = *d2++;
- if(ldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */
+ 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)) {
- d1 = ldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
- if(d1 >= ldns_buffer_at(pkt, ldns_buffer_limit(pkt)))
+ d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1));
+ if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt)))
return 0;
len1 = *d1++;
if(count++ > MAX_COMPRESS_PTRS)
@@ -1449,6 +1485,8 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
size_t backlen = 0;
#ifdef UNBOUND_DEBUG
rbnode_t* rem =
+#else
+ (void)
#endif
/* remove from tree, and schedule for deletion, so that callbacks
* can safely deregister themselves and even create new serviced
@@ -1459,10 +1497,10 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
verbose(VERB_ALGO, "svcd callbacks start");
if(sq->outnet->use_caps_for_id && error == NETEVENT_NOERROR && c) {
/* noerror and nxdomain must have a qname in reply */
- if(ldns_buffer_read_u16_at(c->buffer, 4) == 0 &&
- (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
+ if(sldns_buffer_read_u16_at(c->buffer, 4) == 0 &&
+ (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_NOERROR ||
- LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
+ LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_NXDOMAIN)) {
verbose(VERB_DETAIL, "no qname in reply to check 0x20ID");
log_addr(VERB_DETAIL, "from server",
@@ -1470,7 +1508,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
log_buf(VERB_DETAIL, "for packet", c->buffer);
error = NETEVENT_CLOSED;
c = NULL;
- } else if(ldns_buffer_read_u16_at(c->buffer, 4) > 0 &&
+ } else if(sldns_buffer_read_u16_at(c->buffer, 4) > 0 &&
!serviced_check_qname(c->buffer, sq->qbuf,
sq->qbuflen)) {
verbose(VERB_DETAIL, "wrong 0x20-ID in reply qname");
@@ -1480,12 +1518,12 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
error = NETEVENT_CAPSFAIL;
/* and cleanup too */
pkt_dname_tolower(c->buffer,
- ldns_buffer_at(c->buffer, 12));
+ sldns_buffer_at(c->buffer, 12));
} else {
verbose(VERB_ALGO, "good 0x20-ID in reply qname");
/* cleanup caps, prettier cache contents. */
pkt_dname_tolower(c->buffer,
- ldns_buffer_at(c->buffer, 12));
+ sldns_buffer_at(c->buffer, 12));
}
}
if(dobackup && c) {
@@ -1493,8 +1531,8 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
* may send outgoing queries that overwrite the buffer.
* use secondary buffer to store the query.
* This is a data copy, but faster than packet to server */
- backlen = ldns_buffer_limit(c->buffer);
- backup_p = memdup(ldns_buffer_begin(c->buffer), backlen);
+ backlen = sldns_buffer_limit(c->buffer);
+ backup_p = memdup(sldns_buffer_begin(c->buffer), backlen);
if(!backup_p) {
log_err("malloc failure in serviced query callbacks");
error = NETEVENT_CLOSED;
@@ -1506,9 +1544,9 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
while((p=sq->cblist) != NULL) {
sq->cblist = p->next; /* remove this element */
if(dobackup && c) {
- ldns_buffer_clear(c->buffer);
- ldns_buffer_write(c->buffer, backup_p, backlen);
- ldns_buffer_flip(c->buffer);
+ sldns_buffer_clear(c->buffer);
+ sldns_buffer_write(c->buffer, backup_p, backlen);
+ sldns_buffer_flip(c->buffer);
}
fptr_ok(fptr_whitelist_serviced_query(p->cb));
(void)(*p->cb)(c, p->cb_arg, error, rep);
@@ -1537,8 +1575,8 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
infra_update_tcp_works(sq->outnet->infra, &sq->addr,
sq->addrlen, sq->zone, sq->zonelen);
if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS &&
- (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) ==
- LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(ldns_buffer_begin(
+ (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
+ LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(sldns_buffer_begin(
c->buffer)) == LDNS_RCODE_NOTIMPL) ) {
/* attempt to fallback to nonEDNS */
sq->status = serviced_query_TCP_EDNS_fallback;
@@ -1546,10 +1584,10 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
return 0;
} else if(error==NETEVENT_NOERROR &&
sq->status == serviced_query_TCP_EDNS_fallback &&
- (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) ==
+ (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
LDNS_RCODE_NOERROR || LDNS_RCODE_WIRE(
- ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NXDOMAIN
- || LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
+ sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NXDOMAIN
+ || LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_YXDOMAIN)) {
/* the fallback produced a result that looks promising, note
* that this server should be approached without EDNS */
@@ -1567,7 +1605,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
(now.tv_sec == sq->last_sent_time.tv_sec &&
now.tv_usec > sq->last_sent_time.tv_usec)) {
/* convert from microseconds to milliseconds */
- int roundtime = ((int)now.tv_sec - (int)sq->last_sent_time.tv_sec)*1000
+ int roundtime = ((int)(now.tv_sec - sq->last_sent_time.tv_sec))*1000
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
verbose(VERB_ALGO, "measured TCP-time at %d msec", roundtime);
log_assert(roundtime >= 0);
@@ -1576,7 +1614,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) {
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
- roundtime, sq->last_rtt, (uint32_t)now.tv_sec))
+ roundtime, sq->last_rtt, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
}
}
@@ -1595,7 +1633,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
static void
serviced_tcp_initiate(struct outside_network* outnet,
- struct serviced_query* sq, ldns_buffer* buff)
+ struct serviced_query* sq, sldns_buffer* buff)
{
verbose(VERB_ALGO, "initiate TCP query %s",
sq->status==serviced_query_TCP_EDNS?"EDNS":"");
@@ -1614,7 +1652,7 @@ serviced_tcp_initiate(struct outside_network* outnet,
/** Send serviced query over TCP return false on initial failure */
static int
-serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff)
+serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
{
int vs, rtt;
uint8_t edns_lame_known;
@@ -1668,7 +1706,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
sq->retry++;
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt,
- (uint32_t)now.tv_sec)))
+ (time_t)now.tv_sec)))
log_err("out of memory in UDP exponential backoff");
if(sq->retry < OUTBOUND_UDP_RETRY) {
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
@@ -1693,9 +1731,9 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
if(!fallback_tcp) {
if( (sq->status == serviced_query_UDP_EDNS
||sq->status == serviced_query_UDP_EDNS_FRAG)
- && (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
+ && (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
- ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) {
+ sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) {
/* try to get an answer by falling back without EDNS */
verbose(VERB_ALGO, "serviced query: attempt without EDNS");
sq->status = serviced_query_UDP_EDNS_fallback;
@@ -1712,7 +1750,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
/* only store noEDNS in cache if domain is noDNSSEC */
if(!sq->want_dnssec)
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
- sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) {
+ sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
log_err("Out of memory caching no edns for host");
}
sq->status = serviced_query_UDP;
@@ -1722,15 +1760,15 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
log_addr(VERB_ALGO, "serviced query: EDNS works for",
&sq->addr, sq->addrlen);
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
- sq->zone, sq->zonelen, 0, (uint32_t)now.tv_sec)) {
+ sq->zone, sq->zonelen, 0, (time_t)now.tv_sec)) {
log_err("Out of memory caching edns works");
}
sq->edns_lame_known = 1;
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
!sq->edns_lame_known && (LDNS_RCODE_WIRE(
- ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
- LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) ==
- LDNS_RCODE_NXDOMAIN || LDNS_RCODE_WIRE(ldns_buffer_begin(
+ sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
+ LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
+ LDNS_RCODE_NXDOMAIN || LDNS_RCODE_WIRE(sldns_buffer_begin(
c->buffer)) == LDNS_RCODE_YXDOMAIN)) {
/* the fallback produced a result that looks promising, note
* that this server should be approached without EDNS */
@@ -1739,7 +1777,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
log_addr(VERB_ALGO, "serviced query: EDNS fails for",
&sq->addr, sq->addrlen);
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
- sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) {
+ sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
log_err("Out of memory caching no edns for host");
}
} else {
@@ -1753,7 +1791,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
(now.tv_sec == sq->last_sent_time.tv_sec &&
now.tv_usec > sq->last_sent_time.tv_usec)) {
/* convert from microseconds to milliseconds */
- int roundtime = ((int)now.tv_sec - (int)sq->last_sent_time.tv_sec)*1000
+ int roundtime = ((int)(now.tv_sec - sq->last_sent_time.tv_sec))*1000
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
log_assert(roundtime >= 0);
@@ -1762,14 +1800,14 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
if(roundtime < 60000) {
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
sq->zone, sq->zonelen, sq->qtype, roundtime,
- sq->last_rtt, (uint32_t)now.tv_sec))
+ sq->last_rtt, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
}
}
} /* end of if_!fallback_tcp */
/* perform TC flag check and TCP fallback after updating our
* cache entries for EDNS status and RTT times */
- if(LDNS_TC_WIRE(ldns_buffer_begin(c->buffer)) || fallback_tcp) {
+ if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) {
/* fallback to TCP */
/* this discards partial UDP contents */
if(sq->status == serviced_query_UDP_EDNS ||
@@ -1792,7 +1830,7 @@ outnet_serviced_query(struct outside_network* outnet,
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
- void* callback_arg, ldns_buffer* buff)
+ void* callback_arg, sldns_buffer* buff)
{
struct serviced_query* sq;
struct service_callback* cb;
@@ -1866,6 +1904,8 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
if(!sq->cblist && !sq->to_be_deleted) {
#ifdef UNBOUND_DEBUG
rbnode_t* rem =
+#else
+ (void)
#endif
rbtree_delete(sq->outnet->serviced, sq);
log_assert(rem); /* should be present */
@@ -1919,7 +1959,7 @@ size_t outnet_get_mem(struct outside_network* outnet)
struct port_comm* pc;
size_t s = sizeof(*outnet) + sizeof(*outnet->base) +
sizeof(*outnet->udp_buff) +
- ldns_buffer_capacity(outnet->udp_buff);
+ sldns_buffer_capacity(outnet->udp_buff);
/* second buffer is not ours */
for(pc = outnet->unused_fds; pc; pc = pc->next) {
s += sizeof(*pc) + comm_point_get_mem(pc->cp);
OpenPOWER on IntegriCloud