Skip to content

Commit

Permalink
MT#55283 Add option to use pure TCP socket
Browse files Browse the repository at this point in the history
closes #1777

Change-Id: Ibdb6ff59068682e3e1f0fd8144e22b489328ef49
  • Loading branch information
rfuchs committed Jan 17, 2024
1 parent 76eec48 commit d5831d9
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 43 deletions.
7 changes: 6 additions & 1 deletion docs/rtpengine-recording.md
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions etc/rtpengine-recording.conf
Expand Up @@ -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

This comment has been minimized.

Copy link
@IgorrG

IgorrG Jan 18, 2024

Contributor

This option left here from initial implementation and should be removed from config example

This comment has been minimized.

Copy link
@rfuchs

rfuchs Jan 18, 2024

Author Member

This option left here from initial implementation and should be removed from config example

Thanks, missed that


### mysql configuration for db storage
# mysql-host = localhost
Expand Down
15 changes: 13 additions & 2 deletions recording-daemon/main.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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" },
Expand All @@ -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, &notify_uri, "Notify destination for finished outputs","URI" },
{ "notify-post", 0, 0, G_OPTION_ARG_NONE, &notify_post, "Use POST instead of GET", NULL },
{ "notify-no-verify", 0, 0, G_OPTION_ARG_NONE, &notify_nverify,"Don't verify HTTPS peer certificate", NULL },
Expand All @@ -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")) {
Expand Down
1 change: 1 addition & 0 deletions recording-daemon/main.h
Expand Up @@ -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;
Expand Down
96 changes: 56 additions & 40 deletions recording-daemon/packet.c
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -244,40 +253,47 @@ 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);
goto tls_out;
}

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) {
Expand Down

0 comments on commit d5831d9

Please sign in to comment.