#ifndef XT_RTPPROXY_H #define XT_RTPPROXY_H #include "common_stats.h" #define RTPE_NUM_PAYLOAD_TYPES 32 #define RTPE_MAX_FORWARD_DESTINATIONS 32 #define RTPE_NUM_SSRC_TRACKING 4 #define RTPE_NUM_EXTMAP_FILTER 32 #define RTPE_NUM_OUTPUT_MEDIA 8 struct global_stats_counter; struct xt_rtpengine_info { unsigned int id; }; enum rtpengine_nft_attributes { RTPEA_RTPENGINE_UNSPEC, RTPEA_RTPENGINE_TABLE, __RTPEA_RTPENGINE_MAX }; #define RTPEA_RTPENGINE_MAX (__RTPEA_RTPENGINE_MAX - 1) struct re_address { int family; union { unsigned char ipv6[16]; uint32_t ipv4; unsigned char u8[16]; uint16_t u16[8]; uint32_t u32[4]; } u; uint16_t port; }; enum rtpengine_cipher { REC_INVALID = 0, REC_NULL, REC_AES_CM_128, REC_AES_F8, REC_AES_CM_192, REC_AES_CM_256, REC_AEAD_AES_GCM_128, REC_AEAD_AES_GCM_256, __REC_LAST }; enum rtpengine_hmac { REH_INVALID = 0, REH_NULL, REH_HMAC_SHA1, __REH_LAST }; struct rtpengine_srtp { enum rtpengine_cipher cipher; enum rtpengine_hmac hmac; unsigned char master_key[32]; unsigned int master_key_len; unsigned char master_salt[14]; unsigned int master_salt_len; unsigned int session_key_len; unsigned int session_salt_len; unsigned char mki[256]; unsigned int rtp_auth_tag_len; /* in bytes */ unsigned int rtcp_auth_tag_len; /* in bytes */ unsigned int mki_len; }; enum rtpengine_src_mismatch { MSM_IGNORE = 0, /* process packet as normal */ MSM_DROP, /* drop packet */ MSM_PROPAGATE, /* propagate to userspace daemon */ }; struct rtpengine_pt_output { unsigned int min_payload_len; char replace_pattern[16]; unsigned char replace_pattern_len; unsigned int blackhole:1; }; struct rtpengine_output_group { unsigned int rtp_start_idx; unsigned int rtp_end_idx; unsigned int rtcp_start_idx; unsigned int rtcp_end_idx; }; struct rtpengine_ring_buf_group { unsigned int start_idx; unsigned int num; void *opaque; // copied into buf_slot->opaque atomic_t *opaque_ref; // increased for each reported event }; struct rtpengine_target_info { struct re_address local; struct re_address expected_src; /* for incoming packets */ enum rtpengine_src_mismatch src_mismatch; unsigned int num_destinations; // total unsigned int intercept_stream_idx; struct rtpengine_output_group media_output_idxs[RTPE_NUM_OUTPUT_MEDIA]; struct rtpengine_srtp decrypt; uint32_t ssrc[RTPE_NUM_SSRC_TRACKING]; // Expose the SSRC to userspace when we resync. struct ssrc_stats *ssrc_stats[RTPE_NUM_SSRC_TRACKING]; // pinned memory unsigned int ssrc_media_idx[RTPE_NUM_PAYLOAD_TYPES]; // same idx as ssrc struct rtp_stats *pt_stats[RTPE_NUM_PAYLOAD_TYPES]; // must be sorted by PT, pinned memory unsigned int pt_media_idx[RTPE_NUM_PAYLOAD_TYPES]; // same idx as pt_stats unsigned int num_payload_types; uint8_t extmap_mid; struct { char mid[255]; size_t len; } mid_output[RTPE_NUM_OUTPUT_MEDIA]; struct interface_stats_block *iface_stats; // for ingress stats, pinned memory struct stream_stats *stats; // for ingress stats, pinned memory struct rtpengine_ring_buf_group raw_ring_buf; // for unhandled packets unsigned int extmap:1, dtls:1, stun:1, rtp:1, ssrc_req:1, rtp_only:1, track_ssrc:1, rtcp:1, rtcp_fw:1, rtcp_fb_fw:1, do_intercept:1, pt_filter:1, non_forwarding:1, // empty src/dst addr blackhole:1, rtp_stats:1; // requires SSRC and clock_rates to be set }; struct rtpengine_output_info { struct re_address src_addr; /* for outgoing packets */ struct re_address dst_addr; unsigned int media_idx; struct rtpengine_srtp encrypt; uint32_t ssrc_out[RTPE_NUM_SSRC_TRACKING]; // Rewrite SSRC uint32_t seq_offset[RTPE_NUM_SSRC_TRACKING]; // Rewrite output seq struct rtpengine_pt_output pt_output[RTPE_NUM_PAYLOAD_TYPES]; // same indexes as pt_input uint8_t extmap_filter[RTPE_NUM_EXTMAP_FILTER]; // must be sorted unsigned int num_extmap_filter; uint8_t extmap_mid; uint8_t extmap_mid_len; char extmap_mid_str[255]; struct interface_stats_block *iface_stats; // for egress stats, pinned memory struct stream_stats *stats; // for egress stats, pinned memory struct ssrc_stats *ssrc_stats[RTPE_NUM_SSRC_TRACKING]; // pinned memory unsigned char tos; unsigned int ssrc_subst:1, extmap:1, rtcp:1; }; struct rtpengine_destination_info { struct re_address local; unsigned int num; struct rtpengine_output_info output; }; struct rtpengine_call_info { unsigned int call_idx; char call_id[256]; }; struct rtpengine_stream_idx_info { unsigned int call_idx; unsigned int stream_idx; }; struct rtpengine_stream_info { struct rtpengine_stream_idx_info idx; unsigned int max_packets; char stream_name[256]; }; struct rtpengine_packet_info { unsigned int call_idx; unsigned int stream_idx; unsigned char data[]; }; enum rtpengine_command { REMG_INIT = 1, REMG_ADD_TARGET, REMG_ADD_DESTINATION, REMG_ADD_CALL, REMG_DEL_CALL, REMG_ADD_STREAM, __REMG_UNSUED_1, // REMG_DEL_STREAM, REMG_PACKET, REMG_DEL_TARGET, REMG_INIT_PLAY_STREAMS, REMG_GET_PACKET_STREAM, REMG_PLAY_STREAM_PACKET, REMG_PLAY_STREAM, REMG_STOP_STREAM, REMG_FREE_PACKET_STREAM, REMG_PIN_MEMORY, REMG_RING_BUFFER, __REMG_LAST }; struct rtpengine_init_info { int last_cmd; size_t msg_size[__REMG_LAST]; struct global_stats_counter *rtpe_stats; // pinned memory }; struct rtpengine_command_init { enum rtpengine_command cmd; struct rtpengine_init_info init; }; struct rtpengine_play_stream_info { struct re_address src_addr; struct re_address dst_addr; unsigned char pt; uint32_t ssrc; uint32_t ts; // start TS uint16_t seq; // start seq int tos; struct rtpengine_srtp encrypt; unsigned int packet_stream_idx; struct interface_stats_block *iface_stats; // for egress stats, pinned memory struct stream_stats *stats; // for egress stats, pinned memory struct ssrc_stats *ssrc_stats; // pinned memory int repeat; int remove_at_end; }; struct rtpengine_play_stream_packet_info { unsigned int packet_stream_idx; unsigned long delay_ms; // first packet = 0 uint32_t delay_ts; // first packet = 0 uint32_t duration_ts; unsigned char data[]; }; struct rtpengine_pin_memory_info { void *addr; size_t size; }; struct rtpengine_ring_buf_shm { atomic_t writers; // lock for readers atomic_t readers; // lock for writers atomic_t queue; // added to readers when processing starts atomic_t slots_filled; atomic64 filled[3]; // buffers (input, output, interim) }; struct rtpengine_buf_metadata { struct re_address src; struct re_address dst; void *opaque; // copied from buf_group->opaque int64_t ts; // microseconds unsigned int tos; }; struct rtpengine_buf_slot_step { ssize_t offset; // from start of buffer size_t length; unsigned int buffer_idx; }; struct rtpengine_buf_slot { struct rtpengine_buf_slot_step steps[3]; }; struct rtpengine_ring_buf { void *head; // in pinned memory struct rtpengine_buf_slot *slots; // in pinned memory struct rtpengine_buf_metadata *metadata; // in pinned memory struct rtpengine_ring_buf_shm *shm; // in pinned memory }; struct rtpengine_ring_buf_info { unsigned int idx; // monotonically increasing from 0 unsigned int num_steps; size_t sizes[3]; // input, output, interim unsigned int num_slots; struct rtpengine_ring_buf buf[2]; atomic_t *buf_idx; // in pinned memory int run_now_event; // notified as soon as there is data int writers_done_event; // notified when waiting for writers to finish bool sender; }; struct rtpengine_command_add_target { enum rtpengine_command cmd; struct rtpengine_target_info target; }; struct rtpengine_command_del_target { enum rtpengine_command cmd; struct re_address local; }; struct rtpengine_command_destination { enum rtpengine_command cmd; struct rtpengine_destination_info destination; }; struct rtpengine_command_add_call { enum rtpengine_command cmd; struct rtpengine_call_info call; }; struct rtpengine_command_del_call { enum rtpengine_command cmd; unsigned int call_idx; }; struct rtpengine_command_add_stream { enum rtpengine_command cmd; struct rtpengine_stream_info stream; }; struct rtpengine_command_del_stream { enum rtpengine_command cmd; struct rtpengine_stream_idx_info stream; }; struct rtpengine_command_packet { enum rtpengine_command cmd; struct rtpengine_packet_info packet; }; struct rtpengine_command_init_play_streams { enum rtpengine_command cmd; unsigned int num_packet_streams; unsigned int num_play_streams; }; struct rtpengine_command_get_packet_stream { enum rtpengine_command cmd; unsigned int packet_stream_idx; // output }; struct rtpengine_command_play_stream_packet { enum rtpengine_command cmd; struct rtpengine_play_stream_packet_info play_stream_packet; }; struct rtpengine_command_play_stream { enum rtpengine_command cmd; struct rtpengine_play_stream_info info; // input unsigned int play_idx; // output }; struct rtpengine_command_stop_stream { enum rtpengine_command cmd; unsigned int play_idx; }; struct rtpengine_command_free_packet_stream { enum rtpengine_command cmd; unsigned int packet_stream_idx; }; struct rtpengine_command_pin_memory { enum rtpengine_command cmd; struct rtpengine_pin_memory_info pin_memory; }; struct rtpengine_command_ring_buf { enum rtpengine_command cmd; struct rtpengine_ring_buf_info buf; }; #endif