From 33e5f09592190cf66dfb53e83ed0e85b1d7a0bbc Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 24 Feb 2025 12:07:13 -0400 Subject: [PATCH] MT#61625 support "blackhole" codec handler Special codec handler to support not forwarding (nor any processing whatsoever) of particular payload types at all. Support this in the kernel module as well. Change-Id: If10227affa54307e1e9b448eadd0bf2bfc5774ba --- daemon/codec.c | 17 ++++++++++++++++- daemon/media_socket.c | 2 ++ include/call.h | 1 + include/codec.h | 1 + kernel-module/xt_RTPENGINE.c | 9 ++++++++- kernel-module/xt_RTPENGINE.h | 1 + 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 6b26ae36d..cacefc197 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -276,6 +276,7 @@ static codec_handler_func handler_func_playback; static codec_handler_func handler_func_inject_dtmf; static codec_handler_func handler_func_dtmf; static codec_handler_func handler_func_t38; +static codec_handler_func handler_func_blackhole; static struct ssrc_entry *__ssrc_handler_transcode_new(void *p); static struct ssrc_entry *__ssrc_handler_decode_new(void *p); @@ -326,6 +327,13 @@ static struct codec_handler codec_handler_stub_ssrc = { .kernelize = true, .passthrough = true, }; +static struct codec_handler codec_handler_stub_blackhole = { + .source_pt.payload_type = -1, + .dest_pt.payload_type = -1, + .handler_func = handler_func_blackhole, + .kernelize = true, + .passthrough = false, +}; @@ -348,6 +356,7 @@ static void __handler_shutdown(struct codec_handler *handler) { handler->pcm_dtmf_detect = false; handler->passthrough = false; handler->payload_len = 0; + handler->blackhole = false; codec_handler_free(&handler->dtmf_injector); @@ -464,6 +473,10 @@ static void __handler_stats_entry(struct codec_handler *handler) { __atomic_fetch_add(&stats_entry->num_transcoders, 1, __ATOMIC_RELAXED); } +static int handler_func_blackhole(struct codec_handler *h, struct media_packet *mp) { + return 0; +} + static void __reset_sequencer(void *p, void *dummy) { struct ssrc_entry_call *s = p; if (s->sequencers) @@ -485,7 +498,7 @@ static bool __make_transcoder_full(struct codec_handler *handler, rtp_payload_ty goto reset; if (!rtp_payload_type_eq_exact(dest, &handler->dest_pt)) goto reset; - if (handler->handler_func != handler_func_transcode) + if (handler->handler_func != handler_func_transcode && handler->handler_func != handler_func_blackhole) goto reset; if (handler->packet_decoded != packet_decoded) goto reset; @@ -1754,6 +1767,8 @@ struct codec_handler *codec_handler_get(struct call_media *m, int payload_type, out: if (ret) return ret; + if (MEDIA_ISSET(sink, SELECT_PT)) + return &codec_handler_stub_blackhole; if (sh && sh->attrs.transcoding) return &codec_handler_stub_ssrc; #endif diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 0c6f5f44f..d6fc40fe8 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1701,6 +1701,8 @@ output: if (ML_ISSET(media->monologue, BLOCK_SHORT) && ch->payload_len) rpt->min_payload_len = ch->payload_len; + + rpt->blackhole = ch->blackhole; } } diff --git a/include/call.h b/include/call.h index d8d272091..aabd3ebf7 100644 --- a/include/call.h +++ b/include/call.h @@ -219,6 +219,7 @@ enum { * if not set, then inactive. */ #define MEDIA_FLAG_REAL_SENDONLY (1LL << 35) +#define MEDIA_FLAG_SELECT_PT (1LL << 36) /* struct call_monologue */ #define ML_FLAG_REC_FORWARDING (1LL << 16) diff --git a/include/codec.h b/include/codec.h index 28e212c20..c33b7a18c 100644 --- a/include/codec.h +++ b/include/codec.h @@ -58,6 +58,7 @@ struct codec_handler { bool kernelize:1; bool transcoder:1; bool pcm_dtmf_detect:1; + bool blackhole:1; size_t payload_len; // for short-packet blocking diff --git a/kernel-module/xt_RTPENGINE.c b/kernel-module/xt_RTPENGINE.c index 0f793f0ff..903299f2f 100644 --- a/kernel-module/xt_RTPENGINE.c +++ b/kernel-module/xt_RTPENGINE.c @@ -1798,6 +1798,9 @@ static int proc_list_show(struct seq_file *f, void *v) { g->target.pt_stats[j]->payload_type, o->output.pt_output[j].replace_pattern_len, o->output.pt_output[j].min_payload_len); + if (o->output.pt_output[j].blackhole) + seq_printf(f, " RTP payload type %3u: blackhole\n", + g->target.pt_stats[j]->payload_type); } proc_list_crypto_print(f, &o->encrypt_rtp, &o->output.encrypt, "encryption"); @@ -6025,8 +6028,12 @@ static bool proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_outpu return true; } - // pattern rewriting if (rtp_pt_idx >= 0) { + // blackhole? + if (o->output.pt_output[rtp_pt_idx].blackhole) + return false; + + // pattern rewriting if (o->output.pt_output[rtp_pt_idx].min_payload_len && rtp->payload_len < o->output.pt_output[rtp_pt_idx].min_payload_len) return false; diff --git a/kernel-module/xt_RTPENGINE.h b/kernel-module/xt_RTPENGINE.h index d16996111..07ebad618 100644 --- a/kernel-module/xt_RTPENGINE.h +++ b/kernel-module/xt_RTPENGINE.h @@ -78,6 +78,7 @@ struct rtpengine_pt_output { unsigned int min_payload_len; char replace_pattern[16]; unsigned char replace_pattern_len; + unsigned int blackhole:1; }; struct rtpengine_target_info {