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-04-07 16:34:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/re (Old)
 and      /work/SRC/openSUSE:Factory/.re.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "re"

Tue Apr  7 16:34:13 2026 rev:19 rq:1344903 version:4.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/re/re.changes    2026-03-16 14:19:45.475334978 
+0100
+++ /work/SRC/openSUSE:Factory/.re.new.21863/re.changes 2026-04-07 
16:50:45.109115342 +0200
@@ -1,0 +2,6 @@
+Tue Apr  7 08:09:44 UTC 2026 - Martin Hauke <[email protected]>
+
+- Update to version 4.7.0
+  https://github.com/baresip/re/releases/tag/v4.7.0
+
+-------------------------------------------------------------------

Old:
----
  re-4.6.0.tar.gz

New:
----
  re-4.7.0.tar.gz

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

Other differences:
------------------
++++++ re.spec ++++++
--- /var/tmp/diff_new_pack.MSBeDr/_old  2026-04-07 16:50:45.689139354 +0200
+++ /var/tmp/diff_new_pack.MSBeDr/_new  2026-04-07 16:50:45.689139354 +0200
@@ -17,10 +17,10 @@
 #
 
 
-%global sover   41
+%global sover   42
 %global libname lib%{name}%{sover}
 Name:           re
-Version:        4.6.0
+Version:        4.7.0
 Release:        0
 Summary:        Library for real-time communications with async I/O support
 License:        BSD-3-Clause

++++++ re-4.6.0.tar.gz -> re-4.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/.github/workflows/abi.yml 
new/re-4.7.0/.github/workflows/abi.yml
--- old/re-4.6.0/.github/workflows/abi.yml      2026-03-04 08:17:45.000000000 
+0100
+++ new/re-4.7.0/.github/workflows/abi.yml      2026-04-07 07:18:58.000000000 
+0200
@@ -15,7 +15,7 @@
     steps:
     - uses: actions/checkout@v5
       with:
-          ref: 'v4.3.0'
+          ref: 'v4.6.0'
           path: old
 
     - uses: actions/checkout@v5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/CHANGELOG.md new/re-4.7.0/CHANGELOG.md
--- old/re-4.6.0/CHANGELOG.md   2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/CHANGELOG.md   2026-04-07 07:18:58.000000000 +0200
@@ -5,6 +5,30 @@
 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.7.0 - 2026-04-07
+
+### What's Changed
+* test: use dns_rrlist_apply() in mock DNS-server by @alfredh in 
https://github.com/baresip/re/pull/1532
+* sip: fix missing auth algorithm for known realm by @cspiel1 in 
https://github.com/baresip/re/pull/1535
+* cmake,unixsock: always add unixsock header and functions by @sreimers in 
https://github.com/baresip/re/pull/1536
+* test/dns: save error code from async work in DNS-test by @alfredh in 
https://github.com/baresip/re/pull/1538
+* docs: update list of modules in README.md by @alfredh in 
https://github.com/baresip/re/pull/1537
+* sipsess/modify: fix calling of offer handler by @maximilianfridrich in 
https://github.com/baresip/re/pull/1539
+* http/server: cleanup  of http_verify_msg_d by @cspiel1 in 
https://github.com/baresip/re/pull/1542
+* test: add permission handler to TURN test by @alfredh in 
https://github.com/baresip/re/pull/1541
+* sip/dialog: fix OOM scenarios is sip_dialog_update by @maximilianfridrich in 
https://github.com/baresip/re/pull/1543
+* test/turnsrv: add LIFETIME attribute to allocation response by @alfredh in 
https://github.com/baresip/re/pull/1545
+* test: add testing of websock_tcp() in websock testcases by @alfredh in 
https://github.com/baresip/re/pull/1544
+* test: split turn-test into permissions/channels by @alfredh in 
https://github.com/baresip/re/pull/1547
+* test: add negative testcases in unixsock by @alfredh in 
https://github.com/baresip/re/pull/1546
+* trace: flush operations must not run concurrently by @sreimers in 
https://github.com/baresip/re/pull/1550
+* test,turn: add forced error code and test more combinations by @alfredh in 
https://github.com/baresip/re/pull/1551
+* test: use TEST_ERR() to check async errors in RTCP-test by @alfredh in 
https://github.com/baresip/re/pull/1549
+* test,odict: add testing of more api functions by @alfredh in 
https://github.com/baresip/re/pull/1552
+* ci/abi: bump old version by @sreimers in 
https://github.com/baresip/re/pull/1560
+
+**Full Changelog**: https://github.com/baresip/re/compare/v4.6.0...v4.7.0
+
 
 ## v4.6.0 - 2026-03-04
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/CMakeLists.txt new/re-4.7.0/CMakeLists.txt
--- old/re-4.6.0/CMakeLists.txt 2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/CMakeLists.txt 2026-04-07 07:18:58.000000000 +0200
@@ -14,13 +14,13 @@
 cmake_minimum_required(VERSION 3.18...4.0)
 
 project(re
-  VERSION 4.6.0
+  VERSION 4.7.0
   LANGUAGES C
   HOMEPAGE_URL https://github.com/baresip/re
   DESCRIPTION "Generic library for real-time communications"
 )
 
-set(PROJECT_SOVERSION 41) # bump if ABI breaks
+set(PROJECT_SOVERSION 42) # bump if ABI breaks
 
 # Pre-release identifier, comment out on a release
 # Increment for breaking changes (dev2, dev3...)
@@ -184,6 +184,7 @@
   include/re_turn.h
   include/re_types.h
   include/re_udp.h
+  include/re_unixsock.h
   include/re_uri.h
   include/re_websock.h
   include/rem_aac.h
@@ -211,11 +212,6 @@
   include/rem_vidmix.h
 )
 
-if(USE_UNIXSOCK)
-  list(APPEND HEADERS
-    include/re_unixsock.h
-  )
-endif()
 
 set(SRCS
 
@@ -407,6 +403,7 @@
 
   src/udp/mcast.c
   src/udp/udp.c
+  src/unixsock/unixsock.c
 
   src/uri/uri.c
   src/uri/uric.c
@@ -440,11 +437,6 @@
   rem/vidmix/vidmix.c
 )
 
-if(USE_UNIXSOCK)
-  list(APPEND SRCS
-    src/unixsock/unixsock.c
-  )
-endif()
 
 if(USE_BFCP)
   list(APPEND SRCS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/README.md new/re-4.7.0/README.md
--- old/re-4.6.0/README.md      2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/README.md      2026-04-07 07:18:58.000000000 +0200
@@ -111,13 +111,18 @@
 |----------|----------|------------------------------------------------|
 | aes      | stable   | AES (Advanced Encryption Standard)             |
 | async    | testing  | Async module                                   |
+| av1      | testing  | AV1 Packetizer                                 |
 | base64   | stable   | Base-64 encoding/decoding functions            |
 | bfcp     | stable   | The Binary Floor Control Protocol (BFCP)       |
+| btrace   | testing  | Backtrace module                               |
 | conf     | stable   | Configuration file parser                      |
 | crc32    | stable   | 32-bit CRC defined in ITU V.42                 |
 | dbg      | stable   | Debug printing                                 |
+| dd       | testing  | Dependency Descriptor                          |
 | dns      | stable   | DNS resolving (NAPTR, SRV, A)                  |
 | fmt      | stable   | Formatted printing and regular expression      |
+| h264     | testing  | H.264 packetizer                               |
+| h265     | testing  | H.265 packetizer                               |
 | hash     | stable   | Hashmap table                                  |
 | hmac     | stable   | HMAC: Keyed-Hashing for Message Authentication |
 | http     | stable   | HTTP parser (RFC 2616)                         |
@@ -134,8 +139,10 @@
 | msg      | stable   | Generic message component library              |
 | net      | stable   | Networking routines                            |
 | odict    | stable   | Ordered Dictionary                             |
+| pcp      | testing  | Port Control Protocol                          |
 | rtmp     | stable   | Real Time Messaging Protocol                   |
 | rtp      | stable   | Real-time Transport Protocol                   |
+| rtpext   | testing  | RTP extensions                                 |
 | sa       | stable   | Socket Address functions                       |
 | sdp      | stable   | Session Description Protocol                   |
 | sha      | stable   | Secure Hash Standard, NIST, FIPS PUB 180-1     |
@@ -153,6 +160,7 @@
 | tmr      | stable   | Timer handling                                 |
 | turn     | stable   | Obtaining Relay Addresses from STUN (TURN)     |
 | trace    | testing  | Trace Helpers JSON traces (chrome://tracing)   |
+| trice    | testing  | Trickle ICE                                    |
 | udp      | stable   | UDP transport                                  |
 | unixsock | testing  | Unix domain sockets                            |
 | uri      | stable   | Generic URI library                            |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/mk/Doxyfile new/re-4.7.0/mk/Doxyfile
--- old/re-4.6.0/mk/Doxyfile    2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/mk/Doxyfile    2026-04-07 07:18:58.000000000 +0200
@@ -4,7 +4,7 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = libre
-PROJECT_NUMBER         = 4.6.0
+PROJECT_NUMBER         = 4.7.0
 OUTPUT_DIRECTORY       = ../re-dox
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/http/server.c 
new/re-4.7.0/src/http/server.c
--- old/re-4.6.0/src/http/server.c      2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/src/http/server.c      2026-04-07 07:18:58.000000000 +0200
@@ -43,7 +43,7 @@
        struct tcp_conn *tc;
        struct tls_conn *sc;
        struct mbuf *mb;
-       struct tmr verify_cert_tmr;
+       struct http_verify_msg_d *verify_msg_d;
 };
 
 
@@ -76,7 +76,7 @@
 
        list_unlink(&conn->le);
        tmr_cancel(&conn->tmr);
-       tmr_cancel(&conn->verify_cert_tmr);
+       mem_deref(conn->verify_msg_d);
        mem_deref(conn->sc);
        mem_deref(conn->tc);
        mem_deref(conn->mb);
@@ -87,7 +87,7 @@
 {
        list_unlink(&conn->le);
        tmr_cancel(&conn->tmr);
-       tmr_cancel(&conn->verify_cert_tmr);
+       conn->verify_msg_d = mem_deref(conn->verify_msg_d);
        conn->sc = mem_deref(conn->sc);
        conn->tc = mem_deref(conn->tc);
        conn->sock = NULL;
@@ -110,12 +110,14 @@
        int err;
        int scode;
        const char *reason;
+       struct tmr tmr;
 };
 
 
 static void verify_msg_destructor(void *arg)
 {
        struct http_verify_msg_d *d = arg;
+       tmr_cancel(&d->tmr);
        mem_deref(d->msg);
 }
 
@@ -123,13 +125,14 @@
 static void verify_cert_done(void *arg)
 {
        struct http_verify_msg_d *d = arg;
+       struct http_conn *conn = d->conn;
 
        if (d->err)
-               http_ereply(d->conn, d->scode, d->reason);
+               http_ereply(conn, d->scode, d->reason);
        else
-               d->conn->sock->reqh(d->conn, d->msg, d->conn->sock->arg);
+               conn->sock->reqh(conn, d->msg, conn->sock->arg);
 
-       mem_deref(arg);
+       conn->verify_msg_d = mem_deref(d);
 }
 
 
@@ -146,8 +149,7 @@
                d->reason = "Forbidden";
        }
 
-       tmr_start(&d->conn->verify_cert_tmr, 1, verify_cert_done, d);
-
+       tmr_start(&d->tmr, 1, verify_cert_done, d);
        return ok;
 }
 
@@ -179,8 +181,9 @@
                d->reason = "Request Timeout";
                d->msg = msg;
 
-               tmr_start(&conn->verify_cert_tmr, TIMEOUT_IDLE,
-                       verify_cert_done, d);
+               mem_deref(conn->verify_msg_d);
+               conn->verify_msg_d = d;
+               tmr_start(&d->tmr, TIMEOUT_IDLE, verify_cert_done, d);
 
                int err = tls_set_verify_client_handler(http_conn_tls(conn),
                        -1, http_verify_handler, d);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/sip/auth.c new/re-4.7.0/src/sip/auth.c
--- old/re-4.6.0/src/sip/auth.c 2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/src/sip/auth.c 2026-04-07 07:18:58.000000000 +0200
@@ -222,7 +222,6 @@
                realm->nonce     = mem_deref(realm->nonce);
                realm->qop       = mem_deref(realm->qop);
                realm->opaque    = mem_deref(realm->opaque);
-               realm->algorithm = mem_deref(realm->algorithm);
        }
 
        realm->hdr = hdr->id;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/sip/dialog.c 
new/re-4.7.0/src/sip/dialog.c
--- old/re-4.6.0/src/sip/dialog.c       2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/src/sip/dialog.c       2026-04-07 07:18:58.000000000 +0200
@@ -490,8 +490,10 @@
                return err;
 
        mb = mbuf_alloc(512);
-       if (!mb)
-               return ENOMEM;
+       if (!mb) {
+               err = ENOMEM;
+               goto out;
+       }
 
        err = mbuf_write_mem(mb, mbuf_buf(dlg->mb), dlg->rpos);
        err |= mbuf_printf(mb, "To: %r\r\n",
@@ -506,10 +508,10 @@
        dlg->cpos = cpos;
        mb->pos = 0;
 
-       mem_deref(dlg->rtag);
+       dlg->rtag = mem_deref(dlg->rtag);
        err = pl_strdup(&dlg->rtag, msg->req ? &msg->from.tag : &msg->to.tag);
        if (err)
-               return err;
+               goto out;
 
        mem_deref(dlg->mb);
        dlg->mb = mem_ref(mb);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/sipsess/modify.c 
new/re-4.7.0/src/sipsess/modify.c
--- old/re-4.6.0/src/sipsess/modify.c   2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/src/sipsess/modify.c   2026-04-07 07:18:58.000000000 +0200
@@ -51,7 +51,7 @@
                                sess->neg_state = SDP_NEG_DONE;
                                err = sess->answerh(msg, sess->arg);
                        }
-                       else if (sess->neg_state == SDP_NEG_NONE) {
+                       else if (sess->neg_state == SDP_NEG_DONE) {
                                sess->neg_state = SDP_NEG_REMOTE_OFFER;
                                err = sess->offerh(&desc, msg, sess->arg);
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/trace/trace.c 
new/re-4.7.0/src/trace/trace.c
--- old/re-4.6.0/src/trace/trace.c      2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/src/trace/trace.c      2026-04-07 07:18:58.000000000 +0200
@@ -63,6 +63,7 @@
        bool new;
        uint64_t start_time;
        struct tmr flush_tmr;
+       bool flush_active;
 } trace = {
        .init = false
 };
@@ -101,13 +102,6 @@
 {
        (void)arg;
 
-       mtx_lock(&trace.lock);
-       if (trace.event_count < TRACE_FLUSH_THRESHOLD) {
-               mtx_unlock(&trace.lock);
-               return 0;
-       }
-       mtx_unlock(&trace.lock);
-
        re_trace_flush();
 
        return 0;
@@ -118,7 +112,12 @@
 {
        (void)arg;
 
-       re_thread_async(flush_worker, NULL, NULL);
+       mtx_lock(&trace.lock);
+       if (!trace.flush_active &&
+           trace.event_count >= TRACE_FLUSH_THRESHOLD) {
+               re_thread_async(flush_worker, NULL, NULL);
+       }
+       mtx_unlock(&trace.lock);
 
        tmr_start(&trace.flush_tmr, TRACE_FLUSH_TMR, flush_tmr, NULL);
 }
@@ -251,6 +250,13 @@
                return 0;
 
        mtx_lock(&trace.lock);
+       if (trace.flush_active) {
+               mtx_unlock(&trace.lock);
+               return EALREADY;
+       }
+
+       trace.flush_active = true;
+
        struct re_trace_event_s *event_tmp = trace.event_buffer_flush;
        trace.event_buffer_flush = trace.event_buffer;
        trace.event_buffer = event_tmp;
@@ -344,6 +350,10 @@
        mem_deref(mb);
        (void)fflush(trace.f);
 
+       mtx_lock(&trace.lock);
+       trace.flush_active = false;
+       mtx_unlock(&trace.lock);
+
        return err;
 #else
        return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/src/unixsock/unixsock.c 
new/re-4.7.0/src/unixsock/unixsock.c
--- old/re-4.6.0/src/unixsock/unixsock.c        2026-03-04 08:17:45.000000000 
+0100
+++ new/re-4.7.0/src/unixsock/unixsock.c        2026-04-07 07:18:58.000000000 
+0200
@@ -35,6 +35,7 @@
  */
 int unixsock_listen_fd(re_sock_t *fdp, const struct sa *sock)
 {
+#if HAVE_UNIXSOCK
        int err = 0;
        re_sock_t fd;
 
@@ -80,4 +81,9 @@
        }
 
        return err;
+#else
+       (void)fdp;
+       (void)sock;
+       return ENOTSUP;
+#endif
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/dns.c new/re-4.7.0/test/dns.c
--- old/re-4.6.0/test/dns.c     2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/dns.c     2026-04-07 07:18:58.000000000 +0200
@@ -803,6 +803,7 @@
        uint32_t srvc;
        unsigned answers;
        int proto;
+       int err;
 };
 
 
@@ -820,6 +821,7 @@
 
        if (err) {
                DEBUG_WARNING("dns query error: %m\n", err);
+               fix->err = err;
                re_cancel();
                return;
        }
@@ -838,6 +840,7 @@
 
  out:
        if (fix->answers >= EXPECTED_ANSWERS || err) {
+               fix->err = err;
                re_cancel();
        }
 }
@@ -883,6 +886,9 @@
        err = re_main_timeout(5000);
        TEST_ERR(err);
 
+       err = fix.err;
+       TEST_ERR(err);
+
        ASSERT_TRUE(fix.answers >= EXPECTED_ANSWERS);
 
  out:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/mock/dnssrv.c 
new/re-4.7.0/test/mock/dnssrv.c
--- old/re-4.6.0/test/mock/dnssrv.c     2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/mock/dnssrv.c     2026-04-07 07:18:58.000000000 +0200
@@ -16,25 +16,13 @@
 #define LOCAL_PORT 0
 
 
-static void dns_server_match(struct dns_server *srv, struct list *rrl,
-                            const char *name, uint16_t type)
+static bool rrlist_handler(struct dnsrr *rr, void *arg)
 {
-       struct dnsrr *rr0 = NULL;
-       struct le *le;
-
-       le = srv->rrl.head;
-       while (le) {
+       struct list *rrl = arg;
 
-               struct dnsrr *rr = le->data;
-               le               = le->next;
+       list_append(rrl, &rr->le_priv, rr);
 
-               if (type == rr->type && 0 == str_casecmp(name, rr->name)) {
-
-                       if (!rr0)
-                               rr0 = rr;
-                       list_append(rrl, &rr->le_priv, rr);
-               }
-       }
+       return false;
 }
 
 
@@ -75,7 +63,8 @@
                   qname);
 
        if (dnsclass == DNS_CLASS_IN) {
-               dns_server_match(srv, &rrl, qname, type);
+               dns_rrlist_apply(&srv->rrl, qname, type, DNS_CLASS_IN,
+                                hdr.rd, rrlist_handler, &rrl);
        }
 
        hdr.qr    = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/mock/turnsrv.c 
new/re-4.7.0/test/mock/turnsrv.c
--- old/re-4.6.0/test/mock/turnsrv.c    2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/mock/turnsrv.c    2026-04-07 07:18:58.000000000 +0200
@@ -121,10 +121,16 @@
 
                mb->pos = start;
 
-               err = udp_send(turn->us, &turn->cli, mb);
+               if (turn->tc)
+                       err = tcp_send(turn->tc, mb);
+               else
+                       err = udp_send(turn->us, &turn->cli, mb);
        }
        else {
-               err = stun_indication(IPPROTO_UDP, turn->us,
+               int proto = turn->tc ? IPPROTO_TCP : IPPROTO_UDP;
+               void *sock = turn->tc ? (void *)turn->tc : (void *)turn->us;
+
+               err = stun_indication(proto, sock,
                                      &turn->cli, 0, STUN_METHOD_DATA,
                                      NULL, 0, false, 2,
                                      STUN_ATTR_XOR_PEER_ADDR, src,
@@ -233,6 +239,20 @@
                goto unauth;
        }
 
+       if (turn->error_scode) {
+
+               err = stun_ereply(proto, sock, src, 0, msg,
+                                 turn->error_scode, "Error",
+                                 NULL, 0, false, 2,
+                                 STUN_ATTR_REALM, turn->auth_realm,
+                                 STUN_ATTR_NONCE,
+                                   mknonce(turn, nstr, now, src));
+
+               turn->error_scode = 0;
+
+               goto unauth;
+       }
+
        if (!user || !realm || !nonce) {
                err = stun_ereply(proto, sock, src, 0, msg,
                                  400, "Bad Request",
@@ -294,6 +314,7 @@
        struct stun_msg *msg = NULL;
        struct sa laddr;
        int err = 0;
+       const uint32_t alloc_lifetime = TURN_DEFAULT_LIFETIME;
 
        if (stun_msg_decode(&msg, mb, NULL)) {
 
@@ -367,9 +388,10 @@
 
                err = stun_reply(proto, sock, src, 0,
                                 msg, ctx.key, ctx.keylen, false,
-                                2,
+                                3,
                                 STUN_ATTR_XOR_MAPPED_ADDR, src,
-                                STUN_ATTR_XOR_RELAY_ADDR, &turn->relay);
+                                STUN_ATTR_XOR_RELAY_ADDR, &turn->relay,
+                                STUN_ATTR_LIFETIME, &alloc_lifetime);
                break;
 
        case STUN_METHOD_CREATEPERM: {
@@ -655,3 +677,12 @@
 
        return err;
 }
+
+
+void turnserver_force_error(struct turnserver *turn, uint16_t scode)
+{
+       if (!turn)
+               return;
+
+       turn->error_scode = scode;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/odict.c new/re-4.7.0/test/odict.c
--- old/re-4.6.0/test/odict.c   2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/odict.c   2026-04-07 07:18:58.000000000 +0200
@@ -95,16 +95,20 @@
                },
        };
        struct odict *dict = NULL;
+       char *debug_str = NULL;
        size_t i;
        int err;
 
        TEST_ASSERT(odict_type_iscontainer(ODICT_OBJECT));
        TEST_ASSERT(odict_type_iscontainer(ODICT_ARRAY));
+       TEST_ASSERT(!odict_type_iscontainer(ODICT_INT));
+
        TEST_ASSERT(odict_type_isreal(ODICT_INT));
        TEST_ASSERT(odict_type_isreal(ODICT_DOUBLE));
        TEST_ASSERT(odict_type_isreal(ODICT_STRING));
        TEST_ASSERT(odict_type_isreal(ODICT_BOOL));
        TEST_ASSERT(odict_type_isreal(ODICT_NULL));
+       TEST_ASSERT(!odict_type_isreal(ODICT_OBJECT));
 
        err = odict_alloc(&dict, 64);
        if (err)
@@ -162,17 +166,18 @@
        /* compare dictionary with itself */
        TEST_ASSERT(odict_compare(dict, dict, false));
 
+       err = re_sdprintf(&debug_str, "%H", odict_debug, dict);
+       TEST_ERR(err);
+       ASSERT_TRUE(str_isset(debug_str));
+
        /* remove all entries */
        for (i=0; i<RE_ARRAY_SIZE(testv); i++) {
 
                const struct dtest *test = &testv[i];
                struct odict_entry *e;
 
-               e = (struct odict_entry *)odict_lookup(dict, test->key);
-               TEST_ASSERT(e != NULL);
-
                /* delete entry from dictionary */
-               mem_deref(e);
+               odict_entry_del(dict, test->key);
 
                /* entry should not exist anymore */
                e = (struct odict_entry *)odict_lookup(dict, test->key);
@@ -183,6 +188,7 @@
        TEST_EQUALS(0, odict_count(dict, false));
 
  out:
+       mem_deref(debug_str);
        mem_deref(dict);
        return err;
 }
@@ -263,6 +269,14 @@
        TEST_EQUALS(ODICT_INT, odict_entry_type(e));
        TEST_EQUALS(3LL, odict_entry_int(e));
 
+       uint64_t num = 0;
+       bool ret = odict_get_number(arr, &num, "1");
+       ASSERT_TRUE(ret);
+       ASSERT_EQ(1, num);
+
+       ret = odict_get_number(arr, &num, "hei");
+       ASSERT_TRUE(!ret);
+
 #if 0
        re_printf("%H\n", odict_debug, arr);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/rtcp.c new/re-4.7.0/test/rtcp.c
--- old/re-4.6.0/test/rtcp.c    2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/rtcp.c    2026-04-07 07:18:58.000000000 +0200
@@ -445,8 +445,10 @@
        err = re_main_timeout(1000);
        TEST_ERR(err);
 
-       ASSERT_EQ(0, a.err);
-       ASSERT_EQ(0, b.err);
+       err = a.err;
+       TEST_ERR(err);
+       err = b.err;
+       TEST_ERR(err);
 
        ASSERT_TRUE(a.rtp_count >= 1);
        ASSERT_EQ(2, a.psfb_count);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/test.h new/re-4.7.0/test/test.h
--- old/re-4.6.0/test/test.h    2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/test.h    2026-04-07 07:18:58.000000000 +0200
@@ -467,6 +467,7 @@
        char addr[64];
        const char *auth_realm;
        uint64_t auth_secret;
+       uint16_t error_scode;
 
        struct channel {
                uint16_t nr;
@@ -486,6 +487,7 @@
 };
 
 int turnserver_alloc(struct turnserver **turnp, const char *addr);
+void turnserver_force_error(struct turnserver *turn, uint16_t scode);
 
 
 enum natbox_type {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/turn.c new/re-4.7.0/test/turn.c
--- old/re-4.6.0/test/turn.c    2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/turn.c    2026-04-07 07:18:58.000000000 +0200
@@ -39,8 +39,10 @@
        mtx_t *mtx;
        int proto;
        int err;
+       bool use_chan;
 
        size_t n_alloc_resp;
+       size_t n_perm_resp;
        size_t n_chan_resp;
        size_t n_peer_recv;
 };
@@ -67,7 +69,8 @@
 
 static bool is_complete(struct turntest *tt)
 {
-       return tt->n_chan_resp >= 1 && tt->n_peer_recv >= 2;
+       return (tt->use_chan ? tt->n_chan_resp >= 1 : tt->n_perm_resp >= 1)
+               && tt->n_peer_recv >= 2;
 }
 
 
@@ -99,7 +102,7 @@
        switch (tt->proto) {
 
        case IPPROTO_UDP:
-               err = udp_send(tt->us_cli, dst, mb);
+               err = turnc_send(tt->turnc, dst, mb);
                break;
 
        case IPPROTO_TCP:
@@ -114,17 +117,32 @@
 }
 
 
+static void turnc_perm_handler(void *arg)
+{
+       struct turntest *tt = arg;
+
+       ++tt->n_perm_resp;
+
+       /* Headroom for IPv4/IPv6 STUN headers */
+       const size_t offset = 48;
+
+       int err = send_payload(tt, offset, &tt->peer, test_payload);
+       if (err) {
+               DEBUG_WARNING("failed to send payload (%m)\n", err);
+               complete_test(tt, err);
+       }
+}
+
+
 static void turnc_chan_handler(void *arg)
 {
        struct turntest *tt = arg;
-       int err = 0;
 
        ++tt->n_chan_resp;
 
-       err |= send_payload(tt, 4, &tt->peer, test_payload);
+       int err = send_payload(tt, 4, &tt->peer, test_payload);
        if (err) {
                DEBUG_WARNING("failed to send payload (%m)\n", err);
-               complete_test(tt, err);
        }
 
        if (err)
@@ -157,24 +175,32 @@
        TEST_SACMP(&tt->turnsrv->relay, relay_addr, SA_ALL);
        TEST_SACMP(&tt->cli, mapped_addr, SA_ALL);
 
-       /* Permission is needed for sending data */
-       err = turnc_add_perm(tt->turnc, &tt->peer, NULL, NULL);
-       if (err)
-               goto out;
+       if (tt->use_chan) {
 
-       /* Headroom for IPv4/IPv6 STUN headers */
-       const size_t offset = 48;
+               err = turnc_add_chan(tt->turnc, &tt->peer,
+                                    turnc_chan_handler, tt);
+               if (err)
+                       goto out;
 
-       err |= send_payload(tt, offset, &tt->peer, test_payload);
-       if (err) {
-               DEBUG_WARNING("failed to send payload (%m)\n", err);
-               complete_test(tt, err);
+               err = turnc_add_chan(tt->turnc, &tt->peer,
+                                    turnc_chan_handler, tt);
+               if (err)
+                       goto out;
        }
+       else {
+               turnserver_force_error(tt->turnsrv, 401);
 
-       err = turnc_add_chan(tt->turnc, &tt->peer,
-                            turnc_chan_handler, tt);
-       if (err)
-               goto out;
+               /* Permission is needed for sending data */
+               err = turnc_add_perm(tt->turnc, &tt->peer,
+                                    turnc_perm_handler, tt);
+               if (err)
+                       goto out;
+
+               err = turnc_add_perm(tt->turnc, &tt->peer,
+                                    turnc_perm_handler, tt);
+               if (err)
+                       goto out;
+       }
 
  out:
        if (err)
@@ -225,10 +251,10 @@
 }
 
 
-static void data_handler(struct turntest *tt, struct mbuf *mb)
+static void data_handler(struct turntest *tt, struct sa *src, struct mbuf *mb)
 {
-       (void)tt;
-       (void)mb;
+       /* echo data */
+       turnc_send(tt->turnc, src, mb);
 }
 
 
@@ -312,7 +338,7 @@
                        goto out;
 
                if (mbuf_get_left(tl->mb))
-                       data_handler(tl, tl->mb);
+                       data_handler(tl, &src, tl->mb);
 
                /* 4 byte alignment */
                while (len & 0x03)
@@ -421,7 +447,7 @@
 }
 
 
-static int test_turn_param(const char *addr)
+static int test_turn_param(const char *addr, bool use_chan)
 {
        struct turntest *tt;
        int err;
@@ -430,6 +456,8 @@
        if (err)
                return err;
 
+       tt->use_chan = use_chan;
+
        err = re_main_timeout(200);
        TEST_ERR(err);
 
@@ -439,13 +467,29 @@
        /* verify results after test is complete */
 
        TEST_EQUALS(1, tt->n_alloc_resp);
-       TEST_EQUALS(1, tt->n_chan_resp);
-       TEST_EQUALS(2, tt->n_peer_recv);
+
+       if (use_chan) {
+               TEST_EQUALS(0, tt->n_perm_resp);
+               TEST_EQUALS(1, tt->n_chan_resp);
+       }
+       else {
+               TEST_EQUALS(1, tt->n_perm_resp);
+               TEST_EQUALS(0, tt->n_chan_resp);
+       }
 
        TEST_ASSERT(tt->turnsrv->n_allocate >= 1);
-       TEST_ASSERT(tt->turnsrv->n_chanbind >= 1);
-       TEST_ASSERT(tt->turnsrv->n_raw >= 1);
-       TEST_EQUALS(1, tt->turnsrv->n_send);
+       TEST_EQUALS(2, tt->n_peer_recv);
+
+       if (use_chan) {
+               TEST_ASSERT(tt->turnsrv->n_chanbind >= 1);
+               TEST_ASSERT(tt->turnsrv->n_raw >= 1);
+               TEST_EQUALS(0, tt->turnsrv->n_send);
+       }
+       else {
+               TEST_EQUALS(0, tt->turnsrv->n_chanbind);
+               TEST_EQUALS(0, tt->turnsrv->n_raw);
+               TEST_EQUALS(2, tt->turnsrv->n_send);
+       }
 
  out:
        mem_deref(tt);
@@ -456,11 +500,17 @@
 
 int test_turn(void)
 {
-       int err = test_turn_param("127.0.0.1");
+       int err = test_turn_param("127.0.0.1", false);
+       TEST_ERR(err);
+
+       err = test_turn_param("127.0.0.1", true);
        TEST_ERR(err);
 
        if (test_ipv6_supported()) {
-               err = test_turn_param("::1");
+               err = test_turn_param("::1", false);
+               TEST_ERR(err);
+
+               err = test_turn_param("::1", true);
                TEST_ERR(err);
        }
 
@@ -469,15 +519,17 @@
 }
 
 
-int test_turn_tcp(void)
+static int test_turn_param_tcp(const char *addr, bool use_chan)
 {
        struct turntest *tt;
        int err;
 
-       err = turntest_alloc(&tt, IPPROTO_TCP, 600, "127.0.0.1");
+       err = turntest_alloc(&tt, IPPROTO_TCP, 600, addr);
        if (err)
                return err;
 
+       tt->use_chan = use_chan;
+
        err = re_main_timeout(200);
        TEST_ERR(err);
 
@@ -487,13 +539,29 @@
        /* verify results after test is complete */
 
        TEST_EQUALS(1, tt->n_alloc_resp);
-       TEST_EQUALS(1, tt->n_chan_resp);
-       TEST_EQUALS(2, tt->n_peer_recv);
+
+       if (use_chan) {
+               TEST_EQUALS(0, tt->n_perm_resp);
+               TEST_EQUALS(1, tt->n_chan_resp);
+       }
+       else {
+               TEST_EQUALS(1, tt->n_perm_resp);
+               TEST_EQUALS(0, tt->n_chan_resp);
+       }
 
        TEST_ASSERT(tt->turnsrv->n_allocate >= 1);
-       TEST_ASSERT(tt->turnsrv->n_chanbind >= 1);
-       TEST_ASSERT(tt->turnsrv->n_raw >= 1);
-       TEST_EQUALS(1, tt->turnsrv->n_send);
+       TEST_EQUALS(2, tt->n_peer_recv);
+
+       if (use_chan) {
+               TEST_ASSERT(tt->turnsrv->n_chanbind >= 1);
+               TEST_ASSERT(tt->turnsrv->n_raw >= 1);
+               TEST_EQUALS(0, tt->turnsrv->n_send);
+       }
+       else {
+               TEST_EQUALS(0, tt->turnsrv->n_chanbind);
+               TEST_EQUALS(0, tt->turnsrv->n_raw);
+               TEST_EQUALS(2, tt->turnsrv->n_send);
+       }
 
  out:
        mem_deref(tt);
@@ -501,6 +569,29 @@
        return err;
 }
 
+
+int test_turn_tcp(void)
+{
+       int err;
+
+       err = test_turn_param_tcp("127.0.0.1", false);
+       TEST_ERR(err);
+
+       err = test_turn_param_tcp("127.0.0.1", true);
+       TEST_ERR(err);
+
+       if (test_ipv6_supported()) {
+               err = test_turn_param_tcp("::1", false);
+               TEST_ERR(err);
+
+               err = test_turn_param_tcp("::1", true);
+               TEST_ERR(err);
+       }
+
+ out:
+       return err;
+}
+
 
 static void tmr_handler(void *arg)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/unixsock.c new/re-4.7.0/test/unixsock.c
--- old/re-4.6.0/test/unixsock.c        2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/unixsock.c        2026-04-07 07:18:58.000000000 +0200
@@ -56,11 +56,25 @@
        err = unlink(&socket[5]);
        TEST_ERR(err);
 
+       int error = unixsock_listen_fd(NULL, NULL);
+       ASSERT_EQ(EINVAL, error);
+
+       re_sock_t fd_dummy = RE_BAD_SOCK;
+       struct sa sa_dummy;
+       sa_set_str(&sa_dummy, "1.2.3.4", 1234);
+       error = unixsock_listen_fd(&fd_dummy, &sa_dummy);
+       ASSERT_EQ(EINVAL, error);
+
 out:
        if (err)
                (void)unlink(&socket[5]);
        return err;
 #else
-       return ESKIPPED;
+       int err = unixsock_listen_fd(NULL, NULL);
+       TEST_EQUALS(ENOTSUP, err);
+
+       return 0;
+out:
+       return err;
 #endif
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re-4.6.0/test/websock.c new/re-4.7.0/test/websock.c
--- old/re-4.6.0/test/websock.c 2026-03-04 08:17:45.000000000 +0100
+++ new/re-4.7.0/test/websock.c 2026-04-07 07:18:58.000000000 +0200
@@ -123,9 +123,13 @@
        struct test *test = arg;
        int err;
 
+       ASSERT_TRUE(NULL != websock_tcp(test->wc_cli));
+
        test->n_estab_cli++;
 
        err = websock_send(test->wc_cli, WEBSOCK_TEXT, test_payload);
+
+ out:
        if (err)
                abort_test(test, err);
 }

Reply via email to