diff --git a/docs/rtpengine-recording.md b/docs/rtpengine-recording.md index 0c583b3d99..bad2837a70 100644 --- a/docs/rtpengine-recording.md +++ b/docs/rtpengine-recording.md @@ -307,12 +307,17 @@ sufficient for a standard installation of rtpengine. Forward raw RTP packets to a Unix socket. Disabled by default. +- __\-\-tcp-send-to=__*IP*:*PORT* +- __\-\-tcp-resample=__*INT* - __\-\-tls-send-to=__*IP*:*PORT* - __\-\-tls-resample=__*INT* - Send decoded audio over a TCP TLS connection to the specified destination. + Send decoded audio over a TCP or TLS connection to the specified destination. Audio is sent as raw mono 16-bit PCM in the given sample rate. + Only one of these option combinations (TCP or TLS) can be active at the + same time. + - __\-\-notify-uri=__*URI* Enable HTTP notification about finished recordings to the specified URI, which diff --git a/etc/rtpengine-recording.conf b/etc/rtpengine-recording.conf index 681415de48..162f664b1b 100644 --- a/etc/rtpengine-recording.conf +++ b/etc/rtpengine-recording.conf @@ -41,6 +41,7 @@ table = 0 ### TCP/TLS output of PCM audio # tls-send-to = 10.4.1.7:15413 # tls-resample = 16000 +# tls-disable = 0 ### mysql configuration for db storage # mysql-host = localhost diff --git a/recording-daemon/main.c b/recording-daemon/main.c index bbaa9a2e0d..1490cfea9e 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -59,6 +59,7 @@ char *forward_to = NULL; static char *tls_send_to = NULL; endpoint_t tls_send_to_ep; int tls_resample = 8000; +bool tls_disable = false; char *notify_uri; gboolean notify_post; gboolean notify_nverify; @@ -189,6 +190,7 @@ static void options(int *argc, char ***argv) { g_autoptr(char) user_uid = NULL; g_autoptr(char) group_gid = NULL; g_autoptr(char) mix_method_str = NULL; + g_autoptr(char) tcp_send_to = NULL; GOptionEntry e[] = { { "table", 't', 0, G_OPTION_ARG_INT, &ktable, "Kernel table rtpengine uses", "INT" }, @@ -214,8 +216,10 @@ static void options(int *argc, char ***argv) { { "mysql-pass", 0, 0, G_OPTION_ARG_STRING, &c_mysql_pass, "MySQL connection credentials", "PASSWORD" }, { "mysql-db", 0, 0, G_OPTION_ARG_STRING, &c_mysql_db, "MySQL database name", "STRING" }, { "forward-to", 0, 0, G_OPTION_ARG_STRING, &forward_to, "Where to forward to (unix socket)", "PATH" }, + { "tcp-send-to", 0, 0, G_OPTION_ARG_STRING, &tcp_send_to, "Where to send to (TCP destination)", "IP:PORT" }, { "tls-send-to", 0, 0, G_OPTION_ARG_STRING, &tls_send_to, "Where to send to (TLS destination)", "IP:PORT" }, - { "tls-resample", 0, 0, G_OPTION_ARG_INT, &tls_resample, "Sampling rate for TLS PCM output", "INT" }, + { "tcp-resample", 0, 0, G_OPTION_ARG_INT, &tls_resample, "Sampling rate for TCP/TLS PCM output", "INT" }, + { "tls-resample", 0, 0, G_OPTION_ARG_INT, &tls_resample, "Sampling rate for TCP/TLS PCM output", "INT" }, { "notify-uri", 0, 0, G_OPTION_ARG_STRING, ¬ify_uri, "Notify destination for finished outputs","URI" }, { "notify-post", 0, 0, G_OPTION_ARG_NONE, ¬ify_post, "Use POST instead of GET", NULL }, { "notify-no-verify", 0, 0, G_OPTION_ARG_NONE, ¬ify_nverify,"Don't verify HTTPS peer certificate", NULL }, @@ -241,9 +245,16 @@ static void options(int *argc, char ***argv) { if (output_format == NULL) output_format = g_strdup("wav"); + if (tcp_send_to) { + if (tls_send_to) + die("Cannot have both 'tcp-send-to' and 'tls-send-to' active at the same time"); + tls_send_to = tcp_send_to; + tls_disable = true; + } + if (tls_send_to) { if (endpoint_parse_any_getaddrinfo_full(&tls_send_to_ep, tls_send_to)) - die("Failed to parse 'tls-send-to' option"); + die("Failed to parse 'tcp-send-to' or 'tls-send-to' option"); } if (!strcmp(output_format, "none")) { diff --git a/recording-daemon/main.h b/recording-daemon/main.h index c2cc636634..35b07c03f6 100644 --- a/recording-daemon/main.h +++ b/recording-daemon/main.h @@ -41,6 +41,7 @@ extern int c_mysql_port; extern char *forward_to; extern endpoint_t tls_send_to_ep; extern int tls_resample; +extern bool tls_disable; extern char *notify_uri; extern gboolean notify_post; extern gboolean notify_nverify; diff --git a/recording-daemon/packet.c b/recording-daemon/packet.c index 6ccecfdcf0..920bff2c2f 100644 --- a/recording-daemon/packet.c +++ b/recording-daemon/packet.c @@ -90,12 +90,14 @@ static void ssrc_tls_shutdown(ssrc_t *ssrc) { streambuf_destroy(ssrc->tls_fwd_stream); ssrc->tls_fwd_stream = NULL; resample_shutdown(&ssrc->tls_fwd_resampler); - if (ssrc->ssl) + if (ssrc->ssl) { SSL_free(ssrc->ssl); - ssrc->ssl = NULL; - if (ssrc->ssl_ctx) + ssrc->ssl = NULL; + } + if (ssrc->ssl_ctx) { SSL_CTX_free(ssrc->ssl_ctx); - ssrc->ssl_ctx = NULL; + ssrc->ssl_ctx = NULL; + } close_socket(&ssrc->tls_fwd_sock); ssrc->sent_intro = 0; } @@ -108,32 +110,39 @@ void ssrc_tls_state(ssrc_t *ssrc) { if (ssrc->tls_fwd_poller.state == PS_CONNECTING) { int status = connect_socket_retry(&ssrc->tls_fwd_sock); if (status == 0) { - dbg("TLS connection to %s doing handshake", - endpoint_print_buf(&tls_send_to_ep)); - ssrc->tls_fwd_poller.state = PS_HANDSHAKE; - if ((ret = SSL_connect(ssrc->ssl)) == 1) { - dbg("TLS connection to %s established", - endpoint_print_buf(&tls_send_to_ep)); + if (tls_disable) { ssrc->tls_fwd_poller.state = PS_OPEN; streambuf_writeable(ssrc->tls_fwd_stream); + } else { + dbg("TLS connection to %s doing handshake", + endpoint_print_buf(&tls_send_to_ep)); + ssrc->tls_fwd_poller.state = PS_HANDSHAKE; + if ((ret = SSL_connect(ssrc->ssl)) == 1) { + dbg("TLS connection to %s established", + endpoint_print_buf(&tls_send_to_ep)); + ssrc->tls_fwd_poller.state = PS_OPEN; + streambuf_writeable(ssrc->tls_fwd_stream); + } + else + ssrc_tls_check_blocked(ssrc->ssl, ret); } - else - ssrc_tls_check_blocked(ssrc->ssl, ret); } else if (status < 0) { - ilog(LOG_ERR, "Failed to connect TLS socket: %s", strerror(errno)); + ilog(LOG_ERR, "Failed to connect TLS/TCP socket: %s", strerror(errno)); ssrc_tls_shutdown(ssrc); } } else if (ssrc->tls_fwd_poller.state == PS_HANDSHAKE) { - if ((ret = SSL_connect(ssrc->ssl)) == 1) { - dbg("TLS connection to %s established", - endpoint_print_buf(&tls_send_to_ep)); - ssrc->tls_fwd_poller.state = PS_OPEN; - streambuf_writeable(ssrc->tls_fwd_stream); + if (!tls_disable) { + if ((ret = SSL_connect(ssrc->ssl)) == 1) { + dbg("TLS connection to %s established", + endpoint_print_buf(&tls_send_to_ep)); + ssrc->tls_fwd_poller.state = PS_OPEN; + streambuf_writeable(ssrc->tls_fwd_stream); + } + else + ssrc_tls_check_blocked(ssrc->ssl, ret); } - else - ssrc_tls_check_blocked(ssrc->ssl, ret); } else if (ssrc->tls_fwd_poller.state == PS_WRITE_BLOCKED) { ssrc->tls_fwd_poller.state = PS_OPEN; @@ -244,26 +253,30 @@ static ssrc_t *ssrc_get(stream_t *stream, unsigned long ssrc) { if ((stream->forwarding_on || mf->forwarding_on) && !ret->tls_fwd_stream && tls_send_to_ep.port) { // initialise the connection ZERO(ret->tls_fwd_poller); - dbg("Starting TLS connection to %s", endpoint_print_buf(&tls_send_to_ep)); + if (!tls_disable) { + dbg("Starting TLS connection to %s", endpoint_print_buf(&tls_send_to_ep)); #if OPENSSL_VERSION_NUMBER >= 0x10100000L - ret->ssl_ctx = SSL_CTX_new(TLS_client_method()); + ret->ssl_ctx = SSL_CTX_new(TLS_client_method()); #else - ret->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + ret->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); #endif - if (!ret->ssl_ctx) { - ilog(LOG_ERR, "Failed to create TLS context"); - ssrc_tls_shutdown(ret); - goto tls_out; - } - ret->ssl = SSL_new(ret->ssl_ctx); - if (!ret->ssl) { - ilog(LOG_ERR, "Failed to create TLS connection"); - ssrc_tls_shutdown(ret); - goto tls_out; + if (!ret->ssl_ctx) { + ilog(LOG_ERR, "Failed to create TLS context"); + ssrc_tls_shutdown(ret); + goto tls_out; + } + ret->ssl = SSL_new(ret->ssl_ctx); + if (!ret->ssl) { + ilog(LOG_ERR, "Failed to create TLS connection"); + ssrc_tls_shutdown(ret); + goto tls_out; + } + } else { + dbg("Starting TCP connection to %s", endpoint_print_buf(&tls_send_to_ep)); } int status = connect_socket_nb(&ret->tls_fwd_sock, SOCK_STREAM, &tls_send_to_ep); if (status < 0) { - ilog(LOG_ERR, "Failed to open/connect TLS socket to %s: %s", + ilog(LOG_ERR, "Failed to open/connect TLS/TCP socket to %s: %s", endpoint_print_buf(&tls_send_to_ep), strerror(errno)); ssrc_tls_shutdown(ret); @@ -271,13 +284,16 @@ static ssrc_t *ssrc_get(stream_t *stream, unsigned long ssrc) { } ret->tls_fwd_poller.state = PS_CONNECTING; - if (SSL_set_fd(ret->ssl, ret->tls_fwd_sock.fd) != 1) { - ilog(LOG_ERR, "Failed to set TLS fd"); - ssrc_tls_shutdown(ret); - goto tls_out; + if (!tls_disable) { + if (SSL_set_fd(ret->ssl, ret->tls_fwd_sock.fd) != 1) { + ilog(LOG_ERR, "Failed to set TLS fd"); + ssrc_tls_shutdown(ret); + goto tls_out; + } + ret->tls_fwd_stream = streambuf_new_ptr(&ret->tls_fwd_poller, ret->ssl, &ssrc_tls_funcs); + } else { + ret->tls_fwd_stream = streambuf_new(&ret->tls_fwd_poller, ret->tls_fwd_sock.fd); } - ret->tls_fwd_stream = streambuf_new_ptr(&ret->tls_fwd_poller, ret->ssl, &ssrc_tls_funcs); - ssrc_tls_state(ret); ret->tls_fwd_format = (format_t) {