]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix error cases when udp-connect is set and send() returns an error
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 16 Dec 2020 16:11:41 +0000 (17:11 +0100)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 16 Dec 2020 16:11:41 +0000 (17:11 +0100)
  (modified patch from Xin Li @delphij).

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

index 07a8e6ea4e95b79536bfa67919a49cdd4ad3e594..3b831fea1893b2488d4f8ca5ddc52be5bef8b46c 100644 (file)
@@ -1,3 +1,7 @@
+16 December 2020: George
+       - Fix error cases when udp-connect is set and send() returns an error
+         (modified patch from Xin Li @delphij).
+
 11 December 2020: Wouter
        - Fix #371: unbound-control timeout when Unbound is not running.
        - Fix to squelch permission denied and other errors from remote host,
index 15be5d60c653283a910abedfc0973b838bd3565c..e59548fc3198aedb42c2725a2a11111d73d9f693 100644 (file)
@@ -6093,7 +6093,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
 
        /* send udp packet */
        if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
-               (struct sockaddr*)&addr, addrlen)) {
+               (struct sockaddr*)&addr, addrlen, 0)) {
                char zname[255+1], as[256];
                dname_str(xfr->name, zname);
                addr_to_str(&addr, addrlen, as, sizeof(as));
index 0886907f7c886ac2151491adea493101b88ab606..d8f9874e62a4a736532881c485579c4d96120cb2 100644 (file)
@@ -1899,17 +1899,10 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout)
        log_assert(pend->pc && pend->pc->cp);
 
        /* send it over the commlink */
-       if(outnet->udp_connect) {
-               if(!comm_point_send_udp_msg(pend->pc->cp, packet, NULL, 0)) {
-                       portcomm_loweruse(outnet, pend->pc);
-                       return 0;
-               }
-       } else {
-               if(!comm_point_send_udp_msg(pend->pc->cp, packet,
-                       (struct sockaddr*)&pend->addr, pend->addrlen)) {
-                       portcomm_loweruse(outnet, pend->pc);
-                       return 0;
-               }
+       if(!comm_point_send_udp_msg(pend->pc->cp, packet,
+               (struct sockaddr*)&pend->addr, pend->addrlen, outnet->udp_connect)) {
+               portcomm_loweruse(outnet, pend->pc);
+               return 0;
        }
 
        /* system calls to set timeout after sending UDP to make roundtrip
index 75a6b8db93185dd473e4f4e05311166a5b13eec3..5164332c04f758983c08cce64699fe0590e7f205 100644 (file)
@@ -1766,7 +1766,7 @@ struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
 }
 
 int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
-       struct sockaddr* addr, socklen_t addrlen
+       struct sockaddr* addr, socklen_t addrlen, int ATTR_UNUSED(is_connected))
 {
        struct fake_commpoint* fc = (struct fake_commpoint*)c;
        struct replay_runtime* runtime = fc->runtime;
index 7c6da50becd8c05c7a2e18a4b0f7ed18e81690af..88be007e7603f0860b39a0a1e4aa12008c0af472 100644 (file)
@@ -333,7 +333,7 @@ int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen)
 /* send a UDP reply */
 int
 comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
-       struct sockaddr* addr, socklen_t addrlen
+       struct sockaddr* addr, socklen_t addrlen, int is_connected)
 {
        ssize_t sent;
        log_assert(c->fd != -1);
@@ -341,8 +341,8 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
        if(sldns_buffer_remaining(packet) == 0)
                log_err("error: send empty UDP packet");
 #endif
-       if(addr) {
-               log_assert(addr && addrlen > 0);
+       log_assert(addr && addrlen > 0);
+       if(!is_connected) {
                sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
                        sldns_buffer_remaining(packet), 0,
                        addr, addrlen);
@@ -367,9 +367,14 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
 #endif
                        int e;
                        fd_set_block(c->fd);
-                       sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), 
-                               sldns_buffer_remaining(packet), 0,
-                               addr, addrlen);
+                       if (!is_connected) {
+                               sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
+                                       sldns_buffer_remaining(packet), 0,
+                                       addr, addrlen);
+                       } else {
+                               sent = send(c->fd, (void*)sldns_buffer_begin(packet),
+                                       sldns_buffer_remaining(packet), 0);
+                       }
                        e = errno;
                        fd_set_nonblock(c->fd);
                        errno = e;
@@ -378,8 +383,12 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
        if(sent == -1) {
                if(!udp_send_errno_needs_log(addr, addrlen))
                        return 0;
-               verbose(VERB_OPS, "sendto failed: %s", sock_strerror(errno));
-               log_addr(VERB_OPS, "remote address is", 
+               if (!is_connected) {
+                       verbose(VERB_OPS, "sendto failed: %s", sock_strerror(errno));
+               } else {
+                       verbose(VERB_OPS, "send failed: %s", sock_strerror(errno));
+               }
+               log_addr(VERB_OPS, "remote address is",
                        (struct sockaddr_storage*)addr, addrlen);
                return 0;
        } else if((size_t)sent != sldns_buffer_remaining(packet)) {
@@ -764,7 +773,7 @@ comm_point_udp_callback(int fd, short event, void* arg)
                        buffer = rep.c->buffer;
 #endif
                        (void)comm_point_send_udp_msg(rep.c, buffer,
-                               (struct sockaddr*)&rep.addr, rep.addrlen);
+                               (struct sockaddr*)&rep.addr, rep.addrlen, 0);
                }
                if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
                another UDP port. Note rep.c cannot be reused with TCP fd. */
@@ -3944,7 +3953,7 @@ comm_point_send_reply(struct comm_reply *repinfo)
                        repinfo->addrlen, repinfo);
                else
                        comm_point_send_udp_msg(repinfo->c, buffer,
-                       (struct sockaddr*)&repinfo->addr, repinfo->addrlen);
+                       (struct sockaddr*)&repinfo->addr, repinfo->addrlen, 0);
 #ifdef USE_DNSTAP
                if(repinfo->c->dtenv != NULL &&
                   repinfo->c->dtenv->log_client_response_messages)
index 266a74ff333e41de63f2e70e1674dda81210b92d..810190683eba3029a93378597ca62bd12b5597fa 100644 (file)
@@ -633,10 +633,11 @@ void comm_point_drop_reply(struct comm_reply* repinfo);
  * @param addr: where to send it to.   If NULL, send is performed,
  *     for connected sockets, to the connected address.
  * @param addrlen: length of addr.
+ * @param is_connected: if the UDP socket is connect()ed.
  * @return: false on a failure.
  */
 int comm_point_send_udp_msg(struct comm_point* c, struct sldns_buffer* packet,
-       struct sockaddr* addr, socklen_t addrlen);
+       struct sockaddr* addr, socklen_t addrlen,int is_connected);
 
 /**
  * Stop listening for input on the commpoint. No callbacks will happen.