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 {