]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
auth zone move file descriptor functionality to outside network
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2018 14:59:17 +0000 (14:59 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 31 Jan 2018 14:59:17 +0000 (14:59 +0000)
for the unit test

git-svn-id: file:///svn/unbound/trunk@4482 be551aaa-1e26-0410-a405-d3ace91eadb9

services/authzone.c
services/outside_network.c
services/outside_network.h
testcode/fake_event.c

index b391eb24c1e7743637f25614c6a4aec62539b01a..6efe2e1f8acd62b1597acda2351918f4da137d61 100644 (file)
@@ -3399,67 +3399,6 @@ xfr_probe_nextmaster(struct auth_xfer* xfr)
        return;
 }
 
-/** create fd to send to this master */
-static int
-xfr_fd_for_master(struct module_env* env, struct sockaddr_storage* to_addr,
-       socklen_t to_addrlen, char* host)
-{
-       struct sockaddr_storage* addr;
-       socklen_t addrlen;
-       int i;
-       int try;
-
-       /* select interface */
-       if(addr_is_ip6(to_addr, to_addrlen)) {
-               if(env->outnet->num_ip6 == 0) {
-                       verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", host);
-                       return -1;
-               }
-               i = ub_random_max(env->rnd, env->outnet->num_ip6);
-               addr = &env->outnet->ip6_ifs[i].addr;
-               addrlen = env->outnet->ip6_ifs[i].addrlen;
-       } else {
-               if(env->outnet->num_ip4 == 0) {
-                       verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", host);
-                       return -1;
-               }
-               i = ub_random_max(env->rnd, env->outnet->num_ip4);
-               addr = &env->outnet->ip4_ifs[i].addr;
-               addrlen = env->outnet->ip4_ifs[i].addrlen;
-       }
-
-       /* create fd */
-       for(try = 0; try<1000; try++) {
-               int freebind = 0;
-               int noproto = 0;
-               int inuse = 0;
-               int port = ub_random(env->rnd)&0xffff;
-               int fd = -1;
-               if(addr_is_ip6(to_addr, to_addrlen)) {
-                       struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
-                       sa.sin6_port = (in_port_t)htons((uint16_t)port);
-                       fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
-                               (struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
-                               0, 0, 0, NULL, 0, freebind, 0);
-               } 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*)&sa, addrlen, 1, &inuse, &noproto,
-                               0, 0, 0, NULL, 0, freebind, 0);
-               }
-               if(fd != -1) {
-                       return fd;
-               }
-               if(!inuse) {
-                       return -1;
-               }
-       }
-       /* too many tries */
-       log_err("cannot send probe, ports are in use");
-       return -1;
-}
-
 /** create SOA probe packet for xfr */
 static void
 xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf, 
@@ -4103,47 +4042,23 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
                xfr->task_transfer->cp = NULL;
        }
 
-       /* connect on fd */
-       if(!xfr->task_transfer->cp) {
-               int fd = outnet_get_tcp_fd(&addr, addrlen, env->cfg->tcp_mss);
-               if(fd == -1) {
-                       char zname[255+1];
-                       dname_str(xfr->name, zname);
-                       verbose(VERB_ALGO, "cannot create fd for "
-                               "xfr %s to %s", zname, master->host);
-                       return 0;
-               }
-               fd_set_nonblock(fd);
-               if(!outnet_tcp_connect(fd, &addr, addrlen)) {
-                       /* outnet_tcp_connect has closed fd on error for us */
-                       char zname[255+1];
-                       dname_str(xfr->name, zname);
-                       verbose(VERB_ALGO, "cannot tcp connect() for"
-                               "xfr %s to %s", zname, master->host);
-                       return 0;
-               }
-
-               xfr->task_transfer->cp = comm_point_create_tcp_out(
-                       env->worker_base, 65552,
-                       auth_xfer_transfer_tcp_callback, xfr);
-               if(!xfr->task_transfer->cp) {
-                       close(fd);
-                       log_err("malloc failure");
-                       return 0;
-               }
-               xfr->task_transfer->cp->repinfo.addrlen = addrlen;
-               memcpy(&xfr->task_transfer->cp->repinfo.addr, &addr, addrlen);
-               /* set timeout on TCP connection */
-               comm_point_start_listening(xfr->task_transfer->cp, fd,
-                       AUTH_TRANSFER_TIMEOUT);
-       }
-
        /* set the packet to be written */
        /* create new ID */
        xfr->task_transfer->id = (uint16_t)(ub_random(env->rnd)&0xffff);
-       xfr_create_ixfr_packet(xfr, xfr->task_transfer->cp->buffer,
+       xfr_create_ixfr_packet(xfr, env->scratch_buffer,
                xfr->task_transfer->id);
 
+       /* connect on fd */
+       xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
+               auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen,
+               env->scratch_buffer, AUTH_TRANSFER_TIMEOUT);
+       if(!xfr->task_transfer->cp) {
+               char zname[255+1];
+               dname_str(xfr->name, zname);
+               verbose(VERB_ALGO, "cannot create tcp cp connection for "
+                       "xfr %s to %s", zname, master->host);
+               return 0;
+       }
        return 1;
 }
 
@@ -4750,22 +4665,15 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
        xfr_create_soa_probe_packet(xfr, env->scratch_buffer, 
                xfr->task_probe->id);
        if(!xfr->task_probe->cp) {
-               int fd = xfr_fd_for_master(env, &addr, addrlen, master->host);
-               if(fd == -1) {
+               xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
+                       auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
+               if(!xfr->task_probe->cp) {
                        char zname[255+1];
                        dname_str(xfr->name, zname);
-                       verbose(VERB_ALGO, "cannot create fd for "
+                       verbose(VERB_ALGO, "cannot create udp cp for "
                                "probe %s to %s", zname, master->host);
                        return 0;
                }
-               xfr->task_probe->cp = comm_point_create_udp(env->worker_base,
-                       fd, env->outnet->udp_buff, auth_xfer_probe_udp_callback,
-                       xfr);
-               if(!xfr->task_probe->cp) {
-                       close(fd);
-                       log_err("malloc failure");
-                       return 0;
-               }
        }
        if(!xfr->task_probe->timer) {
                xfr->task_probe->timer = comm_timer_create(env->worker_base,
index 1e4059888b9522cd677cb68792216d558e9447f1..bda2fa12edff3be25236912cc4f5977f8c68fc6e 100644 (file)
@@ -2140,6 +2140,122 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
        }
 }
 
+/** create fd to send to this destination */
+static int
+fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
+       socklen_t to_addrlen)
+{
+       struct sockaddr_storage* addr;
+       socklen_t addrlen;
+       int i;
+       int try;
+
+       /* select interface */
+       if(addr_is_ip6(to_addr, to_addrlen)) {
+               if(outnet->num_ip6 == 0) {
+                       char to[64];
+                       addr_to_str(to_addr, to_addrlen, to, sizeof(to));
+                       verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
+                       return -1;
+               }
+               i = ub_random_max(outnet->rnd, outnet->num_ip6);
+               addr = &outnet->ip6_ifs[i].addr;
+               addrlen = outnet->ip6_ifs[i].addrlen;
+       } else {
+               if(outnet->num_ip4 == 0) {
+                       char to[64];
+                       addr_to_str(to_addr, to_addrlen, to, sizeof(to));
+                       verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
+                       return -1;
+               }
+               i = ub_random_max(outnet->rnd, outnet->num_ip4);
+               addr = &outnet->ip4_ifs[i].addr;
+               addrlen = outnet->ip4_ifs[i].addrlen;
+       }
+
+       /* create fd */
+       for(try = 0; try<1000; try++) {
+               int freebind = 0;
+               int noproto = 0;
+               int inuse = 0;
+               int port = ub_random(outnet->rnd)&0xffff;
+               int fd = -1;
+               if(addr_is_ip6(to_addr, to_addrlen)) {
+                       struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
+                       sa.sin6_port = (in_port_t)htons((uint16_t)port);
+                       fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
+                               (struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
+                               0, 0, 0, NULL, 0, freebind, 0);
+               } 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*)&sa, addrlen, 1, &inuse, &noproto,
+                               0, 0, 0, NULL, 0, freebind, 0);
+               }
+               if(fd != -1) {
+                       return fd;
+               }
+               if(!inuse) {
+                       return -1;
+               }
+       }
+       /* too many tries */
+       log_err("cannot send probe, ports are in use");
+       return -1;
+}
+
+struct comm_point*
+outnet_comm_point_for_udp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen)
+{
+       struct comm_point* cp;
+       int fd = fd_for_dest(outnet, to_addr, to_addrlen);
+       if(fd == -1) {
+               return NULL;
+       }
+       cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
+               cb, cb_arg);
+       if(!cp) {
+               log_err("malloc failure");
+               close(fd);
+               return NULL;
+       }
+       return cp;
+}
+
+struct comm_point*
+outnet_comm_point_for_tcp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen,
+       sldns_buffer* query, int timeout)
+{
+       struct comm_point* cp;
+       int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
+       if(fd == -1) {
+               return 0;
+       }
+       fd_set_nonblock(fd);
+       if(!outnet_tcp_connect(fd, to_addr, to_addrlen)) {
+               /* outnet_tcp_connect has closed fd on error for us */
+               return 0;
+       }
+       cp = comm_point_create_tcp_out(outnet->base, 65552, cb, cb_arg);
+       if(!cp) {
+               log_err("malloc failure");
+               close(fd);
+               return 0;
+       }
+       cp->repinfo.addrlen = to_addrlen;
+       memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
+       /* set timeout on TCP connection */
+       comm_point_start_listening(cp, fd, timeout);
+       /* copy scratch buffer to cp->buffer */
+       sldns_buffer_copy(cp->buffer, query);
+       return cp;
+}
+
 /** get memory used by waiting tcp entry (in use or not) */
 static size_t
 waiting_tcp_get_mem(struct waiting_tcp* w)
index 04e89a0b7fe3a3ceb3097917f8a0606753cf9819..674acff9a608c4e7a182025c307e567c0399e435 100644 (file)
@@ -537,6 +537,41 @@ size_t serviced_get_mem(struct serviced_query* sq);
  * tcp_mss is 0 or maxseg size to set for TCP packets. */
 int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss);
 
+/**
+ * Create udp commpoint suitable for sending packets to the destination.
+ * @param outnet: outside_network with the comm_base it is attached to,
+ *     with the outgoing interfaces chosen from, and rnd gen for random.
+ * @param cb: callback function for the commpoint.
+ * @param cb_arg: callback argument for cb.
+ * @param to_addr: intended destination.
+ * @param to_addrlen: length of to_addr.
+ * @return commpoint that you can comm_point_send_udp_msg with, or NULL.
+ */
+struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen);
+
+/**
+ * Create tcp commpoint suitable for communication to the destination.
+ * It also performs connect() to the to_addr.
+ * @param outnet: outside_network with the comm_base it is attached to,
+ *     and the tcp_mss.
+ * @param cb: callback function for the commpoint.
+ * @param cb_arg: callback argument for cb.
+ * @param to_addr: intended destination.
+ * @param to_addrlen: length of to_addr.
+ * @param query: initial packet to send writing, in buffer.  It is copied
+ *     to the commpoint buffer that is created.
+ * @param timeout: timeout for the TCP connection.
+ *     timeout in milliseconds, or -1 for no (change to the) timeout.
+ *     So seconds*1000.
+ * @return commpoint that you can comm_point_send_udp_msg with, or NULL.
+ */
+struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen,
+       struct sldns_buffer* query, int timeout);
+
 /** connect tcp connection to addr, 0 on failure */
 int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
 
index cb7167477a4dde8bb2eccb2ff037c464f75b8bf4..e999896ece8bb4daf37522f05ceb32574f45275f 100644 (file)
@@ -1437,7 +1437,6 @@ struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
        comm_point_callback_type* ATTR_UNUSED(callback),
        void* ATTR_UNUSED(callback_arg))
 {
-       /* could create a test framework; and intercept eg. authzone probes */
        return NULL;
 }
 
@@ -1445,8 +1444,38 @@ struct comm_point* comm_point_create_tcp_out(struct comm_base*
        ATTR_UNUSED(base), size_t ATTR_UNUSED(bufsize),
        comm_point_callback_type* ATTR_UNUSED(callback),
        void* ATTR_UNUSED(callback_arg))
+{
+       return NULL;
+}
+
+struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen)
+{
+       /* used by authzone transfers */
+       (void)outnet;
+       (void)cb;
+       (void)cb_arg;
+       (void)to_addr;
+       (void)to_addrlen;
+       /* TODO */
+       return NULL;
+}
+
+struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
+       comm_point_callback_type* cb, void* cb_arg,
+       struct sockaddr_storage* to_addr, socklen_t to_addrlen,
+       struct sldns_buffer* query, int timeout)
 {
        /* used by authzone transfers */
+       (void)outnet;
+       (void)cb;
+       (void)cb_arg;
+       (void)to_addr;
+       (void)to_addrlen;
+       (void)query;
+       (void)timeout;
+       /* TODO */
        return NULL;
 }