Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package re for openSUSE:Factory checked in 
at 2026-11-05 18:20:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/re (Old)
 and      /work/SRC/openSUSE:Factory/.re.new.3759290 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "re"

Thu Nov  5 18:20:22 2026 rev:26 rq:1395055 version:4.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/re/re.changes    2026-10-01 16:47:06.058181338 
+0200
+++ /work/SRC/openSUSE:Factory/.re.new.3759290/re.changes       2026-11-05 
18:22:06.057167141 +0100
@@ -1,0 +2,16 @@
+Wed Nov  4 20:29:01 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 4.13.0
+  * tcp: add tcp_conn_set_nodelay.
+  * sip: add sip_transp_udp_sock().
+  * mbuf/mbuf_read_str: optimize and fix null-terminated read.
+  * tmr,test: fix tmr_cancel and tmr_isrunning.
+  * tmr/tmr_timespec_get: fix tv_nsec max 999'999'999.
+  * tmr: fix and optimize timer list destructing, fixes timer
+    "running".
+  * sipsess: properly CRLF terminate RAck header.
+  * websock: close stale KEEPALIVE connections.
+  * sip: remove re_printf from transp/ws code.
+  * tls/openssl: fix OpenSSL 4.1 deprecated warnings.
+
+-------------------------------------------------------------------

Old:
----
  re-4.12.0.tar.gz

New:
----
  re-4.13.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ re.spec ++++++
--- /var/tmp/diff_new_pack.Mp6fp3/_old  2026-11-05 18:22:06.791197654 +0100
+++ /var/tmp/diff_new_pack.Mp6fp3/_new  2026-11-05 18:22:06.793197737 +0100
@@ -17,10 +17,10 @@
 #
 
 
-%global sover   45
+%global sover   46
 %global libname lib%{name}%{sover}
 Name:           re
-Version:        4.12.0
+Version:        4.13.0
 Release:        0
 Summary:        Library for real-time communications with async I/O support
 License:        BSD-3-Clause

++++++ re-4.12.0.tar.gz -> re-4.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/.github/workflows/cmake_win.yml 
new/re-4.13.0/.github/workflows/cmake_win.yml
--- old/re-4.12.0/.github/workflows/cmake_win.yml       2026-09-30 
19:40:28.000000000 +0200
+++ new/re-4.13.0/.github/workflows/cmake_win.yml       2026-11-04 
20:31:42.000000000 +0100
@@ -53,10 +53,13 @@
     steps:
       - uses: actions/checkout@v7
 
-      - name: Install OpenSSL
+      - name: Download pre-compiled OpenSSL
         if: ${{ matrix.config.openssl }}
+        shell: bash
         run: |
-          choco install --no-progress ${{ matrix.config.choco }} openssl
+          curl -fsSL -o openssl.zip 
"https://github.com/baresip/tools/releases/download/v2026.10.0/openssl-windows-x64.zip";
+          7z x openssl.zip
+          echo "OPENSSL_ROOT_DIR=$GITHUB_WORKSPACE\\openssl-windows-x64" >> 
$GITHUB_ENV
 
       - name: Build
         shell: cmd
@@ -64,7 +67,7 @@
           call "${{ matrix.config.environment_script }}"
           cmake --version
           ninja --version
-          cmake -S . -B build -G "${{ matrix.config.generators }}" 
-DCMAKE_C_FLAGS="/WX" -DHAVE_THREADS="${{ matrix.c11_threads }}" 
-DCMAKE_BUILD_TYPE="${{ matrix.config.build }}" 
-DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL="${{ matrix.config.disable_openssl }}"
+          cmake -S . -B build -G "${{ matrix.config.generators }}" 
-DCMAKE_C_FLAGS="/WX" -DHAVE_THREADS="${{ matrix.c11_threads }}" 
-DCMAKE_BUILD_TYPE="${{ matrix.config.build }}" 
-DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL="${{ matrix.config.disable_openssl }}" 
-DOPENSSL_USE_STATIC_LIBS=TRUE
           cmake --build build --parallel -t retest
 
       - name: retest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/.github/workflows/valgrind.yml 
new/re-4.13.0/.github/workflows/valgrind.yml
--- old/re-4.12.0/.github/workflows/valgrind.yml        2026-09-30 
19:40:28.000000000 +0200
+++ new/re-4.13.0/.github/workflows/valgrind.yml        2026-11-04 
20:31:42.000000000 +0100
@@ -33,4 +33,4 @@
 
     - name: retest
       run: |
-        valgrind --leak-check=full --show-reachable=yes --error-exitcode=42 
./build/test/retest -r -v
+        valgrind --track-origins=yes --suppressions=test/valgrind.supp 
--leak-check=full --show-reachable=yes --error-exitcode=42 ./build/test/retest 
-r -v
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/CHANGELOG.md new/re-4.13.0/CHANGELOG.md
--- old/re-4.12.0/CHANGELOG.md  2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/CHANGELOG.md  2026-11-04 20:31:42.000000000 +0100
@@ -5,6 +5,32 @@
 The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic 
Versioning](https://semver.org/spec/v2.0.0.html).
 
+## v4.13.0 - 2026-11-04
+
+### What's Changed
+* ci/win: use OpenSSL tools build (replaces unstable choco) by @sreimers in 
https://github.com/baresip/re/pull/1626
+* tcp: add tcp_conn_set_nodelay by @sreimers in 
https://github.com/baresip/re/pull/1627
+* sip: add sip_transp_udp_sock() by @a7asoft in 
https://github.com/baresip/re/pull/1624
+* mbuf/mbuf_read_str: optimize and fix null-terminated read by @sreimers in 
https://github.com/baresip/re/pull/1622
+* tmr,test: fix tmr_cancel and tmr_isrunning by @sreimers in 
https://github.com/baresip/re/pull/1629
+* tmr/tmr_timespec_get: fix tv_nsec max 999'999'999 by @sreimers in 
https://github.com/baresip/re/pull/1630
+* tmr: fix and optimize timer list destructing, fixes timer "running" by 
@sreimers in https://github.com/baresip/re/pull/1631
+* sipsess: properly CRLF terminate RAck header by @ExtremelyLazyCat in 
https://github.com/baresip/re/pull/1633
+* sys: add missing stdarg.h, fixes build on OpenBSD by @landryb in 
https://github.com/baresip/re/pull/1632
+* websock: close stale KEEPALIVE connections by @sreimers in 
https://github.com/baresip/re/pull/1634
+* btrace: fix mem_debug() deadlock and stale frames on Windows by @oldwired in 
https://github.com/baresip/re/pull/1637
+* sip: remove re_printf from transp/ws code by @alfredh in 
https://github.com/baresip/re/pull/1638
+* ci/valgrind: add openssl gcm suppression by @sreimers in 
https://github.com/baresip/re/pull/1640
+* tls/openssl: fix OpenSSL 4.1 deprecated warnings by @sreimers in 
https://github.com/baresip/re/pull/1646
+
+### New Contributors
+* @a7asoft made their first contribution in 
https://github.com/baresip/re/pull/1624
+* @ExtremelyLazyCat made their first contribution in 
https://github.com/baresip/re/pull/1633
+* @oldwired made their first contribution in 
https://github.com/baresip/re/pull/1637
+
+**Full Changelog**: https://github.com/baresip/re/compare/v4.12.0...v4.13.0
+
+
 ## v4.12.0 - 2026-09-30
 
 ### What's Changed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/CMakeLists.txt new/re-4.13.0/CMakeLists.txt
--- old/re-4.12.0/CMakeLists.txt        2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/CMakeLists.txt        2026-11-04 20:31:42.000000000 +0100
@@ -14,13 +14,13 @@
 cmake_minimum_required(VERSION 3.18...4.0)
 
 project(re
-  VERSION 4.12.0
+  VERSION 4.13.0
   LANGUAGES C
   HOMEPAGE_URL https://github.com/baresip/re
   DESCRIPTION "Generic library for real-time communications"
 )
 
-set(PROJECT_SOVERSION 45) # bump if ABI breaks
+set(PROJECT_SOVERSION 46) # bump if ABI breaks
 
 # Pre-release identifier, comment out on a release
 # Increment for breaking changes (dev2, dev3...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/include/re_sip.h 
new/re-4.13.0/include/re_sip.h
--- old/re-4.12.0/include/re_sip.h      2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/include/re_sip.h      2026-11-04 20:31:42.000000000 +0100
@@ -313,6 +313,7 @@
                    const struct sa *laddr, ...);
 int  sip_transp_add_sock(struct sip *sip, enum sip_transp tp,
                         bool listen, const struct sa *laddr, ...);
+struct udp_sock *sip_transp_udp_sock(struct sip *sip);
 int  sip_transp_add_websock(struct sip *sip, enum sip_transp tp,
                            const struct sa *laddr,
                            bool server, const char *cert, struct tls *tls);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/include/re_sys.h 
new/re-4.13.0/include/re_sys.h
--- old/re-4.12.0/include/re_sys.h      2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/include/re_sys.h      2026-11-04 20:31:42.000000000 +0100
@@ -4,6 +4,7 @@
  * Copyright (C) 2010 Creytiv.com
  */
 #include <stdio.h>
+#include <stdarg.h>
 
 #ifndef RE_VERSION
 #define RE_VERSION "?"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/include/re_tcp.h 
new/re-4.13.0/include/re_tcp.h
--- old/re-4.12.0/include/re_tcp.h      2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/include/re_tcp.h      2026-11-04 20:31:42.000000000 +0100
@@ -59,6 +59,7 @@
 int  tcp_sock_local_get(const struct tcp_sock *ts, struct sa *local);
 int  tcp_settos(struct tcp_sock *ts, uint32_t tos);
 int  tcp_conn_settos(struct tcp_conn *tc, uint32_t tos);
+int  tcp_conn_set_nodelay(struct tcp_conn *tc, bool nodelay);
 
 
 /* TCP Connection */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/mk/Doxyfile new/re-4.13.0/mk/Doxyfile
--- old/re-4.12.0/mk/Doxyfile   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/mk/Doxyfile   2026-11-04 20:31:42.000000000 +0100
@@ -4,7 +4,7 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = libre
-PROJECT_NUMBER         = 4.12.0
+PROJECT_NUMBER         = 4.13.0
 OUTPUT_DIRECTORY       = ../re-dox
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/btrace/btrace.c 
new/re-4.13.0/src/btrace/btrace.c
--- old/re-4.12.0/src/btrace/btrace.c   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/btrace/btrace.c   2026-11-04 20:31:42.000000000 +0100
@@ -36,16 +36,18 @@
 
        return 0;
 #elif defined(WIN32)
-       SYMBOL_INFO *symbol;
+       /* On the stack, not mem_zalloc(): mem_debug() calls this with the
+        * mem lock held */
+       ULONG64 buf[(sizeof(SYMBOL_INFO) + 256 * sizeof(char) +
+                    sizeof(ULONG64) - 1) / sizeof(ULONG64)];
+       SYMBOL_INFO *symbol = (SYMBOL_INFO *)buf;
        DWORD displacement = 0;
        IMAGEHLP_LINE line;
        HANDLE hProcess = GetCurrentProcess();
        (void)type;
 
        /* Initialize the symbol buffer. */
-       symbol = mem_zalloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), NULL);
-       if (!symbol)
-               return ENOMEM;
+       ZeroMemory(buf, sizeof(buf));
 
        SymInitialize(hProcess, NULL, TRUE);
 
@@ -57,14 +59,21 @@
        line.SizeOfStruct = sizeof(line);
 
        for (size_t i = 0; i < bt->len; i++) {
-               SymFromAddr(hProcess, (DWORD64)(bt->stack[i]), NULL, symbol);
-               SymGetLineFromAddr(hProcess, (DWORD64)(bt->stack[i]),
-                                  &displacement, &line);
-               re_hprintf(pf, "%zu: %s (%s:%lu)\n", i, symbol->Name,
-                          line.FileName, line.LineNumber);
+               DWORD64 addr = (DWORD64)(bt->stack[i]);
+
+               /* both keep the previous frame's result on failure */
+               if (!SymFromAddr(hProcess, addr, NULL, symbol)) {
+                       re_hprintf(pf, "%zu: %p\n", i, bt->stack[i]);
+                       continue;
+               }
+
+               if (SymGetLineFromAddr(hProcess, addr, &displacement, &line))
+                       re_hprintf(pf, "%zu: %s (%s:%lu)\n", i, symbol->Name,
+                                  line.FileName, line.LineNumber);
+               else
+                       re_hprintf(pf, "%zu: %s\n", i, symbol->Name);
        }
 
-       mem_deref(symbol);
        SymCleanup(hProcess);
 
        return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/mbuf/mbuf.c 
new/re-4.13.0/src/mbuf/mbuf.c
--- old/re-4.12.0/src/mbuf/mbuf.c       2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/mbuf/mbuf.c       2026-11-04 20:31:42.000000000 +0100
@@ -468,26 +468,39 @@
 
 
 /**
- * Read a string from a memory buffer
+ * Read null-terminated string from a memory buffer
  *
  * @param mb   Memory buffer
- * @param str  Buffer to read string to
+ * @param str  Buffer to read null-terminated string to
  * @param size Size of buffer
  *
  * @return 0 if success, otherwise errorcode
  */
 int mbuf_read_str(struct mbuf *mb, char *str, size_t size)
 {
-       if (!mb || !str)
+       if (!mb || !str || !size)
                return EINVAL;
 
-       while (size--) {
-               const uint8_t c = mbuf_read_u8(mb);
-               *str++ = c;
-               if ('\0' == c)
-                       break;
+       uint8_t *buf = mbuf_buf(mb);
+
+       size_t l = mbuf_get_left(mb);
+       size_t n = min(l, size - 1);
+       if (!n)
+               return EOVERFLOW;
+
+       char *c = memchr(buf, '\0', min(l, n + 1));
+       if (c) {
+               n = c - (char *)(buf);
+               mb->pos += n + 1;
+       }
+       else {
+               mb->pos += n;
        }
 
+       memcpy(str, buf, n);
+
+       str[n] = '\0';
+
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/sip/transp.c 
new/re-4.13.0/src/sip/transp.c
--- old/re-4.12.0/src/sip/transp.c      2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/sip/transp.c      2026-11-04 20:31:42.000000000 +0100
@@ -935,8 +935,6 @@
                           conn,
                           &conn->paddr, qent->mb);
 
-               re_printf("--> send\n");
-
                err = websock_send(conn->websock_conn, WEBSOCK_BIN,
                                   "%b",
                                   mbuf_buf(qent->mb),
@@ -1117,7 +1115,6 @@
        }
 #endif
 
-       re_printf("websock: connecting to '%s'\n", ws_uri);
        err = websock_connect(&conn->websock_conn, sip->websock,
                              transp->http_cli, ws_uri, 15000,
                              websock_estab_handler, websock_recv_handler,
@@ -1194,8 +1191,6 @@
 
        paddr = http_conn_peer(hc);
 
-       re_printf("http request from %J\n", paddr);
-
        hdr = http_msg_hdr(msg, HTTP_HDR_SEC_WEBSOCKET_PROTOCOL);
        if (!hdr) {
                re_printf("sip: missing Sec-WebSocket-Protocol header\n");
@@ -1380,6 +1375,31 @@
 }
 
 
+/**
+ * Get the UDP socket of the first UDP transport, e.g. to bind its file
+ * descriptor to a network interface
+ *
+ * @param sip SIP stack instance
+ *
+ * @return UDP socket, or NULL if no UDP transport was added
+ */
+struct udp_sock *sip_transp_udp_sock(struct sip *sip)
+{
+       struct le *le;
+
+       if (!sip)
+               return NULL;
+
+       for (le = sip->transpl.head; le; le = le->next) {
+               struct sip_transport *transp = le->data;
+               if (transp->tp == SIP_TRANSP_UDP)
+                       return transp->sock;
+       }
+
+       return NULL;
+}
+
+
 /**
  * Add a SIP websocket transport
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/sipsess/prack.c 
new/re-4.13.0/src/sipsess/prack.c
--- old/re-4.12.0/src/sipsess/prack.c   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/sipsess/prack.c   2026-11-04 20:31:42.000000000 +0100
@@ -138,7 +138,7 @@
        return sip_drequestf(&req->req, req->sess->sip, true, "PRACK",
                             req->sess->dlg, 0, req->sess->auth, NULL,
                             prack_resp_handler, prack,
-                            "RAck: %s\n"
+                            "RAck: %s\r\n"
                             "%s%s%s"
                             "Content-Length: %zu\r\n"
                             "\r\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/tcp/tcp.c new/re-4.13.0/src/tcp/tcp.c
--- old/re-4.12.0/src/tcp/tcp.c 2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/tcp/tcp.c 2026-11-04 20:31:42.000000000 +0100
@@ -12,6 +12,7 @@
 #endif
 #if !defined(WIN32)
 #include <netdb.h>
+#include <netinet/tcp.h>
 #endif
 #include <string.h>
 #include <re_types.h>
@@ -1505,3 +1506,33 @@
 {
        return tc->sendq.head != NULL;
 }
+
+
+/**
+ * Enable or disable Nagle's algorithm (TCP_NODELAY) on a TCP Connection
+ *
+ * With nodelay enabled, small writes are sent right away instead of
+ * waiting for the ACK of the previous segment. Useful for protocols
+ * that send several small messages back to back (e.g. WebSocket frames)
+ *
+ * @param tc      TCP Connection
+ * @param nodelay True to disable Nagle's algorithm, false to enable it
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int tcp_conn_set_nodelay(struct tcp_conn *tc, bool nodelay)
+{
+       int v = nodelay;
+
+       if (!tc)
+               return EINVAL;
+
+       if (tc->fdc == RE_BAD_SOCK)
+               return ENOTCONN;
+
+       if (0 != setsockopt(tc->fdc, IPPROTO_TCP, TCP_NODELAY,
+                           BUF_CAST &v, sizeof(v)))
+               return RE_ERRNO_SOCK;
+
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/tls/openssl/sni.c 
new/re-4.13.0/src/tls/openssl/sni.c
--- old/re-4.12.0/src/tls/openssl/sni.c 2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/tls/openssl/sni.c 2026-11-04 20:31:42.000000000 +0100
@@ -42,8 +42,13 @@
                if (!astr)
                        continue;
 
+#if OPENSSL_VERSION_NUMBER >= 0x40100000L
+               struct pl cn = {(char *)ASN1_STRING_get0_data(astr),
+                               ASN1_STRING_get_length(astr)};
+#else
                struct pl cn = {(char *)ASN1_STRING_get0_data(astr),
                                ASN1_STRING_length(astr)};
+#endif
 
                if (!pl_strcasecmp(&cn, sni))
                        return true;
@@ -71,9 +76,13 @@
                        astr = ASN1_IA5STRING_new();
                        if (!astr)
                                goto out;
-
+#if OPENSSL_VERSION_NUMBER >= 0x40100000L
+                       if (!ASN1_STRING_set1_string(astr, sni))
+                               goto out;
+#else
                        if (!ASN1_STRING_set(astr, sni, -1))
                                goto out;
+#endif
 
                        if (!ASN1_STRING_cmp(astr, g->d.dNSName)) {
                                match = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/tls/openssl/tls.c 
new/re-4.13.0/src/tls/openssl/tls.c
--- old/re-4.12.0/src/tls/openssl/tls.c 2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/tls/openssl/tls.c 2026-11-04 20:31:42.000000000 +0100
@@ -1034,7 +1034,12 @@
                if (astr) {
                        str_ncpy(cn, (char *)ASN1_STRING_get0_data(astr),
                                 size);
+
+#if OPENSSL_VERSION_NUMBER >= 0x40100000L
+                       n = (int)ASN1_STRING_get_length(astr);
+#else
                        n = ASN1_STRING_length(astr);
+#endif
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/tmr/tmr.c new/re-4.13.0/src/tmr/tmr.c
--- old/re-4.12.0/src/tmr/tmr.c 2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/tmr/tmr.c 2026-11-04 20:31:42.000000000 +0100
@@ -44,14 +44,14 @@
 static void tmrl_destructor(void *arg)
 {
        struct tmrl *tmrl = arg;
-       struct le *le;
 
        mtx_lock(tmrl->lock);
-       LIST_FOREACH(&tmrl->list, le) {
-               struct tmr *tmr = le->data;
+       while (tmrl->list.head) {
+               struct tmr *tmr = tmrl->list.head->data;
+               tmr->th = NULL;
                re_atomic_rls_set(&tmr->llock, (uintptr_t)NULL);
+               list_unlink(tmrl->list.head);
        }
-       list_clear(&tmrl->list);
        mtx_unlock(tmrl->lock);
 
        mem_deref(tmrl->lock);
@@ -284,7 +284,7 @@
        if (offset) {
                tp->tv_sec += (offset / 1000);
                tp->tv_nsec += ((offset * 1000000) % 1000000000LL);
-               while (tp->tv_nsec > 1000000000LL) {
+               while (tp->tv_nsec >= 1000000000LL) {
                        tp->tv_sec += 1;
                        tp->tv_nsec -= 1000000000LL;
                }
@@ -406,8 +406,10 @@
 
        mtx_lock(lock);
 
-       if (tmr->th)
+       if (tmr->th) {
                list_unlink(&tmr->le);
+               tmr->th = NULL;
+       }
 
        mtx_unlock(lock);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/src/websock/websock.c 
new/re-4.13.0/src/websock/websock.c
--- old/re-4.12.0/src/websock/websock.c 2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/src/websock/websock.c 2026-11-04 20:31:42.000000000 +0100
@@ -26,6 +26,7 @@
 enum {
        TIMEOUT_CLOSE = 10000,
        BUFSIZE_MAX   = 131072,
+       KA_MISSED_MAX = 2
 };
 
 enum websock_state {
@@ -56,6 +57,7 @@
        void *arg;
        enum websock_state state;
        unsigned kaint;
+       uint8_t ka_missed;
        bool active;
 };
 
@@ -150,6 +152,11 @@
 {
        struct websock_conn *conn = arg;
 
+       if (++conn->ka_missed > KA_MISSED_MAX) {
+               conn_close(conn, ETIMEDOUT);
+               return;
+       }
+
        tmr_start(&conn->tmr, conn->kaint, keepalive_handler, conn);
 
        (void)websock_send(conn, WEBSOCK_PING, NULL);
@@ -230,6 +237,8 @@
        struct websock_conn *conn = arg;
        int err = 0;
 
+       conn->ka_missed = 0; /* reset keepalive missing on all packets */
+
        if (conn->mb) {
 
                const size_t len = mbuf_get_left(mb), pos = conn->mb->pos;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/data/sni/client-interm.pem 
new/re-4.13.0/test/data/sni/client-interm.pem
--- old/re-4.12.0/test/data/sni/client-interm.pem       2026-09-30 
19:40:28.000000000 +0200
+++ new/re-4.13.0/test/data/sni/client-interm.pem       2026-11-04 
20:31:42.000000000 +0100
@@ -1,35 +1,36 @@
 -----BEGIN CERTIFICATE-----
-MIICOzCCAeGgAwIBAgIUOGllk+RwWh0SaiOIlZ28iDr9CUQwCgYIKoZIzj0EAwIw
-VzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTAgFw0yMjEy
-MjkwOTMxMDRaGA8yMTIyMTIwMzA5MzEwNFowTzELMAkGA1UEBhMCQVUxEzARBgNV
-BAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVzdDEaMBgGA1UEAwwRcmV0ZXN0
-LmNsaWVudC5vcmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARpvxjuwaXKPM2d
-M9G1DNYQR/cXacJw1ZlFgDT/PqolekRtjOUtFTs+2NAC5F8so3So9QS+XOBel851
-ZIfSZznco4GQMIGNMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgbAMB0GA1Ud
-DgQWBBQl0oAqn8/QfeOxwRS4iic96jokKDAfBgNVHSMEGDAWgBTGQwW6wdqJ1o5Y
-G1KSgeBw+jOwPzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
-CCsGAQUFBwMCMAoGCCqGSM49BAMCA0gAMEUCIEkiN/wpykIISrCZtFDa3SslEJL/
-i3bUUAKrHMab52xtAiEAkA0z6aDhxITnxIfqG3RqPR/NTlyJ8JVtrLcbHFRWRzI=
+MIICQzCCAemgAwIBAgIRANrVtMcY+CeYIqn2kSGF8T4wCgYIKoZIzj0EAwIwVzEL
+MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVz
+dDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTAgFw0yNjExMDEx
+MjAxNDlaGA8yMTI2MTAwODEyMDE0OVowTzELMAkGA1UEBhMCQVUxEzARBgNVBAgM
+ClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVzdDEaMBgGA1UEAwwRcmV0ZXN0LmNs
+aWVudC5vcmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATEcOGooeGZH6pxu4MI
+1aUW8d7nJ63qwb7KA3etPi2hiGEzGi7Ymu9wDkSwM9sm/O1LijhpxwiJGva0YZM8
+xqMCo4GbMIGYMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG
+CCsGAQUFBwMBBggrBgEFBQcDAjAcBgNVHREEFTATghFyZXRlc3QuY2xpZW50Lm9y
+ZzAdBgNVHQ4EFgQUvvOenRU7PIXT/iu3kB3/cTDnUNMwHwYDVR0jBBgwFoAU4MAa
+P1mU2radk2uH8VmDwBdEUXIwCgYIKoZIzj0EAwIDSAAwRQIgGg6B5/07PhCxWfe9
+sPmd52phTqPphVwnoN5PaM7Ru3wCIQDkHzwPvelsJ4kq3+qEFyztvNkvDKovJwq0
+EiMNbSGi3Q==
 -----END CERTIFICATE-----
 -----BEGIN EC PARAMETERS-----
 BggqhkjOPQMBBw==
 -----END EC PARAMETERS-----
 -----BEGIN EC PRIVATE KEY-----
-MHcCAQEEIJ76xyjJn4C6ZaQRszt0rNwKq0LBz/Re9QZPeDyBW4r0oAoGCCqGSM49
-AwEHoUQDQgAEab8Y7sGlyjzNnTPRtQzWEEf3F2nCcNWZRYA0/z6qJXpEbYzlLRU7
-PtjQAuRfLKN0qPUEvlzgXpfOdWSH0mc53A==
+MHcCAQEEIM+6J+5FxqQwNTtlEyhCgyQg+ClZzJddMoGzLGMX3WmPoAoGCCqGSM49
+AwEHoUQDQgAExHDhqKHhmR+qcbuDCNWlFvHe5yet6sG+ygN3rT4toYhhMxou2Jrv
+cA5EsDPbJvztS4o4accIiRr2tGGTPMajAg==
 -----END EC PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIB/TCCAaOgAwIBAgIBATAKBggqhkjOPQQDAjBPMQswCQYDVQQGEwJBVTETMBEG
-A1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGUmV0ZXN0MRowGAYDVQQDDBFNciBS
-ZXRlc3QgUm9vdCBDQTAgFw0yMjEyMjkwOTIzNTRaGA8yMTIyMTIwNDA5MjM1NFow
-VzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTBZMBMGByqG
-SM49AgEGCCqGSM49AwEHA0IABHn8RqyvhhIdMK0o0wc+mKfO97SghjB3FlKBLjQT
-+jIOVW3YboDBgPCRwdjGFugc661MyIHQrT74FXSpkYOWhtKjZjBkMB0GA1UdDgQW
-BBTGQwW6wdqJ1o5YG1KSgeBw+jOwPzAfBgNVHSMEGDAWgBSzp+1VNAQC/frGxi3S
-P0yfFD7bMjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAKBggq
-hkjOPQQDAgNIADBFAiEApEk3i06Pmp8JcWf+zP63qTIWRvXqi4wScxgyc9f9nLsC
-IEp5w8tyc7NxZFlAzH0ENl7L9zyLOoj685m5qnI/g9n2
+MIICCzCCAbKgAwIBAgIQFADkThPTHsMoisiEFGKJ9zAKBggqhkjOPQQDAjBPMQsw
+CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGUmV0ZXN0
+MRowGAYDVQQDDBFNciBSZXRlc3QgUm9vdCBDQTAgFw0yNjExMDExMjAxNDlaGA8y
+MTI2MTAwODEyMDE0OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh
+dGUxDzANBgNVBAoMBlJldGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVk
+aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPkzZ5C3bcWsWSZFdqnx
+U/Q2AZwtnvlquXbuJJfF6erUg856Z98cOz+Hy3p96wWVQZC3Q5ffbEAAzRRfs+PA
+keejZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBTgwBo/WZTatp2Ta4fxWYPAF0RRcjAfBgNVHSMEGDAWgBQCZaxMTRK4A1qM
+xvp6g1HWimh0lzAKBggqhkjOPQQDAgNHADBEAiBBhdSztskI5dfQ1iRn6qs4nSN4
+7cmU3y4TQx4+10OIaQIgP2kveUN83sDvpUP5KomXZE3p3gPYkUZ0+QTSv1NIEBw=
 -----END CERTIFICATE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/data/sni/gen.sh 
new/re-4.13.0/test/data/sni/gen.sh
--- old/re-4.12.0/test/data/sni/gen.sh  1970-01-01 01:00:00.000000000 +0100
+++ new/re-4.13.0/test/data/sni/gen.sh  2026-11-04 20:31:42.000000000 +0100
@@ -0,0 +1,103 @@
+#!/bin/sh
+#
+# Regenerate the SNI test certificates in this directory.
+#
+#   root-ca.pem          Root CA (cert only)
+#   server-interm.pem    Leaf retest.server.org + key + intermediate CA
+#   client-interm.pem    Leaf retest.client.org + key + intermediate CA
+#   server-verifyhost.pem Self-signed retest.server.org with IP:127.0.0.1 SAN
+#
+# Hostnames must be in subjectAltName: OpenSSL >= 4.1 no longer falls back
+# to the subject CN for hostname verification.
+#
+# The CA private keys are discarded. Set OPENSSL to use another binary.
+#
+# Usage: ./gen.sh
+
+set -eu
+
+OPENSSL=${OPENSSL:-openssl}
+DAYS=36500
+SUBJ="/C=AU/ST=Some-State/O=Retest"
+
+OUT=$(cd "$(dirname "$0")" && pwd)
+TMP=$(mktemp -d)
+trap 'rm -rf "$TMP"' EXIT
+cd "$TMP"
+
+cat > ext.cnf <<'EOF'
+[interm]
+basicConstraints = critical, CA:TRUE, pathlen:0
+keyUsage = critical, keyCertSign, cRLSign
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+
+[server]
+basicConstraints = CA:FALSE
+keyUsage = critical, digitalSignature
+extendedKeyUsage = serverAuth, clientAuth
+subjectAltName = DNS:retest.server.org
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+
+[client]
+basicConstraints = CA:FALSE
+keyUsage = critical, digitalSignature
+extendedKeyUsage = serverAuth, clientAuth
+subjectAltName = DNS:retest.client.org
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+EOF
+
+genkey() {
+       "$OPENSSL" ecparam -name prime256v1 -genkey -out "$1"
+}
+
+serial() {
+       echo "0x$("$OPENSSL" rand -hex 16)"
+}
+
+# sign <name> <cn> <ca> <extensions>
+sign() {
+       genkey "$1.key"
+       "$OPENSSL" req -new -key "$1.key" -subj "$SUBJ/CN=$2" -out "$1.csr"
+       "$OPENSSL" x509 -req -sha256 -in "$1.csr" \
+               -CA "$3.pem" -CAkey "$3.key" -set_serial "$(serial)" \
+               -days $DAYS -extfile ext.cnf -extensions "$4" -out "$1.pem"
+}
+
+# Root CA
+genkey root.key
+"$OPENSSL" req -new -x509 -sha256 -key root.key \
+       -subj "$SUBJ/CN=Mr Retest Root CA" -days $DAYS \
+       -addext "basicConstraints=critical,CA:TRUE" \
+       -addext "keyUsage=critical,keyCertSign,cRLSign" \
+       -out root.pem
+
+# Intermediate CA and leaf certificates
+sign interm "Mr Retest Intermediate CA" root   interm
+sign server "retest.server.org"         interm server
+sign client "retest.client.org"         interm client
+
+# Self-signed server cert for hostname + IP-literal verification
+genkey verifyhost.key
+"$OPENSSL" req -new -x509 -sha256 -key verifyhost.key \
+       -subj "$SUBJ/CN=retest.server.org" -days $DAYS \
+       -addext "subjectAltName=DNS:retest.server.org,IP:127.0.0.1" \
+       -addext "basicConstraints=critical,CA:TRUE" \
+       -out verifyhost.pem
+
+# Sanity check
+"$OPENSSL" verify -CAfile root.pem -untrusted interm.pem \
+       -verify_hostname retest.server.org server.pem
+"$OPENSSL" verify -CAfile root.pem -untrusted interm.pem \
+       -verify_hostname retest.client.org client.pem
+"$OPENSSL" verify -CAfile verifyhost.pem \
+       -verify_hostname retest.server.org verifyhost.pem
+
+cp root.pem "$OUT/root-ca.pem"
+cat server.pem server.key interm.pem > "$OUT/server-interm.pem"
+cat client.pem client.key interm.pem > "$OUT/client-interm.pem"
+cat verifyhost.pem verifyhost.key   > "$OUT/server-verifyhost.pem"
+
+echo "Certificates written to $OUT"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/data/sni/root-ca.pem 
new/re-4.13.0/test/data/sni/root-ca.pem
--- old/re-4.12.0/test/data/sni/root-ca.pem     2026-09-30 19:40:28.000000000 
+0200
+++ new/re-4.13.0/test/data/sni/root-ca.pem     2026-11-04 20:31:42.000000000 
+0100
@@ -1,13 +1,13 @@
 -----BEGIN CERTIFICATE-----
-MIIB9DCCAZugAwIBAgIUGWM5J2Oi1FhuZiq1agTkmWGNOqEwCgYIKoZIzj0EAwIw
+MIICBTCCAaugAwIBAgIUFn1nuklp7tcUa9BvqKEdC7yjJ7owCgYIKoZIzj0EAwIw
 TzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEaMBgGA1UEAwwRTXIgUmV0ZXN0IFJvb3QgQ0EwIBcNMjIxMjI5MDkyMDEx
-WhgPMjEyMjEyMDUwOTIwMTFaME8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
+dGVzdDEaMBgGA1UEAwwRTXIgUmV0ZXN0IFJvb3QgQ0EwIBcNMjYxMTAxMTIwMTQ5
+WhgPMjEyNjEwMDgxMjAxNDlaME8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
 LVN0YXRlMQ8wDQYDVQQKDAZSZXRlc3QxGjAYBgNVBAMMEU1yIFJldGVzdCBSb290
-IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErdUhTL7f5A5qa4GGcJEWkwBa
-l1Q7XU8DSKOiSsVnJ0w3TLHMXXoEx83yOF9yyp5xbxMtr3rSZEpFfQ6VVZ9FyKNT
-MFEwHQYDVR0OBBYEFLOn7VU0BAL9+sbGLdI/TJ8UPtsyMB8GA1UdIwQYMBaAFLOn
-7VU0BAL9+sbGLdI/TJ8UPtsyMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID
-RwAwRAIgcml4Q6W/zcUnzPI9eb97FNBqLNwWRTlh3JPDplpfj4MCIBVrXpAPEfVy
-JsCIPpxLjYPRhvfdRIZGgvzTP5q4mGaT
+IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2FDHd4Y81EsyRvMPdGN6KT+f
+A+y0Dhjr1eq2dqFjiA86NhJeJa62luy56vky7HpDjDMw++XPDAXa/qZVmlC5iKNj
+MGEwHQYDVR0OBBYEFAJlrExNErgDWozG+nqDUdaKaHSXMB8GA1UdIwQYMBaAFAJl
+rExNErgDWozG+nqDUdaKaHSXMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMAoGCCqGSM49BAMCA0gAMEUCIBo3APbW/3iZsItsfw6a/W98mx0QxhIsId/k
+LLicHX5eAiEA1mjs+c4FMZHUTUk8Xod3idFsgutUe1luQ9rl/t0Jlk4=
 -----END CERTIFICATE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/data/sni/server-interm.pem 
new/re-4.13.0/test/data/sni/server-interm.pem
--- old/re-4.12.0/test/data/sni/server-interm.pem       2026-09-30 
19:40:28.000000000 +0200
+++ new/re-4.13.0/test/data/sni/server-interm.pem       2026-11-04 
20:31:42.000000000 +0100
@@ -1,37 +1,36 @@
 -----BEGIN CERTIFICATE-----
-MIIClDCCAjmgAwIBAgIUa79XJUJxiZsuE19rM05mJwE/AuowCgYIKoZIzj0EAwIw
-VzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTAgFw0yMjEy
-MjkwOTMxMThaGA8yMTIyMTIwMzA5MzExOFowTzELMAkGA1UEBhMCQVUxEzARBgNV
-BAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVzdDEaMBgGA1UEAwwRcmV0ZXN0
-LnNlcnZlci5vcmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQIJmj//cAvgPmv
-VYe5IbVUg65pQzpTwRskbFqpDqUnIqkcdFHPHCtqAVg8bkTsXBETB76m44ejAps/
-F1cii/Rfo4HoMIHlMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgbAMB0GA1Ud
-DgQWBBSTjuar4J+Cv02G6QpqgCflL7swsDB3BgNVHSMEcDBugBTGQwW6wdqJ1o5Y
-G1KSgeBw+jOwP6FTpFEwTzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh
-dGUxDzANBgNVBAoMBlJldGVzdDEaMBgGA1UEAwwRTXIgUmV0ZXN0IFJvb3QgQ0GC
-AQEwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
-AjAKBggqhkjOPQQDAgNJADBGAiEAhfU/r3G88n0V3h5jc7FwgWL+9ig+SGlc6mPG
-FsqI0eECIQCMLbYDZgMPpaFPzCWKVAmp9wxzLLpX9++C/v4Y4FVOAg==
+MIICQzCCAemgAwIBAgIRALD6BXDqXz39AiNMZmPS6wUwCgYIKoZIzj0EAwIwVzEL
+MAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVz
+dDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTAgFw0yNjExMDEx
+MjAxNDlaGA8yMTI2MTAwODEyMDE0OVowTzELMAkGA1UEBhMCQVUxEzARBgNVBAgM
+ClNvbWUtU3RhdGUxDzANBgNVBAoMBlJldGVzdDEaMBgGA1UEAwwRcmV0ZXN0LnNl
+cnZlci5vcmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQSMEMmY+Ho0OXbDOFr
+4QODrLBcfGdMY60Ikmn1TgruwyZV/nYOU0FG45eXfc/tss+I+rv14lcBBgtDehe5
+0pzDo4GbMIGYMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG
+CCsGAQUFBwMBBggrBgEFBQcDAjAcBgNVHREEFTATghFyZXRlc3Quc2VydmVyLm9y
+ZzAdBgNVHQ4EFgQU+qmWsvWBVB8MUIMGo6M51Z78Ll4wHwYDVR0jBBgwFoAU4MAa
+P1mU2radk2uH8VmDwBdEUXIwCgYIKoZIzj0EAwIDSAAwRQIhAMRLhp8S61+UZ5gT
+LJXtmL/66exDoCCHVZvM5Rd6DjG0AiAvPzB+/7loHXKbMoysjLZn6L5W+bS7NItI
+Rwxd2KYFiw==
 -----END CERTIFICATE-----
 -----BEGIN EC PARAMETERS-----
 BggqhkjOPQMBBw==
 -----END EC PARAMETERS-----
 -----BEGIN EC PRIVATE KEY-----
-MHcCAQEEIJMwouMCx2+QTFwiuo2GUYPgtmTGpx/7+0rkcw6//GQvoAoGCCqGSM49
-AwEHoUQDQgAECCZo//3AL4D5r1WHuSG1VIOuaUM6U8EbJGxaqQ6lJyKpHHRRzxwr
-agFYPG5E7FwREwe+puOHowKbPxdXIov0Xw==
+MHcCAQEEIK6KhreraGn2QIlylpnbGgfS0cZHVHIH7nnucdZrUSdWoAoGCCqGSM49
+AwEHoUQDQgAEEjBDJmPh6NDl2wzha+EDg6ywXHxnTGOtCJJp9U4K7sMmVf52DlNB
+RuOXl33P7bLPiPq79eJXAQYLQ3oXudKcww==
 -----END EC PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
-MIIB/TCCAaOgAwIBAgIBATAKBggqhkjOPQQDAjBPMQswCQYDVQQGEwJBVTETMBEG
-A1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGUmV0ZXN0MRowGAYDVQQDDBFNciBS
-ZXRlc3QgUm9vdCBDQTAgFw0yMjEyMjkwOTIzNTRaGA8yMTIyMTIwNDA5MjM1NFow
-VzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVkaWF0ZSBDQTBZMBMGByqG
-SM49AgEGCCqGSM49AwEHA0IABHn8RqyvhhIdMK0o0wc+mKfO97SghjB3FlKBLjQT
-+jIOVW3YboDBgPCRwdjGFugc661MyIHQrT74FXSpkYOWhtKjZjBkMB0GA1UdDgQW
-BBTGQwW6wdqJ1o5YG1KSgeBw+jOwPzAfBgNVHSMEGDAWgBSzp+1VNAQC/frGxi3S
-P0yfFD7bMjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAKBggq
-hkjOPQQDAgNIADBFAiEApEk3i06Pmp8JcWf+zP63qTIWRvXqi4wScxgyc9f9nLsC
-IEp5w8tyc7NxZFlAzH0ENl7L9zyLOoj685m5qnI/g9n2
+MIICCzCCAbKgAwIBAgIQFADkThPTHsMoisiEFGKJ9zAKBggqhkjOPQQDAjBPMQsw
+CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UECgwGUmV0ZXN0
+MRowGAYDVQQDDBFNciBSZXRlc3QgUm9vdCBDQTAgFw0yNjExMDExMjAxNDlaGA8y
+MTI2MTAwODEyMDE0OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh
+dGUxDzANBgNVBAoMBlJldGVzdDEiMCAGA1UEAwwZTXIgUmV0ZXN0IEludGVybWVk
+aWF0ZSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPkzZ5C3bcWsWSZFdqnx
+U/Q2AZwtnvlquXbuJJfF6erUg856Z98cOz+Hy3p96wWVQZC3Q5ffbEAAzRRfs+PA
+keejZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBTgwBo/WZTatp2Ta4fxWYPAF0RRcjAfBgNVHSMEGDAWgBQCZaxMTRK4A1qM
+xvp6g1HWimh0lzAKBggqhkjOPQQDAgNHADBEAiBBhdSztskI5dfQ1iRn6qs4nSN4
+7cmU3y4TQx4+10OIaQIgP2kveUN83sDvpUP5KomXZE3p3gPYkUZ0+QTSv1NIEBw=
 -----END CERTIFICATE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/data/sni/server-verifyhost.pem 
new/re-4.13.0/test/data/sni/server-verifyhost.pem
--- old/re-4.12.0/test/data/sni/server-verifyhost.pem   2026-09-30 
19:40:28.000000000 +0200
+++ new/re-4.13.0/test/data/sni/server-verifyhost.pem   2026-11-04 
20:31:42.000000000 +0100
@@ -1,21 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIICBDCCAaqgAwIBAgIUIOphNYGjeu6zTVYgPPZMi3FK50owCgYIKoZIzj0EAwIw
+MIICGjCCAb+gAwIBAgIUHQISsiviZgSiQt4oVFknDLRYBsIwCgYIKoZIzj0EAwIw
 TzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxDzANBgNVBAoMBlJl
-dGVzdDEaMBgGA1UEAwwRcmV0ZXN0LnNlcnZlci5vcmcwHhcNMjYwOTIxMTg1NzM1
-WhcNMzYwOTE4MTg1NzM1WjBPMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1T
-dGF0ZTEPMA0GA1UECgwGUmV0ZXN0MRowGAYDVQQDDBFyZXRlc3Quc2VydmVyLm9y
-ZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABN0A1KAyC1QU9VDjH+DdTd0QxrpG
-C/lSVbXBbl0MapZdoXL+mkdQOhrQOkmyso6GTT6JdkjqvU4P6s+HgI5/zlKjZDBi
-MA8GA1UdEQQIMAaHBH8AAAEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU1Jxb
-TE5qbmJCg8QjySWnIJtaZ+wwHwYDVR0jBBgwFoAU1JxbTE5qbmJCg8QjySWnIJta
-Z+wwCgYIKoZIzj0EAwIDSAAwRQIhAJ4PwO+4zqzpIP8jsNcjl7rJEWRPbdtAbmYq
-2FYwzyW4AiBayvJn4r4HjsrXukdNFfRSSIslUyDdsJ4FsxnF4WisMA==
+dGVzdDEaMBgGA1UEAwwRcmV0ZXN0LnNlcnZlci5vcmcwIBcNMjYxMTAxMTIwMTQ5
+WhgPMjEyNjEwMDgxMjAxNDlaME8xCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
+LVN0YXRlMQ8wDQYDVQQKDAZSZXRlc3QxGjAYBgNVBAMMEXJldGVzdC5zZXJ2ZXIu
+b3JnMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4rkj6eX9/G+FKkZC2frSCOf8
+ONfCQUN1Mi7dD0bRfnYYUwezszU/elH2Zk8KXP+6RH3W8GuwH4bpnRXrrjI23KN3
+MHUwHQYDVR0OBBYEFB+vYW1w/rAJ4m504md02eHeboLrMB8GA1UdIwQYMBaAFB+v
+YW1w/rAJ4m504md02eHeboLrMCIGA1UdEQQbMBmCEXJldGVzdC5zZXJ2ZXIub3Jn
+hwR/AAABMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAL1V6Ruu
+HE8qeOEKgOOO3ILy3vfqAlUaPzlFm4vT/tuWAiEAnWdiFZROOfGAO/IVmFx5W2S8
+tV9nSzKXVFazwOlM4uI=
 -----END CERTIFICATE-----
 -----BEGIN EC PARAMETERS-----
 BggqhkjOPQMBBw==
 -----END EC PARAMETERS-----
 -----BEGIN EC PRIVATE KEY-----
-MHcCAQEEINsflZjpwDE9EguyUKKRK+2S72gvU8VABK3JZ/fIp8ypoAoGCCqGSM49
-AwEHoUQDQgAE3QDUoDILVBT1UOMf4N1N3RDGukYL+VJVtcFuXQxqll2hcv6aR1A6
-GtA6SbKyjoZNPol2SOq9Tg/qz4eAjn/OUg==
+MHcCAQEEIEecuJOMhef5GpS26wE6VEGtEQSUkBs1c/Nwz+lcf1DDoAoGCCqGSM49
+AwEHoUQDQgAE4rkj6eX9/G+FKkZC2frSCOf8ONfCQUN1Mi7dD0bRfnYYUwezszU/
+elH2Zk8KXP+6RH3W8GuwH4bpnRXrrjI23A==
 -----END EC PRIVATE KEY-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/mbuf.c new/re-4.13.0/test/mbuf.c
--- old/re-4.12.0/test/mbuf.c   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/mbuf.c   2026-11-04 20:31:42.000000000 +0100
@@ -160,6 +160,64 @@
 }
 
 
+static int test_mbuf_str(void)
+{
+       char payload[]  = "PAYLOAD";
+       char payload2[] = "TEST";
+       char str[255]   = {0};
+       int err;
+
+       struct mbuf *mb = mbuf_alloc(sizeof(payload));
+       if (!mb)
+               return ENOMEM;
+
+       err = mbuf_write_str(mb, payload);
+       TEST_ERR(err);
+
+       err = mbuf_write_u8(mb, '\0');
+       TEST_ERR(err);
+
+       err = mbuf_write_str(mb, payload2);
+       TEST_ERR(err);
+
+       /* "PAYLOAD\0" */
+       mb->pos = 0;
+       err     = mbuf_read_str(mb, str, sizeof(str));
+       TEST_ERR(err);
+       TEST_STRCMP(payload, strlen(payload), str, strlen(str));
+
+       /* "TEST\0" */
+       err = mbuf_read_str(mb, str, sizeof(str));
+       TEST_ERR(err);
+       TEST_STRCMP(payload2, strlen(payload2), str, strlen(str));
+
+       /* "PAYLOA\0" */
+       mb->pos = 0;
+       err     = mbuf_read_str(mb, str, strlen(payload));
+       TEST_ERR(err);
+       TEST_STRCMP(payload, strlen(payload) - 1, str, strlen(str));
+
+       /* "PAYLOAD" - not null terminated mbuf */
+       mbuf_rewind(mb);
+       mbuf_write_mem(mb, (uint8_t *)payload, sizeof(payload) - 1);
+
+       mb->pos = 0;
+       err     = mbuf_read_str(mb, str, sizeof(str));
+       TEST_ERR(err);
+       TEST_STRCMP(payload, strlen(payload), str, strlen(str));
+
+       /* empty mbuf */
+       err = mbuf_read_str(mb, str, sizeof(str));
+       TEST_EQUALS(err, EOVERFLOW);
+
+       err = 0;
+
+out:
+       mem_deref(mb);
+       return err;
+}
+
+
 int test_mbuf(void)
 {
        int err;
@@ -173,6 +231,9 @@
        err = test_mbuf_ptr();
        TEST_ERR(err);
 
+       err = test_mbuf_str();
+       TEST_ERR(err);
+
 out:
        return err;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/sip.c new/re-4.13.0/test/sip.c
--- old/re-4.12.0/test/sip.c    2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/sip.c    2026-11-04 20:31:42.000000000 +0100
@@ -770,6 +770,51 @@
 }
 
 
+int test_sip_transp_udp_sock(void)
+{
+       struct sip *sip = NULL;
+       struct udp_sock *us;
+       struct sa laddr, local;
+       int err;
+
+       ASSERT_TRUE(sip_transp_udp_sock(NULL) == NULL);
+
+       err = sip_alloc(&sip, NULL, 32, 32, 32, "retest", NULL, NULL);
+       TEST_ERR(err);
+
+       ASSERT_TRUE(sip_transp_udp_sock(sip) == NULL);
+
+       err = sa_set_str(&laddr, "127.0.0.1", 0);
+       TEST_ERR(err);
+
+       /* A TCP transport has no UDP socket */
+       err = sip_transp_add(sip, SIP_TRANSP_TCP, &laddr);
+       TEST_ERR(err);
+       ASSERT_TRUE(sip_transp_udp_sock(sip) == NULL);
+
+       err = sip_transp_add(sip, SIP_TRANSP_UDP, &laddr);
+       TEST_ERR(err);
+
+       us = sip_transp_udp_sock(sip);
+       ASSERT_TRUE(us != NULL);
+
+       /* The socket is the one bound to the UDP transport address */
+       err = udp_local_get(us, &local);
+       TEST_ERR(err);
+       err = sip_transp_laddr(sip, &laddr, SIP_TRANSP_UDP, NULL);
+       TEST_ERR(err);
+       ASSERT_TRUE(sa_cmp(&local, &laddr, SA_ALL));
+
+out:
+       if (sip) {
+               sip_close(sip, false);
+               mem_deref(sip);
+       }
+
+       return err;
+}
+
+
 #ifdef USE_TLS
 struct sip_transp_tls {
        struct sip *sip;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/tcp.c new/re-4.13.0/test/tcp.c
--- old/re-4.12.0/test/tcp.c    2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/tcp.c    2026-11-04 20:31:42.000000000 +0100
@@ -147,6 +147,12 @@
                abort_test(tt, err);
                return;
        }
+
+       err = tcp_conn_set_nodelay(tt->tc2, true);
+       if (err) {
+               abort_test(tt, err);
+               return;
+       }
 }
 
 
@@ -157,6 +163,12 @@
 
        DEBUG_INFO("Client: TCP Established\n");
 
+       err = tcp_conn_set_nodelay(tt->tc, true);
+       if (err) {
+               abort_test(tt, err);
+               return;
+       }
+
        err = send_data(tt->tc, ping);
        if (err)
                abort_test(tt, err);
@@ -219,8 +231,18 @@
        if (err)
                goto out;
 
-       if (tt->err)
+       if (tt->err) {
                err = tt->err;
+               goto out;
+       }
+
+       /* can be switched back, and needs a connection */
+       err = tcp_conn_set_nodelay(tt->tc, false);
+       if (err)
+               goto out;
+
+       if (EINVAL != tcp_conn_set_nodelay(NULL, true))
+               err = EINVAL;
 
  out:
        mem_deref(tt);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/test.c new/re-4.13.0/test/test.c
--- old/re-4.12.0/test/test.c   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/test.c   2026-11-04 20:31:42.000000000 +0100
@@ -205,6 +205,7 @@
        TEST(test_sip_param),
        TEST(test_sip_parse),
        TEST(test_sip_via),
+       TEST(test_sip_transp_udp_sock),
 #ifdef USE_TLS
        TEST(test_sip_transp_add_client_cert),
        TEST(test_sip_transp_wss_verify_host),
@@ -263,6 +264,7 @@
        TEST(test_thread),
        TEST(test_thread_tss),
        TEST(test_trace),
+       TEST(test_tmr_cancel),
        TEST(test_trice_cand),
        TEST(test_trice_candpair),
        TEST(test_trice_checklist),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/test.h new/re-4.13.0/test/test.h
--- old/re-4.12.0/test/test.h   2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/test.h   2026-11-04 20:31:42.000000000 +0100
@@ -318,6 +318,7 @@
 int test_sip_parse(void);
 int test_sip_via(void);
 int test_sip_dns(void);
+int test_sip_transp_udp_sock(void);
 #ifdef USE_TLS
 int test_sip_transp_add_client_cert(void);
 int test_sip_transp_wss_verify_host(void);
@@ -364,6 +365,7 @@
 int test_thread(void);
 int test_thread_cnd_timedwait(void);
 int test_thread_tss(void);
+int test_tmr_cancel(void);
 int test_tmr_jiffies(void);
 int test_tmr_jiffies_usec(void);
 int test_try_into(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/tmr.c new/re-4.13.0/test/tmr.c
--- old/re-4.12.0/test/tmr.c    2026-09-30 19:40:28.000000000 +0200
+++ new/re-4.13.0/test/tmr.c    2026-11-04 20:31:42.000000000 +0100
@@ -48,3 +48,39 @@
 out:
        return err;
 }
+
+
+static void tmr_cancel_handler(void *arg)
+{
+       (void)arg;
+}
+
+
+int test_tmr_cancel(void)
+{
+       struct tmr tmr;
+       int err = 0;
+
+       tmr_init(&tmr);
+       TEST_ASSERT(!tmr_isrunning(&tmr));
+
+       tmr_start(&tmr, 1000, tmr_cancel_handler, NULL);
+       TEST_ASSERT(tmr_isrunning(&tmr));
+       TEST_ASSERT(tmr_get_expire(&tmr) > 0);
+
+       tmr_cancel(&tmr);
+       TEST_ASSERT(!tmr_isrunning(&tmr));
+       TEST_EQUALS(0, tmr_get_expire(&tmr));
+
+       /* a canceled timer can be started and canceled again */
+       tmr_start(&tmr, 1000, tmr_cancel_handler, NULL);
+       TEST_ASSERT(tmr_isrunning(&tmr));
+
+       tmr_cancel(&tmr);
+       TEST_ASSERT(!tmr_isrunning(&tmr));
+
+out:
+       tmr_cancel(&tmr);
+
+       return err;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.12.0/test/valgrind.supp 
new/re-4.13.0/test/valgrind.supp
--- old/re-4.12.0/test/valgrind.supp    1970-01-01 01:00:00.000000000 +0100
+++ new/re-4.13.0/test/valgrind.supp    2026-11-04 20:31:42.000000000 +0100
@@ -0,0 +1,8 @@
+{
+   openssl-3.5-gcm-decryptfinal-false-positive
+   Memcheck:Cond
+   obj:*/libcrypto.so.*
+   obj:*/libcrypto.so.*
+   fun:EVP_DecryptFinal_ex
+   fun:aes_authenticate
+}

Reply via email to