Browse Source

Add 'all' recording method

pull/1502/head
Stefan Mititelu 4 years ago
parent
commit
3813821129
4 changed files with 94 additions and 19 deletions
  1. +1
    -1
      daemon/main.c
  2. +85
    -14
      daemon/recording.c
  3. +5
    -2
      daemon/rtpengine.pod
  4. +3
    -2
      include/recording.h

+ 1
- 1
daemon/main.c View File

@ -512,7 +512,7 @@ static void options(int *argc, char ***argv) {
{ "homer-protocol",0,0,G_OPTION_ARG_STRING, &homerproto, "Transport protocol for Homer (default udp)", "udp|tcp" },
{ "homer-id", 0, 0, G_OPTION_ARG_INT, &rtpe_config.homer_id, "'Capture ID' to use within the HEP protocol", "INT" },
{ "recording-dir", 0, 0, G_OPTION_ARG_STRING, &rtpe_config.spooldir, "Directory for storing pcap and metadata files", "FILE" },
{ "recording-method",0, 0, G_OPTION_ARG_STRING, &rtpe_config.rec_method, "Strategy for call recording", "pcap|proc" },
{ "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" },
#ifdef WITH_IPTABLES_OPTION
{ "iptables-chain",0,0, G_OPTION_ARG_STRING, &rtpe_config.iptables_chain,"Add explicit firewall rules to this iptables chain","STRING" },


+ 85
- 14
daemon/recording.c View File

@ -39,6 +39,14 @@ static int append_meta_chunk(struct recording *recording, const char *buf, unsig
const char *label_fmt, ...)
__attribute__((format(printf,4,5)));
// all methods
static int create_spool_dir_all(const char *spoolpath);
static void init_all(struct call *call);
static void sdp_after_all(struct recording *recording, GString *str, struct call_monologue *ml,
enum call_opmode opmode);
static void dump_packet_all(struct media_packet *mp, const str *s);
static void finish_all(struct call *call);
// pcap methods
static int rec_pcap_create_spool_dir(const char *dirpath);
static void rec_pcap_init(struct call *);
@ -68,15 +76,23 @@ static void rec_pcap_eth_header(unsigned char *, struct packet_stream *);
#define append_meta_chunk_null(r,f...) append_meta_chunk(r, "", 0, f)
static const struct recording_method methods[] = {
const struct recording_method methods[] = {
{
.name = "pcap",
.kernel_support = 0,
.create_spool_dir = rec_pcap_create_spool_dir,
.init_struct = rec_pcap_init,
.sdp_before = NULL,
.sdp_after = sdp_after_pcap,
.meta_chunk = NULL,
.update_flags = NULL,
.dump_packet = dump_packet_pcap,
.finish = finish_pcap,
.init_stream_struct = NULL,
.setup_stream = NULL,
.setup_media = NULL,
.setup_monologue = NULL,
.stream_kernel_info = NULL,
.response = response_pcap,
},
{
@ -95,6 +111,25 @@ static const struct recording_method methods[] = {
.setup_media = setup_media_proc,
.setup_monologue = setup_monologue_proc,
.stream_kernel_info = kernel_info_proc,
.response = NULL,
},
{
.name = "all",
.kernel_support = 0,
.create_spool_dir = create_spool_dir_all,
.init_struct = init_all,
.sdp_before = sdp_before_proc,
.sdp_after = sdp_after_all,
.meta_chunk = meta_chunk_proc,
.update_flags = update_flags_proc,
.dump_packet = dump_packet_all,
.finish = finish_all,
.init_stream_struct = init_stream_proc,
.setup_stream = setup_stream_proc,
.setup_media = setup_media_proc,
.setup_monologue = setup_monologue_proc,
.stream_kernel_info = kernel_info_proc,
.response = response_pcap,
},
};
@ -425,14 +460,14 @@ static char *meta_setup_file(struct recording *recording) {
}
char *meta_filepath = file_path_str(recording->meta_prefix, "/tmp/rtpengine-meta-", ".tmp");
recording->meta_filepath = meta_filepath;
recording->meta_filepath_pcap = meta_filepath;
FILE *mfp = fopen(meta_filepath, "w");
// coverity[check_return : FALSE]
chmod(meta_filepath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
if (mfp == NULL) {
ilog(LOG_ERROR, "Could not open metadata file: %s%s%s", FMT_M(meta_filepath));
free(meta_filepath);
recording->meta_filepath = NULL;
recording->meta_filepath_pcap = NULL;
return NULL;
}
recording->u.pcap.meta_fp = mfp;
@ -513,10 +548,10 @@ static int rec_pcap_meta_finish_file(struct call *call) {
// and move it to the finished file location.
// Rename extension to ".txt".
int fn_len;
char *meta_filename = strrchr(recording->meta_filepath, '/');
char *meta_filename = strrchr(recording->meta_filepath_pcap, '/');
char *meta_ext = NULL;
if (meta_filename == NULL) {
meta_filename = recording->meta_filepath;
meta_filename = recording->meta_filepath_pcap;
}
else {
meta_filename = meta_filename + 1;
@ -529,13 +564,13 @@ static int rec_pcap_meta_finish_file(struct call *call) {
char new_metapath[prefix_len + fn_len + ext_len + 1];
snprintf(new_metapath, prefix_len+fn_len+1, "%s/metadata/%s", spooldir, meta_filename);
snprintf(new_metapath + prefix_len+fn_len, ext_len+1, ".txt");
return_code = return_code || rename(recording->meta_filepath, new_metapath);
return_code = return_code || rename(recording->meta_filepath_pcap, new_metapath);
if (return_code != 0) {
ilog(LOG_ERROR, "Could not move metadata file \"%s\" to \"%s/metadata/\"",
recording->meta_filepath, spooldir);
recording->meta_filepath_pcap, spooldir);
} else {
ilog(LOG_INFO, "Moved metadata file \"%s\" to \"%s/metadata\"",
recording->meta_filepath, spooldir);
recording->meta_filepath_pcap, spooldir);
}
mutex_destroy(&recording->u.pcap.recording_lock);
@ -672,7 +707,8 @@ void recording_finish(struct call *call) {
free(recording->meta_prefix);
free(recording->escaped_callid);
free(recording->meta_filepath);
free(recording->meta_filepath_pcap);
free(recording->meta_filepath_proc);
g_slice_free1(sizeof(*(recording)), recording);
call->recording = NULL;
@ -687,10 +723,10 @@ void recording_finish(struct call *call) {
static int open_proc_meta_file(struct recording *recording) {
int fd;
fd = open(recording->meta_filepath, O_WRONLY | O_APPEND | O_CREAT, 0666);
fd = open(recording->meta_filepath_proc, O_WRONLY | O_APPEND | O_CREAT, 0666);
if (fd == -1) {
ilog(LOG_ERR, "Failed to open recording metadata file '%s' for writing: %s",
recording->meta_filepath, strerror(errno));
recording->meta_filepath_proc, strerror(errno));
return -1;
}
return fd;
@ -756,8 +792,8 @@ static void proc_init(struct call *call) {
}
ilog(LOG_DEBUG, "kernel call idx is %u", recording->u.proc.call_idx);
recording->meta_filepath = file_path_str(recording->meta_prefix, "/", ".meta");
unlink(recording->meta_filepath); // start fresh XXX good idea?
recording->meta_filepath_proc = file_path_str(recording->meta_prefix, "/", ".meta");
unlink(recording->meta_filepath_proc); // start fresh XXX good idea?
append_meta_chunk_str(recording, &call->callid, "CALL-ID");
append_meta_chunk_s(recording, recording->meta_prefix, "PARENT");
@ -791,7 +827,7 @@ static void finish_proc(struct call *call) {
struct packet_stream *ps = l->data;
ps->recording.u.proc.stream_idx = UNINIT_IDX;
}
unlink(recording->meta_filepath);
unlink(recording->meta_filepath_proc);
}
static void init_stream_proc(struct packet_stream *stream) {
@ -904,3 +940,38 @@ static void kernel_info_proc(struct packet_stream *stream, struct rtpengine_targ
static void meta_chunk_proc(struct recording *recording, const char *label, const str *data) {
append_meta_chunk_str(recording, data, "%s", label);
}
static int create_spool_dir_all(const char *spoolpath) {
int ret1, ret2;
ret1 = rec_pcap_create_spool_dir(spoolpath);
ret2 = check_main_spool_dir(spoolpath);
if (ret1 == FALSE || ret2 == FALSE) {
return FALSE;
}
return TRUE;
}
static void init_all(struct call *call) {
rec_pcap_init(call);
proc_init(call);
}
static void sdp_after_all(struct recording *recording, GString *str, struct call_monologue *ml,
enum call_opmode opmode)
{
sdp_after_pcap(recording, str, ml, opmode);
sdp_after_proc(recording, str, ml, opmode);
}
static void dump_packet_all(struct media_packet *mp, const str *s) {
dump_packet_pcap(mp, s);
dump_packet_proc(mp, s);
}
static void finish_all(struct call *call) {
finish_pcap(call);
finish_proc(call);
}

+ 5
- 2
daemon/rtpengine.pod View File

@ -603,11 +603,11 @@ Since call recording via this method happens entirely in userspace,
in-kernel packet forwarding cannot be used for calls that are currently
being recorded and packet forwarding will thus be done in userspace only.
=item B<--recording-method=>B<pcap>|B<proc>
=item B<--recording-method=>B<pcap>|B<proc>|B<all>
Multiple methods of call recording are supported and this option can be
used to select one.
Currently supported are the method B<pcap> and B<proc>.
Currently supported are the method B<pcap>, B<proc> and B<all>.
The default method is B<pcap> and is the one described above.
The recording method B<proc> works by writing metadata files directly into
@ -629,6 +629,9 @@ any purpose or not.
In-kernel packet forwarding is fully supported with this recording method
even for calls being recorded.
The recording method B<all> will enable both B<pcap> and B<proc>
at the same time.
=item B<--recording-format=>B<raw>|B<eth>
When recording to pcap file in B<raw> (default) format, there is no


+ 3
- 2
include/recording.h View File

@ -44,14 +44,15 @@ struct recording_stream_proc {
};
struct recording {
union {
struct {
struct recording_pcap pcap;
struct recording_proc proc;
} u;
char *escaped_callid; // call-id with dangerous characters escaped
char *meta_prefix; // escaped call-id plus random suffix
char *meta_filepath; // full file path
char *meta_filepath_proc; // full file path
char *meta_filepath_pcap; // full file path
};
struct recording_stream {


Loading…
Cancel
Save