]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix CVE-2026-14586, Assertion in libngtcp2 when under pressure
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:08:48 +0000 (10:08 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:08:48 +0000 (10:08 +0200)
  in high concurrency DNS-over-QUIC environments. Thanks to Kunta
  Chu, Kaihua Wang, and Jianjun Chen from Tsinghua University,
  for the report.

configure.ac
services/listen_dnsport.c
services/listen_dnsport.h
util/netevent.c
util/netevent.h

index 27e16f64658ab5509b338473e71d255ff8612cde..a4b6b17bdc65c1f43acbe41ce8da815a2e60f239 100644 (file)
@@ -1736,6 +1736,22 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
        AC_MSG_RESULT(no)
     ])
 
+    AC_CHECK_DECL([CLOCK_MONOTONIC]
+        , []
+        , [AC_MSG_ERROR([ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system])]
+        , [AC_INCLUDES_DEFAULT
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+        ])
+
 fi
 
 # set static linking for uninstalled libraries if requested
index 5db2b940bc04a531dd5b5a90a248154306639935..a08a5352ecff82373647b002558ddc86989fd770 100644 (file)
@@ -42,7 +42,6 @@
 #ifdef HAVE_SYS_TYPES_H
 #  include <sys/types.h>
 #endif
-#include <sys/time.h>
 #include <limits.h>
 #ifdef USE_TCP_FASTOPEN
 #include <netinet/tcp.h>
@@ -3399,14 +3398,13 @@ doq_table_delete(struct doq_table* table)
 }
 
 struct doq_timer*
-doq_timer_find_time(struct doq_table* table, struct timeval* tv)
+doq_timer_find_time(struct doq_table* table, ngtcp2_tstamp ts)
 {
        struct doq_timer key;
        struct rbnode_type* node;
        log_assert(table != NULL);
        memset(&key, 0, sizeof(key));
-       key.time.tv_sec = tv->tv_sec;
-       key.time.tv_usec = tv->tv_usec;
+       key.time_mono = ts;
        node = rbtree_search(table->timer_tree, &key);
        if(node)
                return (struct doq_timer*)node->key;
@@ -3454,7 +3452,7 @@ doq_timer_list_remove(struct doq_table* table, struct doq_timer* timer)
        if(!timer->timer_in_list)
                return;
        /* The item in the rbtree has the list start and end. */
-       rb_timer = doq_timer_find_time(table, &timer->time);
+       rb_timer = doq_timer_find_time(table, timer->time_mono);
        if(rb_timer) {
                if(timer->setlist_prev)
                        timer->setlist_prev->setlist_next = timer->setlist_next;
@@ -3500,7 +3498,8 @@ doq_timer_unset(struct doq_table* table, struct doq_timer* timer)
 }
 
 void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
-       struct doq_server_socket* worker_doq_socket, struct timeval* tv)
+       struct doq_server_socket* worker_doq_socket, struct timeval* tv,
+       ngtcp2_tstamp ts)
 {
        struct doq_timer* rb_timer;
        if(verbosity >= VERB_ALGO && timer->conn) {
@@ -3514,14 +3513,14 @@ void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
                        (int)rel.tv_sec, (int)rel.tv_usec);
        }
        if(timer->timer_in_tree || timer->timer_in_list) {
-               if(timer->time.tv_sec == tv->tv_sec &&
-                       timer->time.tv_usec == tv->tv_usec)
+               if(timer->time_mono == ts)
                        return; /* already set on that time */
                doq_timer_unset(table, timer);
        }
-       timer->time.tv_sec = tv->tv_sec;
-       timer->time.tv_usec = tv->tv_usec;
-       rb_timer = doq_timer_find_time(table, tv);
+       timer->time_real.tv_sec = tv->tv_sec;
+       timer->time_real.tv_usec = tv->tv_usec;
+       timer->time_mono = ts;
+       rb_timer = doq_timer_find_time(table, ts);
        if(rb_timer) {
                /* There is a timeout already with this value. Timer is
                 * added to the setlist. */
@@ -3700,13 +3699,9 @@ int doq_timer_cmp(const void* key1, const void* key2)
 {
        struct doq_timer* e = (struct doq_timer*)key1;
        struct doq_timer* f = (struct doq_timer*)key2;
-       if(e->time.tv_sec < f->time.tv_sec)
-               return -1;
-       if(e->time.tv_sec > f->time.tv_sec)
-               return 1;
-       if(e->time.tv_usec < f->time.tv_usec)
+       if(e->time_mono < f->time_mono)
                return -1;
-       if(e->time.tv_usec > f->time.tv_usec)
+       if(e->time_mono > f->time_mono)
                return 1;
        return 0;
 }
@@ -4254,12 +4249,11 @@ doq_submit_new_token(struct doq_conn* conn)
        ngtcp2_ssize tokenlen;
        int ret;
        const ngtcp2_path* path = ngtcp2_conn_get_path(conn->conn);
-       ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
 
        tokenlen = ngtcp2_crypto_generate_regular_token(token,
                conn->doq_socket->static_secret,
                conn->doq_socket->static_secret_len, path->remote.addr,
-               path->remote.addrlen, ts);
+               path->remote.addrlen, doq_get_timestamp_nanosec());
        if(tokenlen < 0) {
                log_err("doq ngtcp2_crypto_generate_regular_token failed");
                return 1;
@@ -5101,23 +5095,30 @@ doq_conn_clear_conids(struct doq_conn* conn)
 
 ngtcp2_tstamp doq_get_timestamp_nanosec(void)
 {
-#ifdef CLOCK_REALTIME
        struct timespec tp;
        memset(&tp, 0, sizeof(tp));
-       /* Get a nanosecond time, that can be compared with the event base. */
-       if(clock_gettime(CLOCK_REALTIME, &tp) == -1) {
-               log_err("clock_gettime failed: %s", strerror(errno));
+#ifdef CLOCK_BOOTTIME
+       if(clock_gettime(CLOCK_BOOTTIME, &tp) == -1) {
+#endif
+               if(clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
+                       log_err("clock_gettime failed: %s", strerror(errno));
+               }
+#ifdef CLOCK_BOOTTIME
        }
+#endif
        return ((uint64_t)tp.tv_sec)*((uint64_t)1000000000) +
                ((uint64_t)tp.tv_nsec);
-#else
+}
+
+static struct timeval doq_get_timevalue(void)
+{
        struct timeval tv;
+       memset(&tv, 0, sizeof(tv));
        if(gettimeofday(&tv, NULL) < 0) {
                log_err("gettimeofday failed: %s", strerror(errno));
+               memset(&tv, 0, sizeof(tv));
        }
-       return ((uint64_t)tv.tv_sec)*((uint64_t)1000000000) +
-               ((uint64_t)tv.tv_usec)*((uint64_t)1000);
-#endif /* CLOCK_REALTIME */
+       return tv;
 }
 
 /** doq start the closing period for the connection. */
@@ -5240,18 +5241,17 @@ doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr,
        int* err_drop)
 {
        int ret;
-       ngtcp2_tstamp ts;
        struct ngtcp2_path path;
        memset(&path, 0, sizeof(path));
        path.remote.addr = (struct sockaddr*)&paddr->addr;
        path.remote.addrlen = paddr->addrlen;
        path.local.addr = (struct sockaddr*)&paddr->localaddr;
        path.local.addrlen = paddr->localaddrlen;
-       ts = doq_get_timestamp_nanosec();
 
        ret = ngtcp2_conn_read_pkt(conn->conn, &path, pi,
                sldns_buffer_begin(c->doq_socket->pkt_buf),
-               sldns_buffer_limit(c->doq_socket->pkt_buf), ts);
+               sldns_buffer_limit(c->doq_socket->pkt_buf),
+               doq_get_timestamp_nanosec());
        if(ret != 0) {
                if(err_retry)
                        *err_retry = 0;
@@ -5339,7 +5339,6 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
 {
        struct doq_stream* stream = conn->stream_write_first;
        ngtcp2_path_storage ps;
-       ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
        size_t num_packets = 0, max_packets = 65535;
        ngtcp2_path_storage_zero(&ps);
 
@@ -5392,7 +5391,8 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
                ret = ngtcp2_conn_writev_stream(conn->conn, &ps.path, &pi,
                        sldns_buffer_begin(c->doq_socket->pkt_buf),
                        sldns_buffer_remaining(c->doq_socket->pkt_buf),
-                       &ndatalen, flags, stream_id, datav, datav_count, ts);
+                       &ndatalen, flags, stream_id, datav, datav_count,
+                       doq_get_timestamp_nanosec());
                if(ret < 0) {
                        if(ret == NGTCP2_ERR_WRITE_MORE) {
                                verbose(VERB_ALGO, "doq: write more, ndatalen %d", (int)ndatalen);
@@ -5464,7 +5464,8 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
                if(ret == 0) {
                        /* congestion limited */
                        doq_conn_write_disable(conn);
-                       ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
+                       ngtcp2_conn_update_pkt_tx_time(conn->conn,
+                               doq_get_timestamp_nanosec());
                        return 1;
                }
                sldns_buffer_set_position(c->doq_socket->pkt_buf, ret);
@@ -5478,7 +5479,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
                if(stream)
                        stream = stream->write_next;
        }
-       ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
+       ngtcp2_conn_update_pkt_tx_time(conn->conn, doq_get_timestamp_nanosec());
        return 1;
 }
 
@@ -5555,32 +5556,35 @@ doq_table_pop_first(struct doq_table* table)
 }
 
 int
-doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv)
+doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv, ngtcp2_tstamp* ts)
 {
-       ngtcp2_tstamp expiry = ngtcp2_conn_get_expiry(conn->conn);
-       ngtcp2_tstamp now = doq_get_timestamp_nanosec();
+       ngtcp2_tstamp doq_expiry = ngtcp2_conn_get_expiry(conn->conn);
+       ngtcp2_tstamp doq_now = doq_get_timestamp_nanosec();
        ngtcp2_tstamp t;
+       struct timeval now = doq_get_timevalue();
 
-       if(expiry <= now) {
+       if(doq_expiry <= doq_now || doq_expiry == UINT64_MAX) {
+               /* UINT64_MAX means there is no next expiry. */
                /* The timer has already expired, add with zero timeout.
                 * This should call the callback straight away. Calling it
                 * from the event callbacks is cleaner than calling it here,
                 * because then it is always called with the same locks and
                 * so on. This routine only has the conn.lock. */
-               t = now;
+               t = doq_now;
+               memcpy(tv, &now, sizeof(*tv));
        } else {
-               t = expiry;
+               t = doq_expiry;
+               memset(tv, 0, sizeof(*tv));
+               tv->tv_sec = (doq_expiry - doq_now) / NGTCP2_SECONDS;
+               tv->tv_usec = ((doq_expiry - doq_now) / NGTCP2_MICROSECONDS)%1000000;
+               timeval_add(tv, &now);
        }
 
-       /* convert to timeval */
-       memset(tv, 0, sizeof(*tv));
-       tv->tv_sec = t / NGTCP2_SECONDS;
-       tv->tv_usec = (t / NGTCP2_MICROSECONDS)%1000000;
+       *ts = t;
 
        /* If we already have a timer, is it the right value? */
        if(conn->timer.timer_in_tree || conn->timer.timer_in_list) {
-               if(conn->timer.time.tv_sec == tv->tv_sec &&
-                       conn->timer.time.tv_usec == tv->tv_usec)
+               if(conn->timer.time_mono == *ts)
                        return 0;
        }
        return 1;
@@ -5601,13 +5605,12 @@ doq_conn_log_line(struct doq_conn* conn, char* s)
 int
 doq_conn_handle_timeout(struct doq_conn* conn)
 {
-       ngtcp2_tstamp now = doq_get_timestamp_nanosec();
        int rv;
 
        if(verbosity >= VERB_ALGO)
                doq_conn_log_line(conn, "timeout");
 
-       rv = ngtcp2_conn_handle_expiry(conn->conn, now);
+       rv = ngtcp2_conn_handle_expiry(conn->conn, doq_get_timestamp_nanosec());
        if(rv != 0) {
                verbose(VERB_ALGO, "ngtcp2_conn_handle_expiry failed: %s",
                        ngtcp2_strerror(rv));
index 963595a1ccc5b5b24066a55394a9c59174997386..95aa3e11ebe3be95d1f27903fa6fdaef4bc630e9 100644 (file)
@@ -538,8 +538,11 @@ void doq_table_delete(struct doq_table* table);
 struct doq_timer {
        /** The rbnode in the tree sorted by timeout value. Key this struct. */
        struct rbnode_type node;
+       /** The timeout value. Monotonic value used with ngtcp2.
+        *  This time value is used for the tree operations. */
+       ngtcp2_tstamp time_mono;
        /** The timeout value. Absolute time value. */
-       struct timeval time;
+       struct timeval time_real;
        /** If the timer is in the time tree, with the node. */
        int timer_in_tree;
        /** If there are more timers with the exact same timeout value,
@@ -813,10 +816,12 @@ struct doq_conn* doq_table_pop_first(struct doq_table* table);
  * doq check if the timer for the conn needs to be changed.
  * @param conn: connection, caller must hold lock on it.
  * @param tv: time value, absolute time, returned.
+ * @param ts: time stamp, absolute time, returned.
  * @return true if timer needs to be set to tv, false if no change is needed
  *     to the timer. The timer is already set to the right time in that case.
  */
-int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv);
+int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv,
+       ngtcp2_tstamp* ts);
 
 /** doq remove timer from tree */
 void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer);
@@ -829,11 +834,12 @@ void doq_timer_unset(struct doq_table* table, struct doq_timer* timer);
 
 /** doq set the timer and add it. */
 void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
-       struct doq_server_socket* worker_doq_socket, struct timeval* tv);
+       struct doq_server_socket* worker_doq_socket, struct timeval* tv,
+       ngtcp2_tstamp ts);
 
 /** doq find a timeout in the timer tree */
 struct doq_timer* doq_timer_find_time(struct doq_table* table,
-       struct timeval* tv);
+       ngtcp2_tstamp ts);
 
 /** doq handle timeout for a connection. Pass conn locked. Returns false for
  * deletion. */
@@ -851,6 +857,9 @@ int doq_table_quic_size_available(struct doq_table* table,
 
 /** doq get the quic size value */
 size_t doq_table_quic_size_get(struct doq_table* table);
+
+/** get a timestamp in nanoseconds */
+ngtcp2_tstamp doq_get_timestamp_nanosec(void);
 #endif /* HAVE_NGTCP2 */
 
 char* set_ip_dscp(int socket, int addrfamily, int ds);
@@ -866,8 +875,4 @@ void doq_client_event_cb(int fd, short event, void* arg);
 /** timer event callback for testcode/doqclient */
 void doq_client_timer_cb(int fd, short event, void* arg);
 
-#ifdef HAVE_NGTCP2
-/** get a timestamp in nanoseconds */
-ngtcp2_tstamp doq_get_timestamp_nanosec(void);
-#endif
 #endif /* LISTEN_DNSPORT_H */
index a86e22518fb81c59b4e9d5b119e3c58accc1f2f7..e1480dc228108b5820f1975fd1317b554d4ed143 100644 (file)
@@ -1827,7 +1827,6 @@ doq_send_retry(struct comm_point* c, struct doq_pkt_addr* paddr,
        char host[256], port[32];
        struct ngtcp2_cid scid;
        uint8_t token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
-       ngtcp2_tstamp ts;
        ngtcp2_ssize tokenlen, ret;
 
        if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
@@ -1841,12 +1840,10 @@ doq_send_retry(struct comm_point* c, struct doq_pkt_addr* paddr,
        scid.datalen = c->doq_socket->sv_scidlen;
        doq_cid_randfill(&scid, scid.datalen, c->doq_socket->rnd);
 
-       ts = doq_get_timestamp_nanosec();
-
        tokenlen = ngtcp2_crypto_generate_retry_token(token,
                c->doq_socket->static_secret, c->doq_socket->static_secret_len,
                hd->version, (void*)&paddr->addr, paddr->addrlen, &scid,
-               &hd->dcid, ts);
+               &hd->dcid, doq_get_timestamp_nanosec());
        if(tokenlen < 0) {
                log_err("ngtcp2_crypto_generate_retry_token failed: %s",
                        ngtcp2_strerror(tokenlen));
@@ -1895,13 +1892,11 @@ doq_verify_retry_token(struct comm_point* c, struct doq_pkt_addr* paddr,
        struct ngtcp2_cid* ocid, struct ngtcp2_pkt_hd* hd)
 {
        char host[256], port[32];
-       ngtcp2_tstamp ts;
        if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
                sizeof(host), port, sizeof(port))) {
                log_err("doq_verify_retry_token failed");
                return 0;
        }
-       ts = doq_get_timestamp_nanosec();
        verbose(VERB_ALGO, "doq: verifying retry token from %s %s", host,
                port);
        if(ngtcp2_crypto_verify_retry_token(ocid,
@@ -1913,7 +1908,7 @@ doq_verify_retry_token(struct comm_point* c, struct doq_pkt_addr* paddr,
                c->doq_socket->static_secret,
                c->doq_socket->static_secret_len, hd->version,
                (void*)&paddr->addr, paddr->addrlen, &hd->dcid,
-               10*NGTCP2_SECONDS, ts) != 0) {
+               10*NGTCP2_SECONDS, doq_get_timestamp_nanosec()) != 0) {
                verbose(VERB_ALGO, "doq: could not verify retry token "
                        "from %s %s", host, port);
                return 0;
@@ -1928,13 +1923,11 @@ doq_verify_token(struct comm_point* c, struct doq_pkt_addr* paddr,
        struct ngtcp2_pkt_hd* hd)
 {
        char host[256], port[32];
-       ngtcp2_tstamp ts;
        if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host,
                sizeof(host), port, sizeof(port))) {
                log_err("doq_verify_token failed");
                return 0;
        }
-       ts = doq_get_timestamp_nanosec();
        verbose(VERB_ALGO, "doq: verifying token from %s %s", host, port);
        if(ngtcp2_crypto_verify_regular_token(
 #ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
@@ -1944,7 +1937,7 @@ doq_verify_token(struct comm_point* c, struct doq_pkt_addr* paddr,
 #endif
                c->doq_socket->static_secret, c->doq_socket->static_secret_len,
                (void*)&paddr->addr, paddr->addrlen, 3600*NGTCP2_SECONDS,
-               ts) != 0) {
+               doq_get_timestamp_nanosec()) != 0) {
                verbose(VERB_ALGO, "doq: could not verify token from %s %s",
                        host, port);
                return 0;
@@ -2171,6 +2164,7 @@ doq_pickup_timer(struct comm_point* c)
 {
        struct doq_timer* t;
        struct timeval tv;
+       ngtcp2_tstamp ts = 0;
        int have_time = 0;
        memset(&tv, 0, sizeof(tv));
 
@@ -2180,27 +2174,24 @@ doq_pickup_timer(struct comm_point* c)
                        t->worker_doq_socket == c->doq_socket) {
                        /* pick up this element */
                        t->worker_doq_socket = c->doq_socket;
+                       memcpy(&tv, &t->time_real, sizeof(tv));
+                       ts = t->time_mono;
                        have_time = 1;
-                       memcpy(&tv, &t->time, sizeof(tv));
                        break;
                }
        }
        lock_rw_unlock(&c->doq_socket->table->lock);
-
+       c->doq_socket->marked_time = ts;
        if(have_time) {
                struct timeval rel;
                timeval_subtract(&rel, &tv, c->doq_socket->now_tv);
                comm_timer_set(c->doq_socket->timer, &rel);
-               memcpy(&c->doq_socket->marked_time, &tv,
-                       sizeof(c->doq_socket->marked_time));
                verbose(VERB_ALGO, "doq pickup timer at %d.%6.6d in %d.%6.6d",
                        (int)tv.tv_sec, (int)tv.tv_usec, (int)rel.tv_sec,
                        (int)rel.tv_usec);
        } else {
                if(comm_timer_is_set(c->doq_socket->timer))
                        comm_timer_disable(c->doq_socket->timer);
-               memset(&c->doq_socket->marked_time, 0,
-                       sizeof(c->doq_socket->marked_time));
                verbose(VERB_ALGO, "doq timer disabled");
        }
 }
@@ -2213,13 +2204,14 @@ doq_done_setup_timer_and_write(struct comm_point* c, struct doq_conn* conn)
        uint8_t cid[NGTCP2_MAX_CIDLEN];
        rbnode_type* node;
        struct timeval new_tv;
+       ngtcp2_tstamp new_ts;
        int write_change = 0, timer_change = 0;
 
        /* No longer in callbacks, so the pointer to doq_socket is back
         * to NULL. */
        conn->doq_socket = NULL;
 
-       if(doq_conn_check_timer(conn, &new_tv))
+       if(doq_conn_check_timer(conn, &new_tv, &new_ts))
                timer_change = 1;
        if( (conn->write_interest && !conn->on_write_list) ||
                (!conn->write_interest && conn->on_write_list))
@@ -2265,7 +2257,7 @@ doq_done_setup_timer_and_write(struct comm_point* c, struct doq_conn* conn)
        }
        if(timer_change) {
                doq_timer_set(c->doq_socket->table, &conn->timer,
-                       c->doq_socket, &new_tv);
+                       c->doq_socket, &new_tv, new_ts);
        }
        lock_rw_unlock(&c->doq_socket->table->lock);
        lock_basic_unlock(&conn->lock);
@@ -2429,7 +2421,7 @@ doq_write_blocked_pkt(struct comm_point* c)
        return 1;
 }
 
-/** doq find a timer that timeouted and return the conn, locked. */
+/** doq find a timer that timed out and return the conn, locked. */
 static struct doq_conn*
 doq_timer_timeout_conn(struct doq_server_socket* doq_socket)
 {
@@ -2442,7 +2434,7 @@ doq_timer_timeout_conn(struct doq_server_socket* doq_socket)
                conn = t->conn;
 
                /* If now < timer then no further timeouts in tree. */
-               if(timeval_smaller(doq_socket->now_tv, &t->time)) {
+               if(timeval_smaller(doq_socket->now_tv, &t->time_real)) {
                        lock_rw_unlock(&doq_socket->table->lock);
                        return NULL;
                }
@@ -2465,11 +2457,11 @@ doq_timer_erase_marker(struct doq_server_socket* doq_socket)
 {
        struct doq_timer* t;
        lock_rw_wrlock(&doq_socket->table->lock);
-       t = doq_timer_find_time(doq_socket->table, &doq_socket->marked_time);
+       t = doq_timer_find_time(doq_socket->table, doq_socket->marked_time);
        if(t && t->worker_doq_socket == doq_socket)
                t->worker_doq_socket = NULL;
        lock_rw_unlock(&doq_socket->table->lock);
-       memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time));
+       doq_socket->marked_time = 0;
 }
 
 void
@@ -2776,7 +2768,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd,
                free(doq_socket);
                return NULL;
        }
-       memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time));
+       doq_socket->marked_time = 0;
        comm_base_timept(base, &doq_socket->now_tt, &doq_socket->now_tv);
        doq_socket->cfg = cfg;
        return doq_socket;
index c5114bbbef27da7a86251457821c10aed6d70907..7235843ee10850a59b5636ec2ed72e87d87e543b 100644 (file)
@@ -1093,8 +1093,10 @@ struct doq_server_socket {
        struct doq_pkt_addr* blocked_paddr;
        /** timer for this worker on this comm_point to wait on. */
        struct comm_timer* timer;
+#ifdef HAVE_NGTCP2
        /** the timer that is marked by the doq_socket as waited on. */
-       struct timeval marked_time;
+       ngtcp2_tstamp marked_time;
+#endif
        /** the current time for use by time functions, time_t. */
        time_t* now_tt;
        /** the current time for use by time functions, timeval. */