Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions daemon/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ static void options(int *argc, char ***argv, charp_ht templates) {
{ "recording-method",0, 0, G_OPTION_ARG_STRING, &rtpe_config.rec_method, "Strategy for call recording", "pcap|proc|all" },
{ "recording-format",0, 0, G_OPTION_ARG_STRING, &rtpe_config.rec_format, "File format for stored pcap files", "raw|eth" },
{ "record-egress",0, 0, G_OPTION_ARG_NONE, &rtpe_config.rec_egress, "Recording egress media instead of ingress", NULL },
{ "record-both",0, 0, G_OPTION_ARG_NONE, &rtpe_config.rec_both, "Record both ingress and egress media", NULL },
#ifdef HAVE_LIBIPTC
{ "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_config.iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" },
#endif
Expand Down
3 changes: 2 additions & 1 deletion daemon/media_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,14 +371,15 @@ static bool __send_timer_send_1(struct rtp_header *rh, struct packet_stream *sin
req->buf = bufferpool_ref(cp->s.s);
uring_methods.sendmsg(&sink_fd->socket, &req->msg, &sink->endpoint, &req->sin, &req->req);

if (sink->call->recording && rtpe_config.rec_egress) {
if (sink->call->recording && (rtpe_config.rec_egress || rtpe_config.rec_both)) {
// fill in required members
struct media_packet mp = {
.call = sink->call,
.stream = sink,
.media = sink->media,
.sfd = sink_fd,
.fsin = sink->endpoint,
.recording_egress = true,
};
dump_packet(&mp, cp->plain.s ? &cp->plain : &cp->s);
}
Expand Down
5 changes: 3 additions & 2 deletions daemon/media_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -3084,7 +3084,7 @@ int media_packet_encrypt(rewrite_func encrypt_func, struct packet_stream *out, s
LOCK(&out->lock);

IQUEUE_FOREACH(&mp->packets_out, p) {
if (mp->call->recording && rtpe_config.rec_egress && CALL_ISSET(mp->call, RECORDING_ON)) {
if (mp->call->recording && (rtpe_config.rec_egress || rtpe_config.rec_both) && CALL_ISSET(mp->call, RECORDING_ON)) {
p->plain = STR_LEN(bufferpool_alloc(media_bufferpool, p->s.len), p->s.len);
memcpy(p->plain.s, p->s.s, p->s.len);
p->plain_free_func = bufferpool_unref;
Expand Down Expand Up @@ -3557,7 +3557,8 @@ static int stream_packet(struct packet_handler_ctx *phc) {
}

// If recording pcap dumper is set, then we record the call.
if (phc->mp.call->recording && !rtpe_config.rec_egress)
phc->mp.recording_egress = false;
if (phc->mp.call->recording && (!rtpe_config.rec_egress || rtpe_config.rec_both))
dump_packet(&phc->mp, &phc->s);

phc->mp.raw = phc->s;
Expand Down
2 changes: 1 addition & 1 deletion daemon/recording.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ static void rec_pcap_recording_finish_file(struct recording *recording) {
// "out" must be at least inp->len + MAX_PACKET_HEADER_LEN bytes
static unsigned int fake_ip_header(unsigned char *out, struct media_packet *mp, const str *inp) {
endpoint_t *src_endpoint, *dst_endpoint;
if (!rtpe_config.rec_egress) {
if (!mp->recording_egress) {
src_endpoint = &mp->fsin;
dst_endpoint = &mp->sfd->socket.local;
}
Expand Down
21 changes: 21 additions & 0 deletions docs/rtpengine.md
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,27 @@ call to inject-DTMF won't be sent to __\-\-dtmf-log-dest=__ or __\-\-listen-tcp-
possible to include manipulated and generated media (such as from the __play
media__ command) in the recordings.

- __\-\-record-both__

Apply media recording to **both** ingress (received) and egress (sent) media
streams simultaneously.

By default, without either __\-\-record-egress__ or __\-\-record-both__, only
ingress media (packets as they arrive at __rtpengine__) is recorded. When
__\-\-record-egress__ is used alone, only egress media (packets as they leave
__rtpengine__) is recorded instead.

With __\-\-record-both__, neither direction is excluded: every packet is
recorded twice — once on ingress and once on egress — so that the recording
captures the full picture.

This option implies the behaviour of __\-\-record-egress__ in addition to the
default ingress recording. It takes effect wherever a recording is active
(i.e. the `record-call` flag has been set on the call).

__\-\-record-both__ supersedes __\-\-record-egress__: if both flags are
supplied, the behaviour is identical to __\-\-record-both__ alone.

- __\-\-iptables-chain=__*STRING*

This option enables explicit management of an iptables chain.
Expand Down
2 changes: 2 additions & 0 deletions etc/rtpengine.conf
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ port-max = 39999
recording-dir = /var/spool/rtpengine
recording-method = proc
# recording-format = raw
# record-egress = false
# record-both = false

# redis = 127.0.0.1:6379/5
# redis-write = password@12.23.34.45:6379/42
Expand Down
1 change: 1 addition & 0 deletions include/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ enum endpoint_learning {
X(no_redis_required) \
X(active_switchover) \
X(rec_egress) \
X(rec_both) \
X(xtables) \
X(nftables_append) \
X(log_keys) \
Expand Down
1 change: 1 addition & 0 deletions include/media_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ struct media_packet {
struct call_media *media_out; // output media
struct sink_handler sink;
struct media_player_cache_entry *cache_entry;
bool recording_egress;

struct rtp_header *rtp;
struct rtcp_packet *rtcp;
Expand Down
Loading