diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d15fd9fa..7c7021139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,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). +## [v3.11.0] - 2024-04-09 + +### What's Changed +* ci/clang-analyze: bump clang version and fix status-bugs by @sreimers in https://github.com/baresip/re/pull/1079 +* main: Flush list of deleted fhs on `fd_poll` errors by @Lastique in https://github.com/baresip/re/pull/1081 +* main: Use slist for fhs delete list. by @Lastique in https://github.com/baresip/re/pull/1082 +* http/server: fix wrong sizeof in verify_msg by @akscf in https://github.com/baresip/re/pull/1083 +* ci/sanitizers: add mmap rnd_bits workaround by @sreimers in https://github.com/baresip/re/pull/1086 +* rtcp: add printing of TWCC packet by @alfredh in https://github.com/baresip/re/pull/1084 +* include: add re_h264.h to re.h by @alfredh in https://github.com/baresip/re/pull/1087 +* sdp: add sdp media lattr apply function the same way as for rattr by @cHuberCoffee in https://github.com/baresip/re/pull/1089 +* av1: improve packetizer by @alfredh in https://github.com/baresip/re/pull/1088 +* test: minor H.264 improvements by @alfredh in https://github.com/baresip/re/pull/1090 +* tls: add session resumption setter by @maximilianfridrich in https://github.com/baresip/re/pull/1091 +* thread/posix: optimize handler and fix gcc arm32 warning by @sreimers in https://github.com/baresip/re/pull/1093 +* h264: fix for Annex-B bitstreams with 4-byte startcode by @alfredh in https://github.com/baresip/re/pull/1092 +* ci/arch: add armv7 check by @sreimers in https://github.com/baresip/re/pull/1085 +* main,httpauth: fix different from the declaration by @jobo-zt in https://github.com/baresip/re/pull/1095 +* httpauth: fix doxygen comment by @alfredh in https://github.com/baresip/re/pull/1097 + +### New Contributors +* @akscf made their first contribution in https://github.com/baresip/re/pull/1083 + +**Full Changelog**: https://github.com/baresip/re/compare/v3.10.0...v3.11.0 + + ## [v3.10.0] - 2024-03-06 ## What's Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index a2a3d0e72..7cb3dc07d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,13 +14,13 @@ cmake_minimum_required(VERSION 3.14) project(re - VERSION 3.10.0 + VERSION 3.11.0 LANGUAGES C HOMEPAGE_URL https://github.com/baresip/re DESCRIPTION "Generic library for real-time communications" ) -set(PROJECT_SOVERSION 22) # bump if ABI breaks +set(PROJECT_SOVERSION 23) # bump if ABI breaks # Pre-release identifier, comment out on a release # Increment for breaking changes (dev2, dev3...) @@ -99,7 +99,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") endif() set(re_DIR ${CMAKE_CURRENT_LIST_DIR}/cmake) -find_package(re CONFIG REQUIRED) +include("${CMAKE_CURRENT_LIST_DIR}/cmake/re-config.cmake") list(APPEND RE_DEFINITIONS -DRE_VERSION="${PROJECT_VERSION_FULL}" @@ -649,7 +649,7 @@ endif() if(LIBRE_BUILD_STATIC) list(APPEND RE_INSTALL_TARGETS re) add_library(re STATIC $) - target_link_libraries(re PUBLIC ${RE_LIBS}) + target_link_libraries(re PRIVATE ${RE_LIBS}) target_include_directories(re PUBLIC $ ) @@ -705,6 +705,9 @@ configure_file(packaging/libre.pc.in libre.pc @ONLY) install(TARGETS ${RE_INSTALL_TARGETS} EXPORT libre + RUNTIME + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT Libraries LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Libraries @@ -723,7 +726,9 @@ install(FILES ${HEADERS} install(EXPORT libre DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libre + FILE libre-targets.cmake NAMESPACE libre:: + COMPONENT Development ) if(LIBRE_BUILD_SHARED) @@ -740,7 +745,9 @@ install(FILES cmake/re-config.cmake COMPONENT Development ) -install(FILES cmake/libre-config.cmake +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/libre-config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/libre-config.cmake" @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/libre-config.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libre COMPONENT Development ) diff --git a/cmake/libre-config.cmake b/cmake/libre-config.cmake index 0965b84fe..e8548a0f2 100644 --- a/cmake/libre-config.cmake +++ b/cmake/libre-config.cmake @@ -1 +1,23 @@ -include("${CMAKE_CURRENT_LIST_DIR}/libre.cmake") +if("@LIBRE_BUILD_STATIC@") + include(CMakeFindDependencyMacro) + find_dependency(Threads) + if("@USE_OPENSSL@") + find_dependency(OpenSSL) + endif() + if("@ZLIB_FOUND@") + find_dependency(ZLIB) + endif() +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/libre-targets.cmake") + +# convenience target libre::libre for uniform usage +if(NOT TARGET libre::libre) + if(TARGET libre::re_shared AND (BUILD_SHARED_LIBS OR NOT TARGET libre::re)) + add_library(libre::libre INTERFACE IMPORTED) + set_target_properties(libre::libre PROPERTIES INTERFACE_LINK_LIBRARIES libre::re_shared) + elseif(TARGET libre::re AND (NOT BUILD_SHARED_LIBS OR NOT TARGET libre::re_shared)) + add_library(libre::libre INTERFACE IMPORTED) + set_target_properties(libre::libre PROPERTIES INTERFACE_LINK_LIBRARIES libre::re) + endif() +endif() diff --git a/debian/changelog b/debian/changelog index bcc86a4ba..ced7077e5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libre (3.11.0) unstable; urgency=medium + + * version 3.11.0 + + -- Sebastian Reimers Tue, 9 Apr 2024 09:00:00 +0200 + libre (3.10.0) unstable; urgency=medium * version 3.10.0 diff --git a/include/re_fmt.h b/include/re_fmt.h index ff694dea5..bb64be49b 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -46,6 +46,7 @@ int pl_strcpy(const struct pl *pl, char *str, size_t size); int pl_strdup(char **dst, const struct pl *src); int pl_dup(struct pl *dst, const struct pl *src); int pl_strcmp(const struct pl *pl, const char *str); +int pl_strncmp(const struct pl *pl, const char *str, size_t n); int pl_strcasecmp(const struct pl *pl, const char *str); int pl_cmp(const struct pl *pl1, const struct pl *pl2); int pl_casecmp(const struct pl *pl1, const struct pl *pl2); diff --git a/include/re_h264.h b/include/re_h264.h index 1268e1172..e5674ea8e 100644 --- a/include/re_h264.h +++ b/include/re_h264.h @@ -104,3 +104,4 @@ bool h264_is_keyframe(int type); int h264_stap_encode(struct mbuf *mb, const uint8_t *frame, size_t frame_sz); int h264_stap_decode_annexb(struct mbuf *mb_frame, struct mbuf *mb_pkt); +int h264_stap_decode_annexb_long(struct mbuf *mb_frame, struct mbuf *mb_pkt); diff --git a/include/re_sip.h b/include/re_sip.h index e374f215c..f9c171765 100644 --- a/include/re_sip.h +++ b/include/re_sip.h @@ -150,6 +150,7 @@ enum { /** SIP Via header */ +#define RE_RFC3261_BRANCH_ID "z9hG4bK" struct sip_via { struct pl sentby; struct sa addr; @@ -344,6 +345,7 @@ int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful, void sip_request_cancel(struct sip_request *req); bool sip_request_loops(struct sip_loopstate *ls, uint16_t scode); void sip_loopstate_reset(struct sip_loopstate *ls); +bool sip_request_provrecv(const struct sip_request *req); /* reply */ diff --git a/mk/Doxyfile b/mk/Doxyfile index c946e921c..df583912b 100644 --- a/mk/Doxyfile +++ b/mk/Doxyfile @@ -4,7 +4,7 @@ # Project related configuration options #--------------------------------------------------------------------------- PROJECT_NAME = libre -PROJECT_NUMBER = 3.10.0 +PROJECT_NUMBER = 3.11.0 OUTPUT_DIRECTORY = ../re-dox CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/src/fmt/pl.c b/src/fmt/pl.c index 72ebfa4e8..47057236f 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -536,6 +536,28 @@ int pl_strcmp(const struct pl *pl, const char *str) } +/** + * Compare n characters of a pointer-length object with a NULL-terminated + * string (case-sensitive) + * + * @param pl Pointer-length object + * @param str NULL-terminated string + * @param n number of characters that should be compared + * + * @return 0 if match, otherwise errorcode + */ +int pl_strncmp(const struct pl *pl, const char *str, size_t n) +{ + if (!pl_isset(pl) || !str || !n) + return EINVAL; + + if (pl->l < n) + return EINVAL; + + return strncmp(pl->p, str, n) == 0 ? 0 : EINVAL; +} + + /** * Compare a pointer-length object with a NULL-terminated string * (case-insensitive) diff --git a/src/h264/nal.c b/src/h264/nal.c index 180cedd33..1ac333a09 100644 --- a/src/h264/nal.c +++ b/src/h264/nal.c @@ -365,17 +365,8 @@ int h264_stap_encode(struct mbuf *mb, const uint8_t *frame, } -/** - * Decode STAP-A payload and convert to Annex-B NAL units - * - * @param mb_frame Target mbuffer for frame with multiple NAL units - * @param mb_pkt Input packet with STAP-A payload - * - * @return 0 if success, otherwise errorcode - * - * NOTE: The NAL header must be decoded outside - */ -int h264_stap_decode_annexb(struct mbuf *mb_frame, struct mbuf *mb_pkt) +static int stap_decode_annexb_int(struct mbuf *mb_frame, struct mbuf *mb_pkt, + bool long_startcode) { if (!mb_frame || !mb_pkt) return EINVAL; @@ -398,8 +389,13 @@ int h264_stap_decode_annexb(struct mbuf *mb_frame, struct mbuf *mb_pkt) #endif static const uint8_t sc3[] = {0, 0, 1}; + static const uint8_t sc4[] = {0, 0, 0, 1}; - int err = mbuf_write_mem(mb_frame, sc3, sizeof(sc3)); + int err; + if (long_startcode) + err = mbuf_write_mem(mb_frame, sc4, sizeof(sc4)); + else + err = mbuf_write_mem(mb_frame, sc3, sizeof(sc3)); err |= mbuf_write_mem(mb_frame, mbuf_buf(mb_pkt), len); if (err) return err; @@ -409,3 +405,36 @@ int h264_stap_decode_annexb(struct mbuf *mb_frame, struct mbuf *mb_pkt) return 0; } + + +/** + * Decode STAP-A payload and convert to Annex-B NAL units + * + * @param mb_frame Target mbuffer for frame with multiple NAL units + * @param mb_pkt Input packet with STAP-A payload + * + * @return 0 if success, otherwise errorcode + * + * NOTE: The NAL header must be decoded outside + */ +int h264_stap_decode_annexb(struct mbuf *mb_frame, struct mbuf *mb_pkt) +{ + return stap_decode_annexb_int(mb_frame, mb_pkt, false); +} + + +/** + * Decode STAP-A payload and convert to Annex-B NAL units + * with long startcode (0x00 0x00 0x00 0x01). + * + * @param mb_frame Target mbuffer for frame with multiple NAL units + * @param mb_pkt Input packet with STAP-A payload + * + * @return 0 if success, otherwise errorcode + * + * NOTE: The NAL header must be decoded outside + */ +int h264_stap_decode_annexb_long(struct mbuf *mb_frame, struct mbuf *mb_pkt) +{ + return stap_decode_annexb_int(mb_frame, mb_pkt, true); +} diff --git a/src/sip/request.c b/src/sip/request.c index cb60a8801..02b45d740 100644 --- a/src/sip/request.c +++ b/src/sip/request.c @@ -970,13 +970,28 @@ void sip_request_cancel(struct sip_request *req) req->canceled = true; - if (!req->provrecv) + if (!req->provrecv) { + req->ct = mem_deref(req->ct); return; + } (void)sip_ctrans_cancel(req->ct); } +/** + * Check if a provisional response was received for a SIP Request + * + * @param req SIP Request + * + * @return True if a provisional response was received, false otherwise + */ +bool sip_request_provrecv(const struct sip_request *req) +{ + return req ? req->provrecv : false; +} + + void sip_request_close(struct sip *sip) { if (!sip) diff --git a/src/sipsess/sess.c b/src/sipsess/sess.c index f394ec92c..18123aa91 100644 --- a/src/sipsess/sess.c +++ b/src/sipsess/sess.c @@ -85,8 +85,13 @@ static bool termwait(struct sipsess *sess) if (sess->req) { sip_request_cancel(sess->req); - mem_ref(sess); - wait = true; + if (!sip_request_provrecv(sess->req)) { + sess->req = mem_deref(sess->req); + } + else { + mem_ref(sess); + wait = true; + } } if (sess->replyl.head) { diff --git a/test/h264.c b/test/h264.c index d10738937..186724b10 100644 --- a/test/h264.c +++ b/test/h264.c @@ -69,26 +69,9 @@ static void dump_rtp(const uint8_t *p, size_t size) #endif -static int test_h264_stap_a_encode(void) +static int test_h264_stap_a_encode_base(const uint8_t *frame, size_t len, + bool long_startcode) { - static const uint8_t frame[] = { - - /* AUD */ - 0x00, 0x00, 0x01, - 0x09, 0x10, - - /* SPS */ - 0x00, 0x00, 0x01, - 0x67, 0x42, 0xc0, 0x1f, 0x8c, 0x8d, 0x40, - - /* PPS */ - 0x00, 0x00, 0x01, - 0x68, 0xce, 0x3c, 0x80, - - /* IDR_SLICE */ - 0x00, 0x00, 0x01, - 0x65, 0xb8, 0x00, 0x04, 0x00, 0x00, 0x05, 0x39, - }; enum { MAX_NRI = 3 }; struct mbuf *mb_pkt = mbuf_alloc(256); struct mbuf *mb_frame = mbuf_alloc(256); @@ -100,7 +83,7 @@ static int test_h264_stap_a_encode(void) goto out; } - err = h264_stap_encode(mb_pkt, frame, sizeof(frame)); + err = h264_stap_encode(mb_pkt, frame, len); if (err) goto out; @@ -112,10 +95,16 @@ static int test_h264_stap_a_encode(void) ASSERT_EQ(MAX_NRI, hdr.nri); /* NOTE: max NRI */ ASSERT_EQ(H264_NALU_STAP_A, hdr.type); - err = h264_stap_decode_annexb(mb_frame, mb_pkt); - ASSERT_EQ(0, err); + if (long_startcode) { + err = h264_stap_decode_annexb_long(mb_frame, mb_pkt); + ASSERT_EQ(0, err); + } + else { + err = h264_stap_decode_annexb(mb_frame, mb_pkt); + ASSERT_EQ(0, err); + } - TEST_MEMCMP(frame, sizeof(frame), mb_frame->buf, mb_frame->end); + TEST_MEMCMP(frame, len, mb_frame->buf, mb_frame->end); out: mem_deref(mb_frame); @@ -125,6 +114,58 @@ static int test_h264_stap_a_encode(void) } +static int test_h264_stap_a_encode(void) +{ + static const uint8_t frame[] = { + + /* AUD */ + 0x00, 0x00, 0x01, + 0x09, 0x10, + + /* SPS */ + 0x00, 0x00, 0x01, + 0x67, 0x42, 0xc0, 0x1f, 0x8c, 0x8d, 0x40, + + /* PPS */ + 0x00, 0x00, 0x01, + 0x68, 0xce, 0x3c, 0x80, + + /* IDR_SLICE */ + 0x00, 0x00, 0x01, + 0x65, 0xb8, 0x00, 0x04, 0x00, 0x00, 0x05, 0x39, + }; + static const uint8_t frame_long[] = { + + /* AUD */ + 0x00, 0x00, 0x00, 0x01, + 0x09, 0x10, + + /* SPS */ + 0x00, 0x00, 0x00, 0x01, + 0x67, 0x42, 0xc0, 0x1f, 0x8c, 0x8d, 0x40, + + /* PPS */ + 0x00, 0x00, 0x00, 0x01, + 0x68, 0xce, 0x3c, 0x80, + + /* IDR_SLICE */ + 0x00, 0x00, 0x00, 0x01, + 0x65, 0xb8, 0x00, 0x04, 0x00, 0x00, 0x05, 0x39, + }; + int err; + + err = test_h264_stap_a_encode_base(frame, sizeof(frame), false); + TEST_ERR(err); + + err = test_h264_stap_a_encode_base(frame_long, sizeof(frame_long), + true); + TEST_ERR(err); + + out: + return err; +} + + static int test_h264_stap_a_decode(void) { static const uint8_t pkt[] = {