aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2014-05-14 18:44:22 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2014-05-14 18:44:22 +0000
commit79dd93c19fd35899133800562b0db20f1a4c0f56 (patch)
tree86c1332d2843f4c80ae64365c16ba04306b6f542 /services
parentf61d78fb42d2662643e7f0dbdcb97adbc2589dbc (diff)
downloadsrc-79dd93c19fd35899133800562b0db20f1a4c0f56.tar.gz
src-79dd93c19fd35899133800562b0db20f1a4c0f56.zip
import unbound 1.4.22vendor/unbound/1.4.22
Notes
Notes: svn path=/vendor/unbound/dist/; revision=266077 svn path=/vendor/unbound/1.4.22/; revision=266078; tag=vendor/unbound/1.4.22
Diffstat (limited to 'services')
-rw-r--r--services/cache/dns.c23
-rw-r--r--services/cache/dns.h20
-rw-r--r--services/cache/infra.c22
-rw-r--r--services/cache/infra.h20
-rw-r--r--services/cache/rrset.c21
-rw-r--r--services/cache/rrset.h20
-rw-r--r--services/listen_dnsport.c142
-rw-r--r--services/listen_dnsport.h40
-rw-r--r--services/localzone.c329
-rw-r--r--services/localzone.h29
-rw-r--r--services/mesh.c55
-rw-r--r--services/mesh.h33
-rw-r--r--services/modstack.c20
-rw-r--r--services/modstack.h20
-rw-r--r--services/outbound_list.c20
-rw-r--r--services/outbound_list.h20
-rw-r--r--services/outside_network.c242
-rw-r--r--services/outside_network.h40
18 files changed, 610 insertions, 506 deletions
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 7dadb5c39656..f2a04a227cb9 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.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.
*/
/**
@@ -50,6 +50,7 @@
#include "util/net_help.h"
#include "util/regional.h"
#include "util/config_file.h"
+#include "ldns/sbuffer.h"
/** store rrsets in the rrset cache.
* @param env: module environment with caches.
@@ -615,7 +616,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
newd->rr_ttl[0] = newd->ttl;
msg->rep->ttl = newd->ttl;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(newd->ttl);
- ldns_write_uint16(newd->rr_data[0], newlen);
+ sldns_write_uint16(newd->rr_data[0], newlen);
memmove(newd->rr_data[0] + sizeof(uint16_t), newname, newlen);
msg->rep->an_numrrsets ++;
msg->rep->rrset_count ++;
diff --git a/services/cache/dns.h b/services/cache/dns.h
index 508f34441118..a7a6190cffba 100644
--- a/services/cache/dns.h
+++ b/services/cache/dns.h
@@ -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.
*/
/**
diff --git a/services/cache/infra.c b/services/cache/infra.c
index 42d6acad1a22..07f2103d756b 100644
--- a/services/cache/infra.c
+++ b/services/cache/infra.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.
*/
/**
@@ -39,7 +39,7 @@
* This file contains the infrastructure cache.
*/
#include "config.h"
-#include <ldns/rr.h>
+#include "ldns/rrdef.h"
#include "services/cache/infra.h"
#include "util/storage/slabhash.h"
#include "util/storage/lookup3.h"
diff --git a/services/cache/infra.h b/services/cache/infra.h
index d3976aed7113..fc54f7f0df00 100644
--- a/services/cache/infra.h
+++ b/services/cache/infra.h
@@ -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.
*/
/**
diff --git a/services/cache/rrset.c b/services/cache/rrset.c
index 642236231121..5f52dbce1948 100644
--- a/services/cache/rrset.c
+++ b/services/cache/rrset.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.
*/
/**
@@ -40,6 +40,7 @@
*/
#include "config.h"
#include "services/cache/rrset.h"
+#include "ldns/rrdef.h"
#include "util/storage/slabhash.h"
#include "util/config_file.h"
#include "util/data/packed_rrset.h"
diff --git a/services/cache/rrset.h b/services/cache/rrset.h
index 92ced928b304..98e44a4e5268 100644
--- a/services/cache/rrset.h
+++ b/services/cache/rrset.h
@@ -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.
*/
/**
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c
index 368faaea4211..8b1d62e3a209 100644
--- a/services/listen_dnsport.c
+++ b/services/listen_dnsport.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.
*/
/**
@@ -49,6 +49,7 @@
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
+#include "ldns/sbuffer.h"
#ifdef HAVE_NETDB_H
#include <netdb.h>
@@ -75,7 +76,7 @@ verbose_print_addr(struct addrinfo *addr)
#endif /* INET6 */
if(inet_ntop(addr->ai_family, sinaddr, buf,
(socklen_t)sizeof(buf)) == 0) {
- strncpy(buf, "(null)", sizeof(buf));
+ (void)strlcpy(buf, "(null)", sizeof(buf));
}
buf[sizeof(buf)-1] = 0;
verbose(VERB_ALGO, "creating %s%s socket %s %d",
@@ -91,10 +92,10 @@ verbose_print_addr(struct addrinfo *addr)
int
create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto,
- int rcv, int snd)
+ int rcv, int snd, int listen, int* reuseport)
{
int s;
-#if defined(IPV6_USE_MIN_MTU)
+#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU)
int on=1;
#endif
#ifdef IPV6_MTU
@@ -129,6 +130,50 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*noproto = 0;
return -1;
}
+ if(listen) {
+#ifdef SO_REUSEADDR
+ if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
+ (socklen_t)sizeof(on)) < 0) {
+#ifndef USE_WINSOCK
+ log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+ strerror(errno));
+ if(errno != ENOSYS) {
+ close(s);
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
+#else
+ log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+ closesocket(s);
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+#endif
+ }
+#endif /* SO_REUSEADDR */
+#if defined(__linux__) && defined(SO_REUSEPORT)
+ /* Linux specific: try to set SO_REUSEPORT so that incoming
+ * queries are distributed evenly among the receiving threads.
+ * Each thread must have its own socket bound to the same port,
+ * with SO_REUSEPORT set on each socket.
+ */
+ if (reuseport && *reuseport &&
+ setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on,
+ (socklen_t)sizeof(on)) < 0) {
+#ifdef ENOPROTOOPT
+ if(errno != ENOPROTOOPT || verbosity >= 3)
+ log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s",
+ strerror(errno));
+#endif
+ /* this option is not essential, we can continue */
+ *reuseport = 0;
+ }
+#else
+ (void)reuseport;
+#endif /* defined(__linux__) && defined(SO_REUSEPORT) */
+ }
if(rcv) {
#ifdef SO_RCVBUF
int got;
@@ -391,10 +436,11 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
}
int
-create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
+create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
+ int* reuseport)
{
int s;
-#if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY)
+#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY)
int on = 1;
#endif /* SO_REUSEADDR || IPV6_V6ONLY */
verbose_print_addr(addr);
@@ -432,6 +478,26 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
return -1;
}
#endif /* SO_REUSEADDR */
+#if defined(__linux__) && defined(SO_REUSEPORT)
+ /* Linux specific: try to set SO_REUSEPORT so that incoming
+ * connections are distributed evenly among the receiving threads.
+ * Each thread must have its own socket bound to the same port,
+ * with SO_REUSEPORT set on each socket.
+ */
+ if (reuseport && *reuseport &&
+ setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (void*)&on,
+ (socklen_t)sizeof(on)) < 0) {
+#ifdef ENOPROTOOPT
+ if(errno != ENOPROTOOPT || verbosity >= 3)
+ log_warn("setsockopt(.. SO_REUSEPORT ..) failed: %s",
+ strerror(errno));
+#endif
+ /* this option is not essential, we can continue */
+ *reuseport = 0;
+ }
+#else
+ (void)reuseport;
+#endif /* defined(__linux__) && defined(SO_REUSEPORT) */
#if defined(IPV6_V6ONLY)
if(addr->ai_family == AF_INET6 && v6only) {
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
@@ -499,7 +565,8 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
*/
static int
make_sock(int stype, const char* ifname, const char* port,
- struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd)
+ struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
+ int* reuseport)
{
struct addrinfo *res = NULL;
int r, s, inuse, noproto;
@@ -526,14 +593,15 @@ make_sock(int stype, const char* ifname, const char* port,
verbose_print_addr(res);
s = create_udp_sock(res->ai_family, res->ai_socktype,
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
- v6only, &inuse, &noproto, (int)rcv, (int)snd);
+ v6only, &inuse, &noproto, (int)rcv, (int)snd, 1,
+ reuseport);
if(s == -1 && inuse) {
log_err("bind: address already in use");
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
*noip6 = 1;
}
} else {
- s = create_tcp_accept_sock(res, v6only, &noproto);
+ s = create_tcp_accept_sock(res, v6only, &noproto, reuseport);
if(s == -1 && noproto && hints->ai_family == AF_INET6){
*noip6 = 1;
}
@@ -545,7 +613,8 @@ make_sock(int stype, const char* ifname, const char* port,
/** make socket and first see if ifname contains port override info */
static int
make_sock_port(int stype, const char* ifname, const char* port,
- struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd)
+ struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
+ int* reuseport)
{
char* s = strchr(ifname, '@');
if(s) {
@@ -562,14 +631,15 @@ make_sock_port(int stype, const char* ifname, const char* port,
*noip6 = 0;
return -1;
}
- strncpy(newif, ifname, sizeof(newif));
+ (void)strlcpy(newif, ifname, sizeof(newif));
newif[s-ifname] = 0;
- strncpy(p, s+1, sizeof(p));
+ (void)strlcpy(p, s+1, sizeof(p));
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6,
- rcv, snd);
+ rcv, snd, reuseport);
}
- return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd);
+ return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
+ reuseport);
}
/**
@@ -661,19 +731,21 @@ set_recvpktinfo(int s, int family)
* @param rcv: receive buffer size for UDP
* @param snd: send buffer size for UDP
* @param ssl_port: ssl service port number
+ * @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
+ * set to false on exit if reuseport failed due to no kernel support.
* @return: returns false on error.
*/
static int
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
struct addrinfo *hints, const char* port, struct listen_port** list,
- size_t rcv, size_t snd, int ssl_port)
+ size_t rcv, size_t snd, int ssl_port, int* reuseport)
{
int s, noip6=0;
if(!do_udp && !do_tcp)
return 0;
if(do_auto) {
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
- &noip6, rcv, snd)) == -1) {
+ &noip6, rcv, snd, reuseport)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
@@ -700,7 +772,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
} else if(do_udp) {
/* regular udp socket */
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
- &noip6, rcv, snd)) == -1) {
+ &noip6, rcv, snd, reuseport)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
@@ -721,7 +793,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
atoi(strchr(ifname, '@')+1) == ssl_port) ||
(!strchr(ifname, '@') && atoi(port) == ssl_port));
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
- &noip6, 0, 0)) == -1) {
+ &noip6, 0, 0, reuseport)) == -1) {
if(noip6) {
/*log_warn("IPv6 protocol not available");*/
return 1;
@@ -772,7 +844,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
if(!front)
return NULL;
front->cps = NULL;
- front->udp_buff = ldns_buffer_new(bufsize);
+ front->udp_buff = sldns_buffer_new(bufsize);
if(!front->udp_buff) {
free(front);
return NULL;
@@ -835,12 +907,12 @@ listen_delete(struct listen_dnsport* front)
if(!front)
return;
listen_list_delete(front->cps);
- ldns_buffer_free(front->udp_buff);
+ sldns_buffer_free(front->udp_buff);
free(front);
}
struct listen_port*
-listening_ports_open(struct config_file* cfg)
+listening_ports_open(struct config_file* cfg, int* reuseport)
{
struct listen_port* list = NULL;
struct addrinfo hints;
@@ -876,7 +948,7 @@ listening_ports_open(struct config_file* cfg)
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port)) {
+ cfg->ssl_port, reuseport)) {
listening_ports_free(list);
return NULL;
}
@@ -887,7 +959,7 @@ listening_ports_open(struct config_file* cfg)
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port)) {
+ cfg->ssl_port, reuseport)) {
listening_ports_free(list);
return NULL;
}
@@ -900,7 +972,7 @@ listening_ports_open(struct config_file* cfg)
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port)) {
+ cfg->ssl_port, reuseport)) {
listening_ports_free(list);
return NULL;
}
@@ -911,7 +983,7 @@ listening_ports_open(struct config_file* cfg)
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
- cfg->ssl_port)) {
+ cfg->ssl_port, reuseport)) {
listening_ports_free(list);
return NULL;
}
@@ -941,7 +1013,7 @@ size_t listen_get_mem(struct listen_dnsport* listen)
{
size_t s = sizeof(*listen) + sizeof(*listen->base) +
sizeof(*listen->udp_buff) +
- ldns_buffer_capacity(listen->udp_buff);
+ sldns_buffer_capacity(listen->udp_buff);
struct listen_list* p;
for(p = listen->cps; p; p = p->next) {
s += sizeof(*p);
diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h
index 4d37aca5eee4..61fb9a0b44e8 100644
--- a/services/listen_dnsport.h
+++ b/services/listen_dnsport.h
@@ -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.
*/
/**
@@ -46,6 +46,7 @@
struct listen_list;
struct config_file;
struct addrinfo;
+struct sldns_buffer;
/**
* Listening for queries structure.
@@ -57,7 +58,7 @@ struct listen_dnsport {
/** buffer shared by UDP connections, since there is only one
datagram at any time. */
- ldns_buffer* udp_buff;
+ struct sldns_buffer* udp_buff;
/** list of comm points used to get incoming events */
struct listen_list* cps;
@@ -106,9 +107,13 @@ struct listen_port {
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
* On the given port number. It creates the sockets.
* @param cfg: settings on what ports to open.
+ * @param reuseport: set to true if you want reuseport, or NULL to not have it,
+ * set to false on exit if reuseport failed to apply (because of no
+ * kernel support).
* @return: linked list of ports or NULL on error.
*/
-struct listen_port* listening_ports_open(struct config_file* cfg);
+struct listen_port* listening_ports_open(struct config_file* cfg,
+ int* reuseport);
/**
* Close and delete the (list of) listening ports.
@@ -178,19 +183,26 @@ void listen_start_accept(struct listen_dnsport* listen);
IPv6 proto (family) is not available.
* @param rcv: set size on rcvbuf with socket option, if 0 it is not set.
* @param snd: set size on sndbuf with socket option, if 0 it is not set.
+ * @param listen: if true, this is a listening UDP port, eg port 53, and
+ * set SO_REUSEADDR on it.
+ * @param reuseport: if nonNULL and true, try to set SO_REUSEPORT on
+ * listening UDP port. Set to false on return if it failed to do so.
* @return: the socket. -1 on error.
*/
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
- int snd);
+ int snd, int listen, int* reuseport);
/**
* Create and bind TCP listening socket
* @param addr: address info ready to make socket.
* @param v6only: enable ip6 only flag on ip6 sockets.
* @param noproto: if error caused by lack of protocol support.
+ * @param reuseport: if nonNULL and true, try to set SO_REUSEPORT on
+ * listening UDP port. Set to false on return if it failed to do so.
* @return: the socket. -1 on error.
*/
-int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto);
+int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
+ int* reuseport);
#endif /* LISTEN_DNSPORT_H */
diff --git a/services/localzone.c b/services/localzone.c
index 4a2187ec4f25..ac889799b430 100644
--- a/services/localzone.c
+++ b/services/localzone.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.
*/
/**
@@ -39,9 +39,9 @@
* This file contains functions to enable local zone authority service.
*/
#include "config.h"
-#include <ldns/dname.h>
-#include <ldns/host2wire.h>
#include "services/localzone.h"
+#include "ldns/str2wire.h"
+#include "ldns/sbuffer.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/data/dname.h"
@@ -59,7 +59,7 @@ local_zones_create(void)
if(!zones)
return NULL;
rbtree_init(&zones->ztree, &local_zone_cmp);
- lock_quick_init(&zones->lock);
+ lock_rw_init(&zones->lock);
lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree));
/* also lock protects the rbnode's in struct local_zone */
return zones;
@@ -78,7 +78,7 @@ local_zones_delete(struct local_zones* zones)
{
if(!zones)
return;
- lock_quick_destroy(&zones->lock);
+ lock_rw_destroy(&zones->lock);
/* walk through zones and delete them all */
traverse_postorder(&zones->ztree, lzdel, NULL);
free(zones);
@@ -125,19 +125,10 @@ local_data_cmp(const void* d1, const void* d2)
int
parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
{
- ldns_rdf* rdf;
- *res = NULL;
- *len = 0;
+ *res = sldns_str2wire_dname(str, len);
*labs = 0;
- rdf = ldns_dname_new_frm_str(str);
- if(!rdf) {
- log_err("cannot parse name %s", str);
- return 0;
- }
- *res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
- ldns_rdf_deep_free(rdf);
if(!*res) {
- log_err("out of memory");
+ log_err("cannot parse name %s", str);
return 0;
}
*labs = dname_count_size_labels(*res, len);
@@ -183,16 +174,16 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
}
/* add to rbtree */
- lock_quick_lock(&zones->lock);
+ lock_rw_wrlock(&zones->lock);
lock_rw_wrlock(&z->lock);
if(!rbtree_insert(&zones->ztree, &z->node)) {
log_warn("duplicate local-zone");
lock_rw_unlock(&z->lock);
local_zone_delete(z);
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
return NULL;
}
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
return z;
}
@@ -225,39 +216,28 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
/** return name and class and rdata of rr; parses string */
static int
get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
- uint16_t* dclass, time_t* ttl, ldns_buffer* rdata)
+ uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
+ uint8_t** rdata, size_t* rdata_len)
{
- ldns_rr* rr = NULL;
- ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
- if(status != LDNS_STATUS_OK) {
- log_err("error parsing local-data '%s': %s",
- str, ldns_get_errorstr_by_id(status));
- ldns_rr_free(rr);
+ size_t dname_len = 0;
+ int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
+ NULL, 0, NULL, 0);
+ if(e) {
+ log_err("error parsing local-data at %d: '%s': %s",
+ LDNS_WIREPARSE_OFFSET(e), str,
+ sldns_get_errorstr_parse(e));
return 0;
}
- *nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
- ldns_rdf_size(ldns_rr_owner(rr)));
+ *nm = memdup(rr, dname_len);
if(!*nm) {
log_err("out of memory");
- ldns_rr_free(rr);
return 0;
}
- *dclass = ldns_rr_get_class(rr);
- *type = ldns_rr_get_type(rr);
- *ttl = (time_t)ldns_rr_ttl(rr);
- ldns_buffer_clear(rdata);
- ldns_buffer_skip(rdata, 2);
- status = ldns_rr_rdata2buffer_wire(rdata, rr);
- ldns_rr_free(rr);
- if(status != LDNS_STATUS_OK) {
- log_err("error converting RR '%s' to wireformat: %s",
- str, ldns_get_errorstr_by_id(status));
- free(*nm);
- *nm = NULL;
- return 0;
- }
- ldns_buffer_flip(rdata);
- ldns_buffer_write_u16_at(rdata, 0, ldns_buffer_limit(rdata) - 2);
+ *dclass = sldns_wirerr_get_class(rr, len, dname_len);
+ *type = sldns_wirerr_get_type(rr, len, dname_len);
+ *ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len);
+ *rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len);
+ *rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2;
return 1;
}
@@ -265,18 +245,18 @@ get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
static int
get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
{
- ldns_rr* rr = NULL;
- ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL);
- if(status != LDNS_STATUS_OK) {
- log_err("error parsing local-data '%s': %s",
- str, ldns_get_errorstr_by_id(status));
- ldns_rr_free(rr);
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ size_t len = sizeof(rr), dname_len = 0;
+ int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
+ NULL, 0, NULL, 0);
+ if(s != 0) {
+ log_err("error parsing local-data at %d '%s': %s",
+ LDNS_WIREPARSE_OFFSET(s), str,
+ sldns_get_errorstr_parse(s));
return 0;
}
- *nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)),
- ldns_rdf_size(ldns_rr_owner(rr)));
- *dclass = ldns_rr_get_class(rr);
- ldns_rr_free(rr);
+ *nm = memdup(rr, dname_len);
+ *dclass = sldns_wirerr_get_class(rr, len, dname_len);
if(!*nm) {
log_err("out of memory");
return 0;
@@ -304,13 +284,12 @@ local_data_find_type(struct local_data* data, uint16_t type)
/** check for RR duplicates */
static int
-rr_is_duplicate(struct packed_rrset_data* pd, ldns_buffer* buf)
+rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
{
size_t i;
for(i=0; i<pd->count; i++) {
- if(ldns_buffer_limit(buf) == pd->rr_len[i] &&
- memcmp(ldns_buffer_begin(buf), pd->rr_data[i],
- ldns_buffer_limit(buf)) == 0)
+ if(pd->rr_len[i] == rdata_len &&
+ memcmp(pd->rr_data[i], rdata, rdata_len) == 0)
return 1;
}
return 0;
@@ -356,7 +335,7 @@ new_local_rrset(struct regional* region, struct local_data* node,
/** insert RR into RRset data structure; Wastes a couple of bytes */
static int
insert_rr(struct regional* region, struct packed_rrset_data* pd,
- ldns_buffer* buf, time_t ttl)
+ uint8_t* rdata, size_t rdata_len, time_t ttl)
{
size_t* oldlen = pd->rr_len;
time_t* oldttl = pd->rr_ttl;
@@ -379,10 +358,9 @@ insert_rr(struct regional* region, struct packed_rrset_data* pd,
memcpy(pd->rr_data+1, olddata,
sizeof(*pd->rr_data)*(pd->count-1));
}
- pd->rr_len[0] = ldns_buffer_limit(buf);
+ pd->rr_len[0] = rdata_len;
pd->rr_ttl[0] = ttl;
- pd->rr_data[0] = regional_alloc_init(region,
- ldns_buffer_begin(buf), ldns_buffer_limit(buf));
+ pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len);
if(!pd->rr_data[0]) {
log_err("out of memory");
return 0;
@@ -440,8 +418,7 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
/** enter data RR into auth zone */
static int
-lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
- const char* rrstr)
+lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
{
uint8_t* nm;
size_t nmlen;
@@ -451,7 +428,11 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
struct packed_rrset_data* pd;
uint16_t rrtype = 0, rrclass = 0;
time_t ttl = 0;
- if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, buf)) {
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ uint8_t* rdata;
+ size_t rdata_len;
+ if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
+ &rdata, &rdata_len)) {
log_err("bad local-data: %s", rrstr);
return 0;
}
@@ -487,16 +468,16 @@ lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf,
log_assert(rrset && pd);
/* check for duplicate RR */
- if(rr_is_duplicate(pd, buf)) {
+ if(rr_is_duplicate(pd, rdata, rdata_len)) {
verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
return 1;
}
- return insert_rr(z->region, pd, buf, ttl);
+ return insert_rr(z->region, pd, rdata, rdata_len, ttl);
}
/** enter a data RR into auth data; a zone for it must exist */
static int
-lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
+lz_enter_rr_str(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
uint16_t rr_class;
@@ -509,16 +490,16 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf)
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
if(!z) {
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
fatal_exit("internal error: no zone for rr %s", rr);
}
lock_rw_wrlock(&z->lock);
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
free(rr_name);
- r = lz_enter_rr_into_zone(z, buf, rr);
+ r = lz_enter_rr_into_zone(z, rr);
lock_rw_unlock(&z->lock);
return r;
}
@@ -549,13 +530,13 @@ lz_exists(struct local_zones* zones, const char* name)
log_err("bad name %s", name);
return 0;
}
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
if(rbtree_search(&zones->ztree, &z.node)) {
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
free(z.name);
return 1;
}
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
free(z.name);
return 0;
}
@@ -582,7 +563,7 @@ lz_nodefault(struct config_file* cfg, const char* name)
/** enter AS112 default zone */
static int
add_as112_default(struct local_zones* zones, struct config_file* cfg,
- ldns_buffer* buf, const char* name)
+ const char* name)
{
struct local_zone* z;
char str[1024]; /* known long enough */
@@ -592,12 +573,12 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
return 0;
snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800", name);
- if(!lz_enter_rr_into_zone(z, buf, str)) {
+ if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
- if(!lz_enter_rr_into_zone(z, buf, str)) {
+ if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
@@ -607,8 +588,7 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg,
/** enter default zones */
static int
-lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
- ldns_buffer* buf)
+lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
{
struct local_zone* z;
@@ -619,14 +599,14 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "localhost.")) {
if(!(z=lz_enter_zone(zones, "localhost.", "static",
LDNS_RR_CLASS_IN)) ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"localhost. 10800 IN NS localhost.") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"localhost. 10800 IN SOA localhost. nobody.invalid. "
"1 3600 1200 604800 10800") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"localhost. 10800 IN A 127.0.0.1") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"localhost. 10800 IN AAAA ::1")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@@ -639,12 +619,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "127.in-addr.arpa.")) {
if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN NS localhost.") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@@ -657,12 +637,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
- !lz_enter_rr_into_zone(z, buf,
+ !lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
@@ -670,37 +650,37 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
}
lock_rw_unlock(&z->lock);
}
- if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") ||
- !add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "8.e.f.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") ||
- !add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
+ if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "16.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "17.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "18.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "19.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "20.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "21.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "22.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "23.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "24.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "25.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "26.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "27.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "28.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "29.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "30.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "31.172.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "168.192.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "0.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "254.169.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") ||
+ !add_as112_default(zones, cfg, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "d.f.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") ||
+ !add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
@@ -713,7 +693,7 @@ init_parents(struct local_zones* zones)
{
struct local_zone* node, *prev = NULL, *p;
int m;
- lock_quick_lock(&zones->lock);
+ lock_rw_wrlock(&zones->lock);
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
lock_rw_wrlock(&node->lock);
node->parent = NULL;
@@ -738,7 +718,7 @@ init_parents(struct local_zones* zones)
prev = node;
lock_rw_unlock(&node->lock);
}
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
}
/** enter implicit transparent zone for local-data: without local-zone: */
@@ -768,7 +748,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) {
if(!have_name) {
dclass = rr_class;
@@ -783,7 +763,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
/* process other classes later */
free(rr_name);
have_other_classes = 1;
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
continue;
}
/* find smallest shared topdomain */
@@ -794,7 +774,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
match = m;
}
} else free(rr_name);
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
}
if(have_name) {
uint8_t* n2;
@@ -825,12 +805,11 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
/** enter auth data */
static int
-lz_enter_data(struct local_zones* zones, struct config_file* cfg,
- ldns_buffer* buf)
+lz_enter_data(struct local_zones* zones, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->local_data; p; p = p->next) {
- if(!lz_enter_rr_str(zones, p->str, buf))
+ if(!lz_enter_rr_str(zones, p->str))
return 0;
}
return 1;
@@ -851,35 +830,27 @@ lz_freeup_cfg(struct config_file* cfg)
int
local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
{
- ldns_buffer* buf = ldns_buffer_new(65535);
- if(!buf) fatal_exit("cannot create temporary buffer");
-
/* create zones from zone statements. */
if(!lz_enter_zones(zones, cfg)) {
- ldns_buffer_free(buf);
return 0;
}
/* apply default zones+content (unless disabled, or overridden) */
- if(!lz_enter_defaults(zones, cfg, buf)) {
- ldns_buffer_free(buf);
+ if(!lz_enter_defaults(zones, cfg)) {
return 0;
}
/* create implicit transparent zone from data. */
if(!lz_setup_implicit(zones, cfg)) {
- ldns_buffer_free(buf);
return 0;
}
/* setup parent ptrs for lookup during data entry */
init_parents(zones);
/* insert local data */
- if(!lz_enter_data(zones, cfg, buf)) {
- ldns_buffer_free(buf);
+ if(!lz_enter_data(zones, cfg)) {
return 0;
}
/* freeup memory from cfg struct. */
lz_freeup_cfg(cfg);
- ldns_buffer_free(buf);
return 1;
}
@@ -948,7 +919,7 @@ local_zone_out(struct local_zone* z)
void local_zones_print(struct local_zones* zones)
{
struct local_zone* z;
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
lock_rw_rdlock(&z->lock);
@@ -985,13 +956,13 @@ void local_zones_print(struct local_zones* zones)
local_zone_out(z);
lock_rw_unlock(&z->lock);
}
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
}
/** encode answer consisting of 1 rrset */
static int
local_encode(struct query_info* qinfo, struct edns_data* edns,
- ldns_buffer* buf, struct regional* temp,
+ sldns_buffer* buf, struct regional* temp,
struct ub_packed_rrset_key* rrset, int ansec, int rcode)
{
struct reply_info rep;
@@ -1011,20 +982,20 @@ local_encode(struct query_info* qinfo, struct edns_data* edns,
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!reply_info_answer_encode(qinfo, &rep,
- *(uint16_t*)ldns_buffer_begin(buf),
- ldns_buffer_read_u16_at(buf, 2),
+ *(uint16_t*)sldns_buffer_begin(buf),
+ sldns_buffer_read_u16_at(buf, 2),
buf, 0, 0, temp, udpsize, edns,
(int)(edns->bits&EDNS_DO), 0))
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
- *(uint16_t*)ldns_buffer_begin(buf),
- ldns_buffer_read_u16_at(buf, 2), edns);
+ *(uint16_t*)sldns_buffer_begin(buf),
+ sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
}
/** answer local data match */
static int
local_data_answer(struct local_zone* z, struct query_info* qinfo,
- struct edns_data* edns, ldns_buffer* buf, struct regional* temp,
+ struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
int labs, struct local_data** ldp)
{
struct local_data key;
@@ -1071,18 +1042,18 @@ local_data_answer(struct local_zone* z, struct query_info* qinfo,
*/
static int
lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
- struct edns_data* edns, ldns_buffer* buf, struct regional* temp,
+ struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
struct local_data* ld)
{
if(z->type == local_zone_deny) {
/** no reply at all, signal caller by clearing buffer. */
- ldns_buffer_clear(buf);
- ldns_buffer_flip(buf);
+ sldns_buffer_clear(buf);
+ sldns_buffer_flip(buf);
return 1;
} else if(z->type == local_zone_refuse) {
error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo,
- *(uint16_t*)ldns_buffer_begin(buf),
- ldns_buffer_read_u16_at(buf, 2), edns);
+ *(uint16_t*)sldns_buffer_begin(buf),
+ sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
} else if(z->type == local_zone_static ||
z->type == local_zone_redirect) {
@@ -1098,8 +1069,8 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
return local_encode(qinfo, edns, buf, temp,
z->soa, 0, rcode);
error_encode(buf, (rcode|BIT_AA), qinfo,
- *(uint16_t*)ldns_buffer_begin(buf),
- ldns_buffer_read_u16_at(buf, 2), edns);
+ *(uint16_t*)sldns_buffer_begin(buf),
+ sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
} else if(z->type == local_zone_typetransparent) {
/* no NODATA or NXDOMAINS for this zone type */
@@ -1115,8 +1086,8 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
return local_encode(qinfo, edns, buf, temp,
z->soa, 0, rcode);
error_encode(buf, (rcode|BIT_AA), qinfo,
- *(uint16_t*)ldns_buffer_begin(buf),
- ldns_buffer_read_u16_at(buf, 2), edns);
+ *(uint16_t*)sldns_buffer_begin(buf),
+ sldns_buffer_read_u16_at(buf, 2), edns);
return 1;
}
@@ -1126,7 +1097,7 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
int
local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
- struct edns_data* edns, ldns_buffer* buf, struct regional* temp)
+ struct edns_data* edns, sldns_buffer* buf, struct regional* temp)
{
/* see if query is covered by a zone,
* if so: - try to match (exact) local data
@@ -1135,15 +1106,15 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
struct local_data* ld;
struct local_zone* z;
int r;
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, qinfo->qname,
qinfo->qname_len, labs, qinfo->qclass);
if(!z) {
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
return 0;
}
lock_rw_rdlock(&z->lock);
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) {
lock_rw_unlock(&z->lock);
@@ -1255,7 +1226,7 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* z)
}
int
-local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
+local_zones_add_RR(struct local_zones* zones, const char* rr)
{
uint8_t* rr_name;
uint16_t rr_class;
@@ -1267,21 +1238,23 @@ local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
return 0;
}
labs = dname_count_size_labels(rr_name, &len);
- lock_quick_lock(&zones->lock);
+ /* could first try readlock then get writelock if zone does not exist,
+ * but we do not add enough RRs (from multiple threads) to optimize */
+ lock_rw_wrlock(&zones->lock);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
if(!z) {
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
local_zone_transparent);
if(!z) {
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
return 0;
}
} else {
free(rr_name);
}
lock_rw_wrlock(&z->lock);
- lock_quick_unlock(&zones->lock);
- r = lz_enter_rr_into_zone(z, buf, rr);
+ lock_rw_unlock(&zones->lock);
+ r = lz_enter_rr_into_zone(z, rr);
lock_rw_unlock(&z->lock);
return r;
}
@@ -1326,15 +1299,15 @@ void local_zones_del_data(struct local_zones* zones,
/* find zone */
struct local_zone* z;
struct local_data* d;
- lock_quick_lock(&zones->lock);
+ lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, name, len, labs, dclass);
if(!z) {
/* no such zone, we're done */
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
return;
}
lock_rw_wrlock(&z->lock);
- lock_quick_unlock(&zones->lock);
+ lock_rw_unlock(&zones->lock);
/* find the domain */
d = lz_find_node(z, name, len, labs);
diff --git a/services/localzone.h b/services/localzone.h
index 794988e66bb9..788fbfb3ba2b 100644
--- a/services/localzone.h
+++ b/services/localzone.h
@@ -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.
*/
/**
@@ -48,6 +48,7 @@ struct regional;
struct config_file;
struct edns_data;
struct query_info;
+struct sldns_buffer;
/**
* Local zone type
@@ -77,7 +78,7 @@ enum localzone_type {
*/
struct local_zones {
/** lock on the localzone tree */
- lock_quick_t lock;
+ lock_rw_t lock;
/** rbtree of struct local_zone */
rbtree_t ztree;
};
@@ -224,7 +225,7 @@ void local_zones_print(struct local_zones* zones);
* value is true, but the buffer is cleared (empty).
*/
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
- struct edns_data* edns, ldns_buffer* buf, struct regional* temp);
+ struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp);
/**
* Parse the string into localzone type.
@@ -286,11 +287,9 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* zone);
* name of the RR is created.
* @param zones: the zones tree. Not locked by caller.
* @param rr: string with on RR.
- * @param buf: buffer for scratch.
* @return false on failure.
*/
-int local_zones_add_RR(struct local_zones* zones, const char* rr,
- ldns_buffer* buf);
+int local_zones_add_RR(struct local_zones* zones, const char* rr);
/**
* Remove data from domain name in the tree.
diff --git a/services/mesh.c b/services/mesh.c
index a8cb115ab935..bc711d9b3ed6 100644
--- a/services/mesh.c
+++ b/services/mesh.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.
*/
/**
@@ -43,7 +43,6 @@
* send back to clients.
*/
#include "config.h"
-#include <ldns/wire2host.h>
#include "services/mesh.h"
#include "services/outbound_list.h"
#include "services/cache/dns.h"
@@ -56,6 +55,7 @@
#include "util/fptr_wlist.h"
#include "util/alloc.h"
#include "util/config_file.h"
+#include "ldns/sbuffer.h"
/** subtract timers and the values do not overflow or become negative */
static void
@@ -162,7 +162,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
return NULL;
}
mesh->histogram = timehist_setup();
- mesh->qbuf_bak = ldns_buffer_new(env->cfg->msg_buffer_size);
+ mesh->qbuf_bak = sldns_buffer_new(env->cfg->msg_buffer_size);
if(!mesh->histogram || !mesh->qbuf_bak) {
free(mesh);
log_err("mesh area alloc: out of memory");
@@ -210,7 +210,7 @@ mesh_delete(struct mesh_area* mesh)
while(mesh->all.count)
mesh_delete_helper(mesh->all.root);
timehist_delete(mesh->histogram);
- ldns_buffer_free(mesh->qbuf_bak);
+ sldns_buffer_free(mesh->qbuf_bak);
free(mesh);
}
@@ -234,7 +234,7 @@ mesh_delete_all(struct mesh_area* mesh)
mesh->jostle_last = NULL;
}
-int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf)
+int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
{
struct mesh_state* m = mesh->jostle_first;
/* free space is available */
@@ -253,7 +253,7 @@ int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf)
m->s.qinfo.qname, m->s.qinfo.qtype,
m->s.qinfo.qclass);
/* backup the query */
- if(qbuf) ldns_buffer_copy(mesh->qbuf_bak, qbuf);
+ if(qbuf) sldns_buffer_copy(mesh->qbuf_bak, qbuf);
/* notify supers */
if(m->super_set.count > 0) {
verbose(VERB_ALGO, "notify supers of failure");
@@ -265,7 +265,7 @@ int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf)
mesh_state_delete(&m->s);
/* restore the query - note that the qinfo ptr to
* the querybuffer is then correct again. */
- if(qbuf) ldns_buffer_copy(qbuf, mesh->qbuf_bak);
+ if(qbuf) sldns_buffer_copy(qbuf, mesh->qbuf_bak);
return 1;
}
}
@@ -372,7 +372,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
int
mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
- uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
+ uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
{
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
@@ -800,7 +800,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
} else {
size_t udp_size = r->edns.udp_size;
- ldns_buffer_clear(r->buf);
+ sldns_buffer_clear(r->buf);
r->edns.edns_version = EDNS_ADVERTISED_VERSION;
r->edns.udp_size = EDNS_ADVERTISED_SIZE;
r->edns.ext_rcode = 0;
@@ -858,11 +858,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
prev->edns.udp_size == r->edns.udp_size) {
/* if the previous reply is identical to this one, fix ID */
if(prev->query_reply.c->buffer != r->query_reply.c->buffer)
- ldns_buffer_copy(r->query_reply.c->buffer,
+ sldns_buffer_copy(r->query_reply.c->buffer,
prev->query_reply.c->buffer);
- ldns_buffer_write_at(r->query_reply.c->buffer, 0,
+ sldns_buffer_write_at(r->query_reply.c->buffer, 0,
&r->qid, sizeof(uint16_t));
- ldns_buffer_write_at(r->query_reply.c->buffer, 12,
+ sldns_buffer_write_at(r->query_reply.c->buffer, 12,
r->qname, m->s.qinfo.qname_len);
comm_point_send_reply(&r->query_reply);
} else if(rcode) {
@@ -892,17 +892,17 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
m->s.env->mesh->num_reply_addrs--;
end_time = *m->s.env->now_tv;
timeval_subtract(&duration, &end_time, &r->start_time);
- verbose(VERB_ALGO, "query took %lld.%6.6d sec",
+ verbose(VERB_ALGO, "query took " ARG_LL "d.%6.6d sec",
(long long)duration.tv_sec, (int)duration.tv_usec);
m->s.env->mesh->replies_sent++;
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
timehist_insert(m->s.env->mesh->histogram, &duration);
if(m->s.env->cfg->stat_extended) {
- uint16_t rc = FLAGS_GET_RCODE(ldns_buffer_read_u16_at(r->
+ uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(r->
query_reply.c->buffer, 2));
if(secure) m->s.env->mesh->ans_secure++;
m->s.env->mesh->ans_rcode[ rc ] ++;
- if(rc == 0 && LDNS_ANCOUNT(ldns_buffer_begin(r->
+ if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r->
query_reply.c->buffer)) == 0)
m->s.env->mesh->ans_nodata++;
}
@@ -956,7 +956,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
}
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
- ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg,
+ sldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg,
uint16_t qid, uint16_t qflags)
{
struct mesh_cb* r = regional_alloc(s->s.region,
@@ -1138,7 +1138,8 @@ mesh_stats(struct mesh_area* mesh, const char* str)
timeval_divide(&avg, &mesh->replies_sum_wait,
mesh->replies_sent);
log_info("average recursion processing time "
- "%lld.%6.6d sec", (long long)avg.tv_sec, (int)avg.tv_usec);
+ ARG_LL "d.%6.6d sec",
+ (long long)avg.tv_sec, (int)avg.tv_usec);
log_info("histogram of recursion processing times");
timehist_log(mesh->histogram, "recursions");
}
@@ -1167,7 +1168,7 @@ mesh_get_mem(struct mesh_area* mesh)
struct mesh_state* m;
size_t s = sizeof(*mesh) + sizeof(struct timehist) +
sizeof(struct th_buck)*mesh->histogram->num +
- sizeof(ldns_buffer) + ldns_buffer_capacity(mesh->qbuf_bak);
+ sizeof(sldns_buffer) + sldns_buffer_capacity(mesh->qbuf_bak);
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
/* all, including m itself allocated in qstate region */
s += regional_get_mem(m->s.region);
diff --git a/services/mesh.h b/services/mesh.h
index 54a3cafecc9e..fbfbbcb4a94b 100644
--- a/services/mesh.h
+++ b/services/mesh.h
@@ -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.
*/
/**
@@ -51,6 +51,7 @@
#include "util/data/msgparse.h"
#include "util/module.h"
#include "services/modstack.h"
+struct sldns_buffer;
struct mesh_state;
struct mesh_reply;
struct mesh_cb;
@@ -125,7 +126,7 @@ struct mesh_area {
/** backup of query if other operations recurse and need the
* network buffers */
- ldns_buffer* qbuf_bak;
+ struct sldns_buffer* qbuf_bak;
/** double linked list of the run-to-completion query states.
* These are query states with a reply */
@@ -219,7 +220,7 @@ struct mesh_reply {
* Mesh result callback func.
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
*/
-typedef void (*mesh_cb_func_t)(void*, int, ldns_buffer*, enum sec_status,
+typedef void (*mesh_cb_func_t)(void*, int, struct sldns_buffer*, enum sec_status,
char*);
/**
@@ -235,7 +236,7 @@ struct mesh_cb {
/** flags of query, for reply flags */
uint16_t qflags;
/** buffer for reply */
- ldns_buffer* buf;
+ struct sldns_buffer* buf;
/** callback routine for results. if rcode != 0 buf has message.
* called as cb(cb_arg, rcode, buf, sec_state);
@@ -294,7 +295,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
* @return 0 on error.
*/
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
- uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
+ uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf,
uint16_t qid, mesh_cb_func_t cb, void* cb_arg);
/**
@@ -473,7 +474,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
* @return: 0 on alloc error.
*/
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
- ldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
+ struct sldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid,
uint16_t qflags);
/**
@@ -548,7 +549,7 @@ int mesh_state_ref_compare(const void* ap, const void* bp);
* You can pass NULL if there is no buffer that must be backed up.
* @return false if no space is available.
*/
-int mesh_make_new_space(struct mesh_area* mesh, ldns_buffer* qbuf);
+int mesh_make_new_space(struct mesh_area* mesh, struct sldns_buffer* qbuf);
/**
* Insert mesh state into a double linked list. Inserted at end.
diff --git a/services/modstack.c b/services/modstack.c
index 7395598c31cd..56515a61f369 100644
--- a/services/modstack.c
+++ b/services/modstack.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.
*/
/**
diff --git a/services/modstack.h b/services/modstack.h
index 869b593ad264..cb8613299abb 100644
--- a/services/modstack.h
+++ b/services/modstack.h
@@ -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.
*/
/**
diff --git a/services/outbound_list.c b/services/outbound_list.c
index be491490411d..ad73380bcf81 100644
--- a/services/outbound_list.c
+++ b/services/outbound_list.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.
*/
/**
diff --git a/services/outbound_list.h b/services/outbound_list.h
index 5631910f6f8c..ad59e42d1929 100644
--- a/services/outbound_list.h
+++ b/services/outbound_list.h
@@ -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.
*/
/**
diff --git a/services/outside_network.c b/services/outside_network.c
index 373d8f353688..fedbd0fa8c8e 100644
--- a/services/outside_network.c
+++ b/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);
@@ -1312,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;
@@ -1346,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);
}
}
@@ -1359,7 +1393,7 @@ 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;
@@ -1399,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)
@@ -1463,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",
@@ -1474,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");
@@ -1484,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) {
@@ -1497,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;
@@ -1510,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);
@@ -1541,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;
@@ -1550,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 */
@@ -1599,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":"");
@@ -1618,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;
@@ -1697,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;
@@ -1732,9 +1766,9 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
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 */
@@ -1773,7 +1807,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
} /* 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 ||
@@ -1796,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;
@@ -1925,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);
diff --git a/services/outside_network.h b/services/outside_network.h
index 87fe8ff108de..dda9d6f5a235 100644
--- a/services/outside_network.h
+++ b/services/outside_network.h
@@ -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.
*/
/**
@@ -54,6 +54,7 @@ struct waiting_udp;
struct infra_cache;
struct port_comm;
struct port_if;
+struct sldns_buffer;
/**
* Send queries to outside servers and wait for answers from servers.
@@ -69,7 +70,7 @@ struct outside_network {
/** buffer shared by UDP connections, since there is only one
datagram at any time. */
- ldns_buffer* udp_buff;
+ struct sldns_buffer* udp_buff;
/** serviced_callbacks malloc overhead when processing multiple
* identical serviced queries to the same server. */
size_t svcd_overhead;
@@ -94,6 +95,10 @@ struct outside_network {
struct port_comm* unused_fds;
/** if udp is done */
int do_udp;
+ /** if udp is delay-closed (delayed answers do not meet closed port)*/
+ int delayclose;
+ /** timeout for delayclose */
+ struct timeval delay_tv;
/** array of outgoing IP4 interfaces */
struct port_if* ip4_ifs;
@@ -376,6 +381,8 @@ struct serviced_query {
* @param unwanted_param: user parameter to action.
* @param do_udp: if udp is done.
* @param sslctx: context to create outgoing connections with (if enabled).
+ * @param delayclose: if not 0, udp sockets are delayed before timeout closure.
+ * msec to wait on timeouted udp sockets.
* @return: the new structure (with no pending answers) or NULL on error.
*/
struct outside_network* outside_network_create(struct comm_base* base,
@@ -384,7 +391,7 @@ struct outside_network* outside_network_create(struct comm_base* base,
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);
/**
* Delete outside_network structure.
@@ -411,7 +418,7 @@ void outside_network_quit_prepare(struct outside_network* outnet);
* @return: NULL on error for malloc or socket. Else the pending query object.
*/
struct pending* pending_udp_query(struct outside_network* outnet,
- ldns_buffer* packet, struct sockaddr_storage* addr,
+ struct sldns_buffer* packet, struct sockaddr_storage* addr,
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
void* callback_arg);
@@ -431,7 +438,7 @@ struct pending* pending_udp_query(struct outside_network* outnet,
* @return: false on error for malloc or socket. Else the pending TCP object.
*/
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet,
- ldns_buffer* packet, struct sockaddr_storage* addr,
+ struct sldns_buffer* packet, struct sockaddr_storage* addr,
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
void* callback_arg, int ssl_upstream);
@@ -476,7 +483,7 @@ struct serviced_query* 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, struct sldns_buffer* buff);
/**
* Remove service query callback.
@@ -515,6 +522,9 @@ int outnet_tcp_cb(struct comm_point* c, void* arg, int error,
/** callback for udp timeout */
void pending_udp_timer_cb(void *arg);
+/** callback for udp delay for timeout */
+void pending_udp_timer_delay_cb(void *arg);
+
/** callback for outgoing TCP timer event */
void outnet_tcptimer(void* arg);