From d4e216e21c36f94cee31bce81aac4c0d765721b5 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 13 Nov 2024 16:41:29 +0100 Subject: [PATCH] aplay/mixer: participant add/rm print fixes - do not print it in constructor/dtor - the participant may be moved - copy the stored address in copy constructor - use get_sockaddr_str + change its prototype - do not use thread_local vars but user provided buffer - also take (const sockaddr *) in the get_sockaddr_str and get_sockaddr_addr_* functions (participants iterated by const iterator returning const participant reference) --- src/audio/playback/mixer.cpp | 28 ++++++++--------- src/hd-rum-translator/hd-rum-translator.cpp | 5 ++- src/rtp/rtp.c | 4 ++- src/utils/net.c | 34 ++++++++++++--------- src/utils/net.h | 12 +++++--- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/audio/playback/mixer.cpp b/src/audio/playback/mixer.cpp index ce3453f54..074e47556 100644 --- a/src/audio/playback/mixer.cpp +++ b/src/audio/playback/mixer.cpp @@ -65,7 +65,6 @@ #include "transmit.h" #include "types.h" // for tx_media_type #include "utils/audio_buffer.h" -#include "utils/macros.h" // for STR_LEN #include "utils/net.h" // for get_sockaddr_addr_str #include "utils/thread.h" @@ -128,7 +127,7 @@ static void mixer_dummy_rtp_callback(struct rtp *session [[gnu::unused]], rtp_ev struct am_participant { am_participant(struct socket_udp_local *l, struct sockaddr_storage *ss, string const &audio_codec) - : remote_addr(*ss) + : m_remote_addr(*ss) { assert(l != nullptr && ss != nullptr); m_buffer = audio_buffer_init(SAMPLE_RATE, BPS, CHANNELS, get_commandline_param("low-latency-audio") ? 50 : 5); @@ -147,12 +146,6 @@ struct am_participant { LOG(LOG_LEVEL_ERROR) << "Audio coder init failed!\n"; throw 1; } - - char buf[STR_LEN]; - MSG(NOTICE, "added participant: %s:%u\n", - get_sockaddr_addr_str((struct sockaddr *) ss, buf, - sizeof buf), - get_sockaddr_addr_port((struct sockaddr *) ss)); } ~am_participant() { if (m_tx_session) { @@ -167,11 +160,6 @@ struct am_participant { if (m_audio_coder) { audio_codec_done(m_audio_coder); } - char buf[STR_LEN]; - MSG(NOTICE, "removed participant: %s:%u\n", - get_sockaddr_addr_str((struct sockaddr *) &remote_addr, buf, - sizeof buf), - get_sockaddr_addr_port((struct sockaddr *) &remote_addr)); } am_participant& operator=(am_participant&& other) { m_audio_coder = std::move(other.m_audio_coder); @@ -179,6 +167,7 @@ struct am_participant { m_network_device = std::move(other.m_network_device); m_tx_session = std::move(other.m_tx_session); last_seen = std::move(other.last_seen); + m_remote_addr = std::move(other.m_remote_addr); other.m_audio_coder = nullptr; other.m_buffer = nullptr; other.m_tx_session = nullptr; @@ -188,7 +177,7 @@ struct am_participant { am_participant(am_participant && other) { *this = std::move(other); } - struct sockaddr_storage remote_addr; + struct sockaddr_storage m_remote_addr; struct audio_codec_state *m_audio_coder; struct audio_buffer *m_buffer; struct rtp *m_network_device; @@ -331,6 +320,12 @@ void state_audio_mixer::worker() for (auto it = participants.cbegin(); it != participants.cend(); ) { if (duration_cast(now - it->second.last_seen).count() > PARTICIPANT_TIMEOUT_S) { + char buf[ADDR_STR_BUF_LEN]; + MSG(NOTICE, "removed participant: %s\n", + get_sockaddr_str( + (const struct sockaddr *) &it->second + .m_remote_addr, + buf, sizeof buf)); it = participants.erase(it); } else { ++it; @@ -441,6 +436,11 @@ static void audio_play_mixer_put_frame(void *state, const struct audio_frame *fr auto ss = *(struct sockaddr_storage *) frame->network_source; if (s->participants.find(ss) == s->participants.end()) { + char buf[ADDR_STR_BUF_LEN]; + MSG(NOTICE, "added participant: %s\n", + get_sockaddr_str( + (struct sockaddr *) &ss, buf, + sizeof buf)); s->participants.emplace(ss, am_participant{s->recv_socket, &ss, s->audio_codec}); } diff --git a/src/hd-rum-translator/hd-rum-translator.cpp b/src/hd-rum-translator/hd-rum-translator.cpp index ed44f0425..90b9a3e2f 100644 --- a/src/hd-rum-translator/hd-rum-translator.cpp +++ b/src/hd-rum-translator/hd-rum-translator.cpp @@ -918,7 +918,10 @@ class Participant_manager{ log_msg(LOG_LEVEL_NOTICE, "New participant\n"); std::string msg = "create-port "; - msg += get_sockaddr_str(reinterpret_cast(&sin)); + char buf[ADDR_STR_BUF_LEN]; + msg += + get_sockaddr_str(reinterpret_cast(&sin), + buf, sizeof buf); if(!compression.empty()){ msg += " "; msg += compression; diff --git a/src/rtp/rtp.c b/src/rtp/rtp.c index 975e6e037..0b8983abc 100644 --- a/src/rtp/rtp.c +++ b/src/rtp/rtp.c @@ -1573,7 +1573,9 @@ static void rtp_process_data(struct rtp *session, uint32_t curr_rtp_ts, if (!rtp_has_receiver(session)) { session->opt->send_back = FALSE; // avoid multiple checks if already sending struct sockaddr *sa = (struct sockaddr *)(void *)((char *) packet + RTP_MAX_PACKET_LEN); - log_msg(LOG_LEVEL_NOTICE, "[RTP] Redirecting stream to a client %s.\n", get_sockaddr_str(sa)); + MSG(NOTICE, "Redirecting stream to a client %s.\n", + get_sockaddr_str(sa, (char[ADDR_STR_BUF_LEN]){ 0 }, + ADDR_STR_BUF_LEN)); udp_set_receiver(session->rtp_socket, sa, sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)); } diff --git a/src/utils/net.c b/src/utils/net.c index e9e23497d..35b58891e 100644 --- a/src/utils/net.c +++ b/src/utils/net.c @@ -411,12 +411,14 @@ bool is_ipv6_supported(void) return true; } -unsigned get_sockaddr_addr_port(struct sockaddr *sa){ +unsigned get_sockaddr_addr_port(const struct sockaddr *sa){ unsigned port = 0; if (sa->sa_family == AF_INET6) { - port = ntohs(((struct sockaddr_in6 *)(void *) sa)->sin6_port); + port = ntohs(((const struct sockaddr_in6 *) (const void *) sa) + ->sin6_port); } else if (sa->sa_family == AF_INET) { - port = ntohs(((struct sockaddr_in *)(void *) sa)->sin_port); + port = ntohs( + ((const struct sockaddr_in *) (const void *) sa)->sin_port); } else { return UINT_MAX; } @@ -428,15 +430,17 @@ unsigned get_sockaddr_addr_port(struct sockaddr *sa){ * @returns the input buffer (buf) */ char * -get_sockaddr_addr_str(struct sockaddr *sa, char *buf, size_t n) +get_sockaddr_addr_str(const struct sockaddr *sa, char *buf, size_t n) { assert(n >= IN6_MAX_ASCII_LEN + 3 /* []: */ + 1 /* \0 */); const void *src = NULL; if (sa->sa_family == AF_INET6) { snprintf(buf, n, "["); - src = &((struct sockaddr_in6 *)(void *) sa)->sin6_addr; + src = &((const struct sockaddr_in6 *) (const void *) sa) + ->sin6_addr; } else if (sa->sa_family == AF_INET) { - src = &((struct sockaddr_in *)(void *) sa)->sin_addr; + src = + &((const struct sockaddr_in *) (const void *) sa)->sin_addr; } else { snprintf(buf, n, "(unknown)"); return buf; @@ -453,20 +457,20 @@ get_sockaddr_addr_str(struct sockaddr *sa, char *buf, size_t n) return buf; } -const char *get_sockaddr_str(struct sockaddr *sa) +/** + * @returns the input buffer (buf) + */ +char * +get_sockaddr_str(const struct sockaddr *sa, char *buf, size_t n) { - enum { ADDR_LEN = IN6_MAX_ASCII_LEN + 3 /* []: */ + 5 /* port */ + 1 /* \0 */ }; - _Thread_local static char addr[ADDR_LEN] = ""; - addr[0] = '\0'; - - get_sockaddr_addr_str(sa, addr, sizeof(addr)); + get_sockaddr_addr_str(sa, buf, n); unsigned port = get_sockaddr_addr_port(sa); if(port == UINT_MAX) - return addr; - snprintf(addr + strlen(addr), ADDR_LEN - strlen(addr), ":%u", port); + return buf; + snprintf(buf + strlen(buf), n - strlen(buf), ":%u", port); - return addr; + return buf; } const char *ug_gai_strerror(int errcode) diff --git a/src/utils/net.h b/src/utils/net.h index 0a951d9b6..62b711ca4 100644 --- a/src/utils/net.h +++ b/src/utils/net.h @@ -47,7 +47,11 @@ #include #endif // __cplusplus -#define IN6_MAX_ASCII_LEN 39 // 32 nibbles + 7 colons +enum { + IN6_MAX_ASCII_LEN = 39, // 32 nibbles + 7 colons + ADDR_STR_BUF_LEN = + IN6_MAX_ASCII_LEN + 3 /* []: */ + 5 /* port */ + 1 /* \0 */, +}; // RFC 6666 prefix 100::/64, suffix 'UltrGrS' #define IN6_BLACKHOLE_SERVER_MODE_STR "100::556C:7472:4772:6453" @@ -66,9 +70,9 @@ bool is_host_private(const char *hostname); uint16_t socket_get_recv_port(int fd); bool get_local_addresses(struct sockaddr_storage *addrs, size_t *len, int ip_version); bool is_ipv6_supported(void); -char *get_sockaddr_addr_str(struct sockaddr *sa, char *buf, size_t n); -unsigned get_sockaddr_addr_port(struct sockaddr *sa); -const char *get_sockaddr_str(struct sockaddr *sa); +char *get_sockaddr_addr_str(const struct sockaddr *sa, char *buf, size_t n); +unsigned get_sockaddr_addr_port(const struct sockaddr *sa); +char *get_sockaddr_str(const struct sockaddr *sa, char *buf, size_t n); const char *ug_gai_strerror(int errcode); #ifdef _WIN32