diff --git a/.github/workflows/abi.yml b/.github/workflows/abi.yml index e3792a5ab..3926a9084 100644 --- a/.github/workflows/abi.yml +++ b/.github/workflows/abi.yml @@ -1,6 +1,12 @@ name: ABI Checks -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: abicheck: diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index fc73f06a5..a1b2cb479 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,6 +1,15 @@ name: Android -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main + +env: + openssl: 3.2.1 jobs: android: @@ -9,11 +18,18 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/cache@v4 + id: openssl + with: + path: openssl + key: ${{ runner.os }}-android-openssl-${{ env.openssl }} + - name: "build openssl" + if: steps.openssl.outputs.cache-hit != 'true' run: | - wget -q https://www.openssl.org/source/openssl-3.2.0.tar.gz - tar -xzf openssl-3.2.0.tar.gz - mv openssl-3.2.0 openssl + wget -q https://www.openssl.org/source/openssl-$openssl.tar.gz + tar -xzf openssl-$openssl.tar.gz + mv openssl-$openssl openssl cd openssl && ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME PATH=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH ./Configure android-arm64 no-shared no-tests -U__ANDROID_API__ -D__ANDROID_API__=21 && PATH=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH make build_libs && cd .. - name: build diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index cf5baf6fb..5d4e1dd44 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: cpp queries: security-extended @@ -34,5 +34,5 @@ jobs: cmake -B build && cmake --build build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 75fa3e069..6415e43dc 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -1,6 +1,12 @@ name: iOS -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: ios: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 68d68d01a..fe39d96e4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,12 @@ name: lint -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: lint: diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 64d765139..2b6a1f95f 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -1,6 +1,12 @@ name: MinGW-w64 Test -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: MinGW-w64-build: @@ -32,7 +38,7 @@ jobs: with: path: baresip-win32/re - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: openssl with: path: baresip-win32/openssl @@ -50,7 +56,7 @@ jobs: run: | cd baresip-win32 && make retest - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: retest-exe path: baresip-win32/re/build/test/retest.exe @@ -62,7 +68,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 - uses: sreimers/pr-dependency-action@v0.6 with: name: re diff --git a/.github/workflows/run-on-arch.yml b/.github/workflows/run-on-arch.yml index 6be3488ce..5a2c66137 100644 --- a/.github/workflows/run-on-arch.yml +++ b/.github/workflows/run-on-arch.yml @@ -1,4 +1,10 @@ -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: build_job: diff --git a/.github/workflows/ssl.yml b/.github/workflows/ssl.yml index 510346c89..39822f776 100644 --- a/.github/workflows/ssl.yml +++ b/.github/workflows/ssl.yml @@ -1,6 +1,12 @@ name: OpenSSL no-deprecated and LibreSSL -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: ssl: diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml index 6cfa3a44e..201a5fa15 100644 --- a/.github/workflows/valgrind.yml +++ b/.github/workflows/valgrind.yml @@ -1,6 +1,12 @@ name: valgrind leak check -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: valgrind: diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f299ab1..e8fc0b66c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,39 @@ 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). +## [v3.9.0] - 2024-01-31 + +## What's Changed +* http: fix doxygen by @cspiel1 in https://github.com/baresip/re/pull/1033 +* types: remove old ARRAY_SIZE macro by @alfredh in https://github.com/baresip/re/pull/1034 +* cmake: bump minimum to version 3.14 by @alfredh in https://github.com/baresip/re/pull/1030 +* test: use re_is_aligned() by @alfredh in https://github.com/baresip/re/pull/1035 +* sipsess: refactor and simplify SDP negotiation state by @maximilianfridrich in https://github.com/baresip/re/pull/1016 +* bump year by @sreimers in https://github.com/baresip/re/pull/1038 +* cmake,pc: fix static library build by @alfredh in https://github.com/baresip/re/pull/1036 +* rx thread activate by @cspiel1 in https://github.com/baresip/re/pull/1037 +* test: fix cppcheck warnings by @alfredh in https://github.com/baresip/re/pull/1040 +* test: move test_rtcp_decode_badmsg() to separate testcase by @alfredh in https://github.com/baresip/re/pull/1041 +* rtp: lock more fields from rtcp_sess by @cspiel1 in https://github.com/baresip/re/pull/1039 +* rtp: lock rtcp_set_srate() by @cspiel1 in https://github.com/baresip/re/pull/1043 +* test: HAVE_INET6 is always defined by @alfredh in https://github.com/baresip/re/pull/1046 +* ci: add run-on-arch for ARM64 linux by @alfredh in https://github.com/baresip/re/pull/1045 +* httpauth: digest verification rfc 7616 by @cHuberCoffee in https://github.com/baresip/re/pull/1044 +* tmr: prevent race condition on cancel by @sreimers in https://github.com/baresip/re/pull/1048 +* aubuf: fix coverity defect by @alfredh in https://github.com/baresip/re/pull/1051 +* btrace: fix coverity warning by @alfredh in https://github.com/baresip/re/pull/1049 +* ci/win: downgrade openssl by @sreimers in https://github.com/baresip/re/pull/1054 +* docs: update README by @alfredh in https://github.com/baresip/re/pull/1053 +* http: client - set scopeid fixes HTTP requests for IPv6ll by @cspiel1 in https://github.com/baresip/re/pull/1055 +* rtp: add rtp_source_ prefix to RTP source api by @alfredh in https://github.com/baresip/re/pull/1052 +* rtp: make struct rtp_source public by @alfredh in https://github.com/baresip/re/pull/1057 +* rtp: sess - fix coverity warning by @cspiel1 in https://github.com/baresip/re/pull/1058 +* mk: bump version to 3.9.0 by @alfredh in https://github.com/baresip/re/pull/1060 + + +**Full Changelog**: https://github.com/baresip/re/compare/v3.8.0...v3.9.0 + + ## [v3.8.0] - 2023-12-27 ## What's Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index 355355ec0..6f9af1f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,13 +14,13 @@ cmake_minimum_required(VERSION 3.14) project(re - VERSION 3.8.0 + VERSION 3.9.0 LANGUAGES C HOMEPAGE_URL https://github.com/baresip/re DESCRIPTION "Generic library for real-time communications" ) -set(PROJECT_SOVERSION 20) # bump if ABI breaks +set(PROJECT_SOVERSION 21) # bump if ABI breaks # Pre-release identifier, comment out on a release # Increment for breaking changes (dev2, dev3...) @@ -242,6 +242,7 @@ set(SRCS src/fmt/regex.c src/fmt/str.c src/fmt/str_error.c + src/fmt/text2pcap.c src/fmt/time.c src/fmt/unicode.c diff --git a/include/re_fmt.h b/include/re_fmt.h index af4cd1841..ff694dea5 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -179,9 +179,10 @@ static inline bool str_isset(const char *s) /* time */ -int fmt_gmtime(struct re_printf *pf, void *ts); -int fmt_timestamp(struct re_printf *pf, void *ts); -int fmt_human_time(struct re_printf *pf, const uint32_t *seconds); +int fmt_gmtime(struct re_printf *pf, void *ts); +int fmt_timestamp(struct re_printf *pf, void *ts); +int fmt_timestamp_us(struct re_printf *pf, void *arg); +int fmt_human_time(struct re_printf *pf, const uint32_t *seconds); void hexdump(FILE *f, const void *p, size_t len); @@ -202,3 +203,15 @@ void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg); int utf8_encode(struct re_printf *pf, const char *str); int utf8_decode(struct re_printf *pf, const struct pl *pl); size_t utf8_byteseq(char u[4], unsigned cp); + + +/* text2pcap */ +struct re_text2pcap { + bool in; + const struct mbuf *mb; + const char *id; +}; + +int re_text2pcap(struct re_printf *pf, struct re_text2pcap *pcap); +void re_text2pcap_trace(const char *name, const char *id, bool in, + const struct mbuf *mb); diff --git a/include/re_sipsess.h b/include/re_sipsess.h index ad4f11544..b1f0087e1 100644 --- a/include/re_sipsess.h +++ b/include/re_sipsess.h @@ -7,13 +7,13 @@ struct sipsess_sock; struct sipsess; -/* SDP Negotiation state */ +/** SDP Negotiation state */ enum sdp_neg_state { SDP_NEG_NONE = 0, - SDP_NEG_LOCAL_OFFER, /** SDP offer sent */ - SDP_NEG_REMOTE_OFFER, /** SDP offer received */ - SDP_NEG_PREVIEW_ANSWER, /** SDP preview answer sent */ - SDP_NEG_DONE /** SDP negotiation done */ + SDP_NEG_LOCAL_OFFER, /**< SDP offer sent */ + SDP_NEG_REMOTE_OFFER, /**< SDP offer received */ + SDP_NEG_PREVIEW_ANSWER, /**< SDP preview answer sent */ + SDP_NEG_DONE /**< SDP negotiation done */ }; diff --git a/include/re_tls.h b/include/re_tls.h index dcfc62958..61e28548f 100644 --- a/include/re_tls.h +++ b/include/re_tls.h @@ -69,10 +69,12 @@ int tls_srtp_keyinfo(const struct tls_conn *tc, enum srtp_suite *suite, const char *tls_cipher_name(const struct tls_conn *tc); int tls_set_ciphers(struct tls *tls, const char *cipherv[], size_t count); int tls_set_verify_server(struct tls_conn *tc, const char *host); +int tls_verify_client(struct tls_conn *tc); int tls_get_issuer(struct tls *tls, struct mbuf *mb); int tls_get_subject(struct tls *tls, struct mbuf *mb); void tls_disable_verify_server(struct tls *tls); +void tls_enable_verify_client(struct tls *tls, bool enable); int tls_set_min_proto_version(struct tls *tls, int version); int tls_set_max_proto_version(struct tls *tls, int version); diff --git a/mk/Doxyfile b/mk/Doxyfile index 8ee292170..fcca5223e 100644 --- a/mk/Doxyfile +++ b/mk/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = libre -PROJECT_NUMBER = 3.8.0 +PROJECT_NUMBER = 3.9.0 OUTPUT_DIRECTORY = ../re-dox CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/rem/aufile/aufile.c b/rem/aufile/aufile.c index f5ceb7eaa..8f18e0a35 100644 --- a/rem/aufile/aufile.c +++ b/rem/aufile/aufile.c @@ -271,6 +271,7 @@ size_t aufile_get_length(struct aufile *af, const struct aufile_prm *prm) * * @param af Audio-file * @param prm Audio file parameters from aufile_open + * @param pos_ms Playing position in milliseconds * * @return 0 if success, otherwise errorcode */ diff --git a/src/fmt/text2pcap.c b/src/fmt/text2pcap.c new file mode 100644 index 000000000..d131323fa --- /dev/null +++ b/src/fmt/text2pcap.c @@ -0,0 +1,47 @@ +#include <re_types.h> +#include <re_fmt.h> +#include <re_mbuf.h> +#include <re_trace.h> +#include <re_mem.h> + + +int re_text2pcap(struct re_printf *pf, struct re_text2pcap *pcap) +{ + if (!pcap) + return EINVAL; + + uint8_t *buf = mbuf_buf(pcap->mb); + if (!buf) + return EINVAL; + + re_hprintf(pf, "%s %H 000000", pcap->in ? "I" : "O", fmt_timestamp_us, + NULL); + + size_t sz = mbuf_get_left(pcap->mb); + for (size_t i = 0; i < sz; i++) { + re_hprintf(pf, " %02x", buf[i]); + } + + re_hprintf(pf, " %s", pcap->id); + + return 0; +} + + +void re_text2pcap_trace(const char *name, const char *id, bool in, + const struct mbuf *mb) +{ + struct re_text2pcap pcap = {.in = in, .mb = mb, .id = id}; + size_t pcap_buf_sz = (mbuf_get_left(mb) * 3) + 64; + + char *pcap_buf = mem_alloc(pcap_buf_sz, NULL); + if (!pcap_buf) + return; + + re_snprintf(pcap_buf, pcap_buf_sz, "%H", re_text2pcap, &pcap); + + re_trace_event("pcap", name, 'I', NULL, RE_TRACE_ARG_STRING_COPY, + "pcap", pcap_buf); + + mem_deref(pcap_buf); +} diff --git a/src/fmt/time.c b/src/fmt/time.c index a0001fd89..76410c438 100644 --- a/src/fmt/time.c +++ b/src/fmt/time.c @@ -4,6 +4,10 @@ * Copyright (C) 2010 Creytiv.com */ +#ifdef __MINGW32__ +#define _POSIX_C_SOURCE 200809L +#endif + #include <time.h> #ifdef WIN32 @@ -129,3 +133,39 @@ int fmt_timestamp(struct re_printf *pf, void *arg) return re_hprintf(pf, "%02u:%02u:%02u.%03llu", h, m, s, ms); } + + +/** + * Print local time stamp including microseconds relative to user's timezone + * + * @param pf Print function for output + * @param arg Not used + * + * @return 0 if success, otherwise errorcode + */ +int fmt_timestamp_us(struct re_printf *pf, void *arg) +{ + int h, m, s; + uint64_t us; + struct timespec tspec; + struct tm tm; + +#if defined(WIN32) && !defined(__MINGW32__) + timespec_get(&tspec, TIME_UTC); + int err = localtime_s(&tm, &tspec.tv_sec); + if (err) + return err; +#else + (void)clock_gettime(CLOCK_REALTIME, &tspec); + if (!localtime_r(&tspec.tv_sec, &tm)) + return EINVAL; +#endif + + h = tm.tm_hour; + m = tm.tm_min; + s = tm.tm_sec; + us = tspec.tv_nsec / 1000; + (void)arg; + + return re_hprintf(pf, "%02u:%02u:%02u.%06llu", h, m, s, us); +} diff --git a/src/rtp/rtp.c b/src/rtp/rtp.c index 76d73cf5f..e889f86c8 100644 --- a/src/rtp/rtp.c +++ b/src/rtp/rtp.c @@ -17,7 +17,6 @@ #include <re_atomic.h> #include "rtcp.h" - #define DEBUG_MODULE "rtp" #define DEBUG_LEVEL 5 #include <re_dbg.h> @@ -167,6 +166,10 @@ static void rtcp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg) struct rtp_sock *rs = arg; struct rtcp_msg *msg; +#ifdef RE_RTP_PCAP + re_text2pcap_trace("rtcp_recv", "RTCP", true, mb); +#endif + while (0 == rtcp_decode(&msg, mb)) { /* handle internally first */ @@ -202,10 +205,15 @@ static void udp_recv_handler(const struct sa *src, struct mbuf *mb, void *arg) } } +#ifdef RE_RTP_PCAP + re_text2pcap_trace("rtp_udp_recv", "RTP", true, mb); +#endif + err = rtp_decode(rs, mb, &hdr); if (err) return; + if (rs->rtcp) rtcp_sess_rx_rtp(rs->rtcp, &hdr, mbuf_get_left(mb), src); @@ -525,6 +533,10 @@ int rtp_send(struct rtp_sock *rs, const struct sa *dst, bool ext, mb->pos = pos; +#ifdef RE_RTP_PCAP + re_text2pcap_trace("rtp_send", "RTP", false, mb); +#endif + return udp_send(rs->sock_rtp, dst, mb); } @@ -569,6 +581,10 @@ int rtp_resend(struct rtp_sock *rs, uint16_t seq, const struct sa *dst, mb->pos = pos; +#ifdef RE_RTP_PCAP + re_text2pcap_trace("rtp_resend", "RTP", false, mb); +#endif + return udp_send(rs->sock_rtp, dst, mb); } @@ -704,6 +720,9 @@ int rtcp_send(struct rtp_sock *rs, struct mbuf *mb) if (!sock || !sa_isset(&rs->rtcp_peer, SA_ALL)) return EINVAL; +#ifdef RE_RTP_PCAP + re_text2pcap_trace("rtcp_send", "RTCP", false, mb); +#endif return udp_send(sock, &rs->rtcp_peer, mb); } diff --git a/src/sip/transp.c b/src/sip/transp.c index ada515522..eb6062fd6 100644 --- a/src/sip/transp.c +++ b/src/sip/transp.c @@ -261,15 +261,14 @@ static void conn_close(struct sip_conn *conn, int err) struct sip_connqent *qent = le->data; le = le->next; - - if (qent->qentp) { - *qent->qentp = NULL; - qent->qentp = NULL; - } + bool qentp_set = qent->qentp ? true : false; qent->transph(err, qent->arg); - list_unlink(&qent->le); - mem_deref(qent); + + if (!qentp_set) { + list_unlink(&qent->le); + mem_deref(qent); + } } sip_keepalive_signal(&conn->kal, err); @@ -618,13 +617,9 @@ static void tcp_estab_handler(void *arg) while (le) { struct sip_connqent *qent = le->data; + bool qentp_set = qent->qentp ? true : false; le = le->next; - if (qent->qentp) { - *qent->qentp = NULL; - qent->qentp = NULL; - } - trace_send(conn->sip, conn->sc ? SIP_TRANSP_TLS : SIP_TRANSP_TCP, conn, @@ -634,8 +629,10 @@ static void tcp_estab_handler(void *arg) if (err) qent->transph(err, qent->arg); - list_unlink(&qent->le); - mem_deref(qent); + if (!qentp_set) { + list_unlink(&qent->le); + mem_deref(qent); + } } } @@ -682,6 +679,10 @@ static void tcp_connect_handler(const struct sa *paddr, void *arg) err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0); if (err) goto out; + + err = tls_verify_client(conn->sc); + if (err) + goto out; } #endif @@ -896,13 +897,9 @@ static void websock_estab_handler(void *arg) while (le) { struct sip_connqent *qent = le->data; + bool qentp_set = qent->qentp ? true : false; le = le->next; - if (qent->qentp) { - *qent->qentp = NULL; - qent->qentp = NULL; - } - trace_send(conn->sip, conn->tp, conn, @@ -917,8 +914,10 @@ static void websock_estab_handler(void *arg) if (err) qent->transph(err, qent->arg); - list_unlink(&qent->le); - mem_deref(qent); + if (!qentp_set) { + list_unlink(&qent->le); + mem_deref(qent); + } } } diff --git a/src/tls/openssl/tls.c b/src/tls/openssl/tls.c index ac1f5b676..a5b983ae9 100644 --- a/src/tls/openssl/tls.c +++ b/src/tls/openssl/tls.c @@ -45,6 +45,7 @@ struct tls { X509 *cert; char *pass; /**< password for private key */ bool verify_server; /**< Enable SIP TLS server verification */ + bool verify_client; /**< Enable SIP TLS client verification */ struct session_reuse reuse; struct list certs; /**< Certificates for SNI selection */ }; @@ -1459,6 +1460,35 @@ int tls_set_verify_server(struct tls_conn *tc, const char *host) } +/** + * Enable verification of client certificate + * + * @param tc TLS Connection + * + * @return 0 if success, otherwise errorcode + */ +int tls_verify_client(struct tls_conn *tc) +{ +#if !defined(LIBRESSL_VERSION_NUMBER) + + if (!tc) + return EINVAL; + + if (!tc->tls->verify_client) + return 0; + + SSL_set_verify(tc->ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, + tls_verify_handler); + + return 0; +#else + (void)tc; + + return ENOSYS; +#endif +} + + static int print_error(const char *str, size_t len, void *unused) { (void)unused; @@ -1597,6 +1627,21 @@ void tls_disable_verify_server(struct tls *tls) } +/** + * Enables SIP TLS client verifications for following requests + * + * @param tls TLS Object + * @param enable true to enable client verification, false to disable + */ +void tls_enable_verify_client(struct tls *tls, bool enable) +{ + if (!tls) + return; + + tls->verify_client = enable; +} + + /** * Set minimum TLS version * diff --git a/src/trace/trace.c b/src/trace/trace.c index 832d0f977..397d48989 100644 --- a/src/trace/trace.c +++ b/src/trace/trace.c @@ -164,7 +164,7 @@ int re_trace_init(const char *json_file) trace.event_buffer_flush = mem_zalloc( TRACE_BUFFER_SIZE * sizeof(struct trace_event), NULL); if (!trace.event_buffer_flush) { - mem_deref(trace.event_buffer); + trace.event_buffer = mem_deref(trace.event_buffer); return ENOMEM; } @@ -191,8 +191,8 @@ int re_trace_init(const char *json_file) out: if (err) { re_atomic_rlx_set(&trace.init, false); - mem_deref(trace.event_buffer); - mem_deref(trace.event_buffer_flush); + trace.event_buffer = mem_deref(trace.event_buffer); + trace.event_buffer_flush = mem_deref(trace.event_buffer_flush); } return err; @@ -245,12 +245,12 @@ int re_trace_close(void) int re_trace_flush(void) { #ifdef RE_TRACE_ENABLED - int i, flush_count; + int flush_count; struct trace_event *event_tmp; struct trace_event *e; - char json_arg[256] = {0}; - char name[128] = {0}; - char id_str[128] = {0}; + char *json_arg; + char name[128] = {0}; + char id_str[128] = {0}; if (!re_atomic_rlx(&trace.init)) return 0; @@ -264,7 +264,21 @@ int re_trace_flush(void) trace.event_count = 0; mtx_unlock(&trace.lock); - for (i = 0; i < flush_count; i++) + size_t json_arg_sz = 4096; + json_arg = mem_zalloc(json_arg_sz, NULL); + if (!json_arg) { + for (int i = 0; i < flush_count; i++) { + e = &trace.event_buffer_flush[i]; + if (e->arg_type == RE_TRACE_ARG_STRING_COPY) + mem_deref((void *)e->arg.a_str); + + if (e->id) + mem_deref(e->id); + } + return ENOMEM; + } + + for (int i = 0; i < flush_count; i++) { e = &trace.event_buffer_flush[i]; @@ -273,17 +287,17 @@ int re_trace_flush(void) json_arg[0] = '\0'; break; case RE_TRACE_ARG_INT: - (void)re_snprintf(json_arg, sizeof(json_arg), + (void)re_snprintf(json_arg, json_arg_sz, ", \"args\":{\"%s\":%i}", e->arg_name, e->arg.a_int); break; case RE_TRACE_ARG_STRING_CONST: - (void)re_snprintf(json_arg, sizeof(json_arg), + (void)re_snprintf(json_arg, json_arg_sz, ", \"args\":{\"%s\":\"%s\"}", e->arg_name, e->arg.a_str); break; case RE_TRACE_ARG_STRING_COPY: - (void)re_snprintf(json_arg, sizeof(json_arg), + (void)re_snprintf(json_arg, json_arg_sz, ", \"args\":{\"%s\":\"%s\"}", e->arg_name, e->arg.a_str); @@ -310,6 +324,8 @@ int re_trace_flush(void) trace.new = false; } + mem_deref(json_arg); + (void)fflush(trace.f); return 0; #else diff --git a/test/fmt.c b/test/fmt.c index 7b82deebb..297346c3f 100644 --- a/test/fmt.c +++ b/test/fmt.c @@ -1158,3 +1158,30 @@ int test_fmt_hexdump(void) return 0; } + + +int test_text2pcap(void) +{ + char test[64]; + struct mbuf *mb; + int err = 0; + + mb = mbuf_alloc(2); + if (!mb) + return ENOMEM; + + mbuf_write_u8(mb, 42); + mbuf_write_u8(mb, 23); + + mbuf_set_pos(mb, 0); + + struct re_text2pcap pcap = {.id = "test", .in = true, .mb = mb}; + + int ret = re_snprintf(test, sizeof(test), "%H", re_text2pcap, &pcap); + + TEST_EQUALS(35, ret); + +out: + mem_deref(mb); + return err; +} diff --git a/test/test.c b/test/test.c index 261c1d96f..6bfc024f9 100644 --- a/test/test.c +++ b/test/test.c @@ -214,6 +214,7 @@ static const struct test tests[] = { TEST(test_sys_getenv), TEST(test_tcp), TEST(test_telev), + TEST(test_text2pcap), #ifdef USE_TLS TEST(test_tls), TEST(test_tls_ec), diff --git a/test/test.h b/test/test.h index 68a681e2c..cee4a3401 100644 --- a/test/test.h +++ b/test/test.h @@ -330,6 +330,7 @@ int test_sys_fs_fopen(void); int test_sys_getenv(void); int test_tcp(void); int test_telev(void); +int test_text2pcap(void); int test_thread(void); int test_thread_cnd_timedwait(void); int test_tmr_jiffies(void); diff --git a/test/trace.c b/test/trace.c index be85c828e..6966be3e2 100644 --- a/test/trace.c +++ b/test/trace.c @@ -67,5 +67,7 @@ int test_trace(void) #endif out: + if (err) + re_trace_close(); return err; }