]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- authzone work, transfer connect.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 12 Dec 2017 15:39:45 +0000 (15:39 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 12 Dec 2017 15:39:45 +0000 (15:39 +0000)
git-svn-id: file:///svn/unbound/trunk@4420 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index 71aa945c7fc067d9af2c8e41f02ac976b5afc37b..46df1780d1f37f8d4bc4513c03db7aff34685274 100644 (file)
@@ -1,6 +1,9 @@
 12 December 2017: Ralph
        - Fix qname-minimisation documentation (A QTYPE, not NS)
 
+12 December 2017: Wouter
+       - authzone work, transfer connect.
+
 7 December 2017: Ralph
        - Check whether --with-libunbound-only is set when using --with-nettle
          or --with-nss.
index 819b8bb1937dee32599c0e49a83605cd17b873a2..4eb6a69ca46a677c3249c6192dba924037c459a0 100644 (file)
@@ -3317,10 +3317,15 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
                }
        }
 
-       /* always new cp? TODO */
-       /* TODO: set REUSEADDR and tcp nonblock, and call connect on fd */
+       /* remove previous TCP connection (if any) */
+       if(xfr->task_transfer->cp) {
+               comm_point_delete(xfr->task_transfer->cp);
+               xfr->task_transfer->cp = NULL;
+       }
+
+       /* connect on fd */
        if(!xfr->task_transfer->cp) {
-               int fd = xfr_fd_for_master(env, &addr, addrlen, master->host);
+               int fd = outnet_get_tcp_fd(&addr, addrlen, env->cfg->tcp_mss);
                if(fd == -1) {
                        char zname[255+1];
                        dname_str(xfr->name, zname);
@@ -3328,6 +3333,16 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
                                "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);
@@ -3339,9 +3354,6 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
                /* set timeout on TCP connection */
                comm_point_start_listening(xfr->task_transfer->cp, fd,
                        AUTH_TRANSFER_TIMEOUT);
-       } else {
-               comm_point_start_listening(xfr->task_transfer->cp, -1,
-                       AUTH_TRANSFER_TIMEOUT);
        }
 
        /* set the packet to be written */
@@ -3486,13 +3498,28 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
        struct module_env* env;
        log_assert(xfr->task_probe);
        env = xfr->task_probe->env;
-
-       /* TODO */
-       (void)xfr;
-       (void)env;
        (void)repinfo;
-       (void)c;
-       (void)err;
+
+       if(err != NETEVENT_NOERROR) {
+               /* connection failed, closed, or timeout */
+               /* stop this transfer, cleanup 
+                * and continue task_transfer*/
+               verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
+                       xfr->task_transfer->master->host);
+               comm_point_close(c);
+               xfr_transfer_nexttarget_or_end(xfr, env);
+               return 0;
+       }
+
+       /* TODO: handle returned packet */
+       /* if it fails, cleanup and end this transfer */
+       /* if it needs to fallback from IXFR to AXFR, do that */
+       /* if it is good, link it into the list of data */
+
+       /* if we want to read more messages, setup the commpoint to read
+        * a DNS packet, and the timeout */
+       c->tcp_is_reading = 1;
+       comm_point_start_listening(c, -1, AUTH_TRANSFER_TIMEOUT);
        return 0;
 }
 
index ec9e11a0e7af143973c9ab8c4b5cb46ac61794e3..1e4059888b9522cd677cb68792216d558e9447f1 100644 (file)
@@ -198,21 +198,17 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
        return 1;
 }
 
-/** use next free buffer to service a tcp query */
-static int
-outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
+/** get TCP file descriptor for address, returns -1 on failure,
+ * 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)
 {
-       struct pending_tcp* pend = w->outnet->tcp_free;
        int s;
 #ifdef SO_REUSEADDR
        int on = 1;
 #endif
-       log_assert(pend);
-       log_assert(pkt);
-       log_assert(w->addrlen > 0);
-       /* open socket */
 #ifdef INET6
-       if(addr_is_ip6(&w->addr, w->addrlen))
+       if(addr_is_ip6(addr, addrlen))
                s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
        else
 #endif
@@ -220,12 +216,12 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
        if(s == -1) {
 #ifndef USE_WINSOCK
                log_err_addr("outgoing tcp: socket", strerror(errno),
-                       &w->addr, w->addrlen);
+                       addr, addrlen);
 #else
                log_err_addr("outgoing tcp: socket", 
-                       wsa_strerror(WSAGetLastError()), &w->addr, w->addrlen);
+                       wsa_strerror(WSAGetLastError()), addr, addrlen);
 #endif
-               return 0;
+               return -1;
        }
 
 #ifdef SO_REUSEADDR
@@ -235,11 +231,11 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
                        " setsockopt(.. SO_REUSEADDR ..) failed");
        }
 #endif
-       if (w->outnet->tcp_mss > 0) {
+
+       if(tcp_mss > 0) {
 #if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
                if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
-                       (void*)&w->outnet->tcp_mss,
-                       (socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {
+                       (void*)&tcp_mss, (socklen_t)sizeof(tcp_mss)) < 0) {
                        verbose(VERB_ALGO, "outgoing tcp:"
                                " setsockopt(.. TCP_MAXSEG ..) failed");
                }
@@ -249,6 +245,49 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
 #endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
        }
 
+       return s;
+}
+
+/** connect tcp connection to addr, 0 on failure */
+int
+outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen)
+{
+       if(connect(s, (struct sockaddr*)addr, addrlen) == -1) {
+#ifndef USE_WINSOCK
+#ifdef EINPROGRESS
+               if(errno != EINPROGRESS) {
+#endif
+                       if(tcp_connect_errno_needs_log(
+                               (struct sockaddr*)addr, addrlen))
+                               log_err_addr("outgoing tcp: connect",
+                                       strerror(errno), addr, addrlen);
+                       close(s);
+#ifdef EINPROGRESS
+               }
+#endif
+#else /* USE_WINSOCK */
+               if(WSAGetLastError() != WSAEINPROGRESS &&
+                       WSAGetLastError() != WSAEWOULDBLOCK) {
+                       closesocket(s);
+               }
+#endif
+               return 0;
+       }
+       return 1;
+}
+
+/** use next free buffer to service a tcp query */
+static int
+outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
+{
+       struct pending_tcp* pend = w->outnet->tcp_free;
+       int s;
+       log_assert(pend);
+       log_assert(pkt);
+       log_assert(w->addrlen > 0);
+       /* open socket */
+       s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
+
        if(!pick_outgoing_tcp(w, s))
                return 0;
 
index befd512f0dad01a7bf90102caa0052673f1f0fe5..04e89a0b7fe3a3ceb3097917f8a0606753cf9819 100644 (file)
@@ -533,6 +533,13 @@ size_t outnet_get_mem(struct outside_network* outnet);
  */
 size_t serviced_get_mem(struct serviced_query* sq);
 
+/** get TCP file descriptor for address, returns -1 on failure,
+ * 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);
+
+/** connect tcp connection to addr, 0 on failure */
+int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
+
 /** callback for incoming udp answers from the network */
 int outnet_udp_cb(struct comm_point* c, void* arg, int error,
        struct comm_reply *reply_info);
index 48ca36357652df4e239d3862f81d0aede4018dce..cb7167477a4dde8bb2eccb2ff037c464f75b8bf4 100644 (file)
@@ -1458,4 +1458,16 @@ int comm_point_send_udp_msg(struct comm_point *ATTR_UNUSED(c),
        return 0;
 }
 
+int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
+       socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss))
+{
+       return -1;
+}
+
+int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(addr),
+       socklen_t ATTR_UNUSED(addrlen))
+{
+       return 0;
+}
+
 /*********** End of Dummy routines ***********/