]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
fix that ssl_handle_it() uses tcp_is_reading in tcp_write_and_read mode.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 10 Jul 2020 13:37:30 +0000 (15:37 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 10 Jul 2020 13:37:30 +0000 (15:37 +0200)
fix that netevent tcp_write_and_read mode does not close due to error from
assert that not both write and read happen at the same time.

services/outside_network.c
util/netevent.c

index af69860b5fb08e6bdbc67b4b026e9c7e7af75a81..d7db120fe20022d2aec65f7dfda4606640bd98a8 100644 (file)
@@ -507,6 +507,9 @@ outnet_tcp_take_query_setup(int s, struct pending_tcp* pend,
        struct waiting_tcp* w)
 {
        struct timeval tv;
+       verbose(5, "outnet_tcp_take_query_setup: setup packet to write "
+               "len %d timeout %d msec",
+               (int)w->pkt_len, w->timeout);
        pend->c->tcp_write_pkt = w->pkt;
        pend->c->tcp_write_pkt_len = w->pkt_len;
        pend->c->tcp_write_and_read = 1;
index 3237907d1792b9e7a453b2d988ea0c1332432894..63150afb79e5edeb4c604e30e1c48d6118107bf3 100644 (file)
@@ -1434,9 +1434,17 @@ ssl_handle_write(struct comm_point* c)
 
 /** handle ssl tcp connection with dns contents */
 static int
-ssl_handle_it(struct comm_point* c)
+ssl_handle_it(struct comm_point* c, int is_write)
 {
-       if(c->tcp_is_reading)
+       /* handle case where renegotiation wants read during write call
+        * or write during read calls */
+       if(is_write && c->ssl_shake_state == comm_ssl_shake_hs_write)
+               return ssl_handle_read(c);
+       else if(!is_write && c->ssl_shake_state == comm_ssl_shake_hs_read)
+               return ssl_handle_write(c);
+       /* handle read events for read operation and write events for a
+        * write operation */
+       else if(!is_write)
                return ssl_handle_read(c);
        return ssl_handle_write(c);
 }
@@ -1452,9 +1460,10 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
 {
        ssize_t r;
        log_assert(c->type == comm_tcp || c->type == comm_local);
+       verbose(5, "comm point tcp handle read fd %d", fd);
        if(c->ssl)
-               return ssl_handle_it(c);
-       if(!c->tcp_is_reading)
+               return ssl_handle_it(c, 0);
+       if(!c->tcp_is_reading && !c->tcp_write_and_read)
                return 0;
 
        log_assert(fd != -1);
@@ -1563,8 +1572,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
 #else
        buffer = c->buffer;
 #endif
-       if(c->tcp_is_reading && !c->ssl)
+       verbose(5, "comm point tcp handle write fd %d", fd);
+       if(c->tcp_is_reading && !c->ssl && !c->tcp_write_and_read)
                return 0;
+       verbose(5, "comm point tcp handle write fd %d, part2", fd);
        log_assert(fd != -1);
        if(((!c->tcp_write_and_read && c->tcp_byte_count == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == 0)) && c->tcp_check_nb_connect) {
                /* check for pending error from nonblocking connect */
@@ -1606,8 +1617,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
                        return 0;
                }
        }
+       verbose(5, "comm point tcp handle write fd %d, part3", fd);
        if(c->ssl)
-               return ssl_handle_it(c);
+               return ssl_handle_it(c, 1);
+       verbose(5, "comm point tcp handle write fd %d, part4", fd);
 
 #ifdef USE_MSG_FASTOPEN
        /* Only try this on first use of a connection that uses tfo, 
@@ -1696,6 +1709,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
        }
 #endif /* USE_MSG_FASTOPEN */
 
+       verbose(5, "comm point tcp handle write fd %d: before write", fd);
        if((c->tcp_write_and_read?c->tcp_write_byte_count:c->tcp_byte_count) < sizeof(uint16_t)) {
                uint16_t len = htons(c->tcp_write_and_read?c->tcp_write_pkt_len:sldns_buffer_limit(buffer));
 #ifdef HAVE_WRITEV
@@ -1722,6 +1736,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
                                sizeof(uint16_t)-c->tcp_byte_count, 0);
                }
 #endif /* HAVE_WRITEV */
+               verbose(5, "comm point tcp handle write fd %d: write res %d", fd, (int)r);
                if(r == -1) {
 #ifndef USE_WINSOCK
 #  ifdef EPIPE
@@ -1777,6 +1792,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
        }
        log_assert(c->tcp_write_and_read || sldns_buffer_remaining(buffer) > 0);
        log_assert(!c->tcp_write_and_read || c->tcp_write_byte_count < c->tcp_write_pkt_len + 2);
+       verbose(5, "comm point tcp handle write fd %d: before write remain", fd);
        if(c->tcp_write_and_read) {
                r = send(fd, (void*)c->tcp_write_pkt + c->tcp_write_byte_count - 2,
                        c->tcp_write_pkt_len + 2 - c->tcp_write_byte_count, 0);
@@ -1784,6 +1800,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
                r = send(fd, (void*)sldns_buffer_current(buffer),
                        sldns_buffer_remaining(buffer), 0);
        }
+       verbose(5, "comm point tcp handle write fd %d: write remain res %d", fd, (int)r);
        if(r == -1) {
 #ifndef USE_WINSOCK
                if(errno == EINTR || errno == EAGAIN)