diff --git a/daemon/Makefile b/daemon/Makefile index 2fc6273cd..cd53d0a81 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -124,7 +124,7 @@ SRCS= main.c kernel.c poller.c aux.c control_tcp.c call.c control_udp.c redis.c crypto.c rtp.c call_interfaces.strhash.c dtls.c log.c cli.c graphite.c ice.c \ media_socket.c homer.c recording.c statistics.c cdr.c ssrc.c iptables.c tcp_listener.c \ codec.c load.c dtmf.c -LIBSRCS= loglib.c auxlib.c rtplib.c str.c socket.c streambuf.c +LIBSRCS= loglib.c auxlib.c rtplib.c str.c socket.c streambuf.c ssllib.c ifeq ($(with_transcoding),yes) LIBSRCS+= codeclib.c resample.c endif diff --git a/daemon/main.c b/daemon/main.c index 3b3fce06b..7033ef776 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -42,6 +41,7 @@ #include "graphite.h" #include "codeclib.h" #include "load.h" +#include "ssllib.h" @@ -586,59 +586,15 @@ void fill_initial_rtpe_cfg(struct rtpengine_config* ini_rtpe_cfg) { } -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static mutex_t *openssl_locks; - -static void cb_openssl_threadid(CRYPTO_THREADID *tid) { - pthread_t me; - - me = pthread_self(); - - if (sizeof(me) == sizeof(void *)) - CRYPTO_THREADID_set_pointer(tid, (void *) me); - else - CRYPTO_THREADID_set_numeric(tid, (unsigned long) me); -} - -static void cb_openssl_lock(int mode, int type, const char *file, int line) { - if ((mode & CRYPTO_LOCK)) - mutex_lock(&openssl_locks[type]); - else - mutex_unlock(&openssl_locks[type]); -} - -static void make_OpenSSL_thread_safe(void) { - int i; - - openssl_locks = malloc(sizeof(*openssl_locks) * CRYPTO_num_locks()); - for (i = 0; i < CRYPTO_num_locks(); i++) - mutex_init(&openssl_locks[i]); - - CRYPTO_THREADID_set_callback(cb_openssl_threadid); - CRYPTO_set_locking_callback(cb_openssl_lock); -} -#else -static void make_OpenSSL_thread_safe(void) { - ; -} -#endif - - static void early_init() { socket_init(); // needed for socktype_udp } static void init_everything() { - struct timespec ts; - log_init("rtpengine"); log_format(rtpe_config.log_format); recording_fs_init(rtpe_config.spooldir, rtpe_config.rec_method, rtpe_config.rec_format); - clock_gettime(CLOCK_REALTIME, &ts); - srandom(ts.tv_sec ^ ts.tv_nsec); - SSL_library_init(); - SSL_load_error_strings(); - make_OpenSSL_thread_safe(); + rtpe_ssl_init(); #if !GLIB_CHECK_VERSION(2,32,0) g_thread_init(NULL); diff --git a/lib/socket.c b/lib/socket.c index e71c84e52..49c3315ce 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -696,9 +696,10 @@ int connect_socket_retry(socket_t *r) { int ret = 0; if (r->family->connect(r, &r->remote)) { - if (errno != EINPROGRESS && errno != EALREADY) + if (errno != EINPROGRESS && errno != EALREADY && errno != EISCONN) goto fail; - ret = 1; + if (errno != EISCONN) + ret = 1; } return ret; diff --git a/lib/ssllib.c b/lib/ssllib.c new file mode 100644 index 000000000..bdecb8183 --- /dev/null +++ b/lib/ssllib.c @@ -0,0 +1,51 @@ +#include "ssllib.h" +#include +#include + + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static mutex_t *openssl_locks; + +static void cb_openssl_threadid(CRYPTO_THREADID *tid) { + pthread_t me; + + me = pthread_self(); + + if (sizeof(me) == sizeof(void *)) + CRYPTO_THREADID_set_pointer(tid, (void *) me); + else + CRYPTO_THREADID_set_numeric(tid, (unsigned long) me); +} + +static void cb_openssl_lock(int mode, int type, const char *file, int line) { + if ((mode & CRYPTO_LOCK)) + mutex_lock(&openssl_locks[type]); + else + mutex_unlock(&openssl_locks[type]); +} + +static void make_OpenSSL_thread_safe(void) { + int i; + + openssl_locks = malloc(sizeof(*openssl_locks) * CRYPTO_num_locks()); + for (i = 0; i < CRYPTO_num_locks(); i++) + mutex_init(&openssl_locks[i]); + + CRYPTO_THREADID_set_callback(cb_openssl_threadid); + CRYPTO_set_locking_callback(cb_openssl_lock); +} +#else +static void make_OpenSSL_thread_safe(void) { + ; +} +#endif + + +void rtpe_ssl_init(void) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + srandom(ts.tv_sec ^ ts.tv_nsec); + SSL_library_init(); + SSL_load_error_strings(); + make_OpenSSL_thread_safe(); +} diff --git a/lib/ssllib.h b/lib/ssllib.h new file mode 100644 index 000000000..f0888a87d --- /dev/null +++ b/lib/ssllib.h @@ -0,0 +1,8 @@ +#ifndef __SSLLIB_H__ +#define __SSLLIB_H__ + + +void rtpe_ssl_init(void); + + +#endif diff --git a/lib/streambuf.c b/lib/streambuf.c index 87c67c61c..f6fb86308 100644 --- a/lib/streambuf.c +++ b/lib/streambuf.c @@ -204,6 +204,9 @@ void streambuf_write(struct streambuf *b, const char *s, unsigned int len) { unsigned int out; int ret; + if (!b) + return; + mutex_lock(&b->lock); while (len && !poller_isblocked(b->poller, b->fd_ptr)) { diff --git a/recording-daemon/Makefile b/recording-daemon/Makefile index 95ed90cab..f686b92df 100644 --- a/recording-daemon/Makefile +++ b/recording-daemon/Makefile @@ -26,7 +26,7 @@ LDLIBS+= $(shell pkg-config --libs openssl) SRCS= epoll.c garbage.c inotify.c main.c metafile.c stream.c recaux.c packet.c \ decoder.c output.c mix.c db.c log.c forward.c tag.c poller.c -LIBSRCS= loglib.c auxlib.c rtplib.c codeclib.c resample.c str.c socket.c streambuf.c +LIBSRCS= loglib.c auxlib.c rtplib.c codeclib.c resample.c str.c socket.c streambuf.c ssllib.c OBJS= $(SRCS:.c=.o) $(LIBSRCS:.c=.o) include ../lib/common.Makefile diff --git a/recording-daemon/db.c b/recording-daemon/db.c index 7b183c4ba..80d4862e7 100644 --- a/recording-daemon/db.c +++ b/recording-daemon/db.c @@ -214,7 +214,7 @@ static void db_do_call_id(metafile_t *mf) { execute_wrap(&stm_insert_call, b, &mf->db_id); } static void db_do_call_metadata(metafile_t *mf) { - if (!mf->metadata) + if (!mf->metadata_db) return; if (mf->db_id == 0) return; @@ -224,7 +224,7 @@ static void db_do_call_metadata(metafile_t *mf) { // XXX offload this parsing to proxy module -> bencode list/dictionary str all_meta; - str_init(&all_meta, mf->metadata); + str_init(&all_meta, mf->metadata_db); while (all_meta.len > 1) { str token; if (str_token_sep(&token, &all_meta, '|')) @@ -242,7 +242,7 @@ static void db_do_call_metadata(metafile_t *mf) { execute_wrap(&stm_insert_metadata, b, NULL); } - mf->metadata = NULL; + mf->metadata_db = NULL; } void db_do_call(metafile_t *mf) { diff --git a/recording-daemon/decoder.c b/recording-daemon/decoder.c index 7dd5c4fee..d97c955d7 100644 --- a/recording-daemon/decoder.c +++ b/recording-daemon/decoder.c @@ -17,6 +17,7 @@ #include "codeclib.h" #include "streambuf.h" #include "main.h" +#include "packet.h" int resample_audio; @@ -128,45 +129,27 @@ no_mix_out: } no_recording: - if (ssrc->tcp_fwd_stream) { + if (ssrc->tls_fwd_stream) { // XXX might be a second resampling to same format - dbg("SSRC %lx of stream #%lu has TCP forwarding stream", ssrc->ssrc, stream->id); - AVFrame *dec_frame = resample_frame(&ssrc->tcp_fwd_resampler, frame, &ssrc->tcp_fwd_format); - - if (!ssrc->tcp_fwd_poller.connected) { - int status = connect_socket_retry(&ssrc->tcp_fwd_sock); - if (status == 0) { - ssrc->tcp_fwd_poller.connected = 1; - ssrc->tcp_fwd_poller.blocked = 0; - dbg("TCP connection to %s established", - endpoint_print_buf(&tcp_send_to_ep)); - } - else if (status < 0) { - ilog(LOG_ERR, "Failed to connect TCP socket: %s", strerror(errno)); - streambuf_destroy(ssrc->tcp_fwd_stream); - ssrc->tcp_fwd_stream = NULL; - } - } + dbg("SSRC %lx of stream #%lu has TLS forwarding stream", ssrc->ssrc, stream->id); + AVFrame *dec_frame = resample_frame(&ssrc->tls_fwd_resampler, frame, &ssrc->tls_fwd_format); - if (ssrc->tcp_fwd_poller.connected && ssrc->tcp_fwd_poller.blocked) { - ssrc->tcp_fwd_poller.blocked = 0; - streambuf_writeable(ssrc->tcp_fwd_stream); - } + ssrc_tls_state(ssrc); - if (!ssrc->tcp_fwd_poller.intro) { + if (!ssrc->sent_intro) { if (metafile->metadata) { - dbg("Writing metadata header to TCP"); - streambuf_write(ssrc->tcp_fwd_stream, metafile->metadata, strlen(metafile->metadata) + 1); + dbg("Writing metadata header to TLS"); + streambuf_write(ssrc->tls_fwd_stream, metafile->metadata, strlen(metafile->metadata) + 1); } else { ilog(LOG_WARN, "No metadata present for forwarding connection"); - streambuf_write(ssrc->tcp_fwd_stream, "\0", 1); + streambuf_write(ssrc->tls_fwd_stream, "\0", 1); } - ssrc->tcp_fwd_poller.intro = 1; + ssrc->sent_intro = 1; } - dbg("Writing %u bytes PCM to TCP", dec_frame->linesize[0]); - streambuf_write(ssrc->tcp_fwd_stream, (char *) dec_frame->extended_data[0], + dbg("Writing %u bytes PCM to TLS", dec_frame->linesize[0]); + streambuf_write(ssrc->tls_fwd_stream, (char *) dec_frame->extended_data[0], dec_frame->linesize[0]); av_frame_free(&dec_frame); diff --git a/recording-daemon/main.c b/recording-daemon/main.c index 0eb5eb739..42a9f6632 100644 --- a/recording-daemon/main.c +++ b/recording-daemon/main.c @@ -25,6 +25,7 @@ #include "forward.h" #include "codeclib.h" #include "socket.h" +#include "ssllib.h" @@ -44,9 +45,9 @@ const char *c_mysql_host, *c_mysql_db; int c_mysql_port; const char *forward_to = NULL; -static const char *tcp_send_to = NULL; -endpoint_t tcp_send_to_ep; -int tcp_resample = 8000; +static const char *tls_send_to = NULL; +endpoint_t tls_send_to_ep; +int tls_resample = 8000; static GQueue threads = G_QUEUE_INIT; // only accessed from main thread @@ -70,6 +71,7 @@ static void signals(void) { static void setup(void) { log_init("rtpengine-recording"); + rtpe_ssl_init(); socket_init(); if (decoding_enabled) codeclib_init(0); @@ -161,24 +163,24 @@ 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" }, - { "tcp-resample", 0, 0, G_OPTION_ARG_INT, &tcp_resample, "Sampling rate for TCP PCM output", "INT" }, + { "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" }, { NULL, } }; config_load(argc, argv, e, " - rtpengine recording daemon", "/etc/rtpengine/rtpengine-recording.conf", "rtpengine-recording", &rtpe_common_config); - if (tcp_send_to) { - if (endpoint_parse_any_getaddrinfo_full(&tcp_send_to_ep, tcp_send_to)) - die("Failed to parse 'tcp-send-to' option"); + 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"); } if (!strcmp(output_format, "none")) { output_enabled = 0; if (output_mixed || output_single) die("Output is disabled, but output-mixed or output-single is set"); - if (!forward_to && !tcp_send_to_ep.port) { + if (!forward_to && !tls_send_to_ep.port) { //the daemon has no function die("Both output and forwarding are disabled"); } @@ -186,7 +188,7 @@ static void options(int *argc, char ***argv) { } else if (!output_mixed && !output_single) output_mixed = output_single = 1; - if (output_enabled || tcp_send_to_ep.port) + if (output_enabled || tls_send_to_ep.port) decoding_enabled = 1; if (!os_str || !strcmp(os_str, "file")) diff --git a/recording-daemon/main.h b/recording-daemon/main.h index 76a1dad19..aa683b4b0 100644 --- a/recording-daemon/main.h +++ b/recording-daemon/main.h @@ -27,8 +27,8 @@ extern const char *c_mysql_host, *c_mysql_db; extern int c_mysql_port; extern const char *forward_to; -extern endpoint_t tcp_send_to_ep; -extern int tcp_resample; +extern endpoint_t tls_send_to_ep; +extern int tls_resample; extern volatile int shutdown_flag; diff --git a/recording-daemon/metafile.c b/recording-daemon/metafile.c index 481bcd4cc..451add550 100644 --- a/recording-daemon/metafile.c +++ b/recording-daemon/metafile.c @@ -72,7 +72,7 @@ static void meta_stream_interface(metafile_t *mf, unsigned long snum, char *cont db_do_call(mf); if (output_enabled && output_mixed) { pthread_mutex_lock(&mf->mix_lock); - if (!mf->mix && output_mixed) { + if (!mf->mix) { char buf[256]; snprintf(buf, sizeof(buf), "%s-mix", mf->parent); mf->mix_out = output_new(output_dir, buf); @@ -119,6 +119,7 @@ static void meta_rtp_payload_type(metafile_t *mf, unsigned long mnum, unsigned i // mf is locked static void meta_metadata(metafile_t *mf, char *content) { mf->metadata = g_string_chunk_insert(mf->gsc, content); + mf->metadata_db = mf->metadata; db_do_call(mf); if (forward_to) start_forwarding_capture(mf, content); diff --git a/recording-daemon/packet.c b/recording-daemon/packet.c index dbe5fec58..6a3e6dc38 100644 --- a/recording-daemon/packet.c +++ b/recording-daemon/packet.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "types.h" #include "log.h" #include "rtplib.h" @@ -17,6 +18,61 @@ #include "resample.h" +static ssize_t ssrc_tls_write(void *, const void *, size_t); +static ssize_t ssrc_tls_read(void *, void *, size_t); + +static struct streambuf_funcs ssrc_tls_funcs = { + .write = ssrc_tls_write, + .read = ssrc_tls_read, +}; + +static void ssrc_tls_log_errors(void) { + int i; + char err[160]; + while ((i = ERR_get_error())) { + ERR_error_string(i, err); + dbg("TLS error: %s", err); + } +} + +static int ssrc_tls_check_blocked(SSL *ssl, int ret) { + if (!ssl) + return 0; + int err = SSL_get_error(ssl, ret); + dbg("TLS error code: %i -> %i", ret, err); + switch (err) { + case SSL_ERROR_ZERO_RETURN: + return 0; // eof + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + errno = EAGAIN; + return -1; + case SSL_ERROR_SYSCALL: + return -1; + } + errno = EFAULT; + return -1; +} + +static ssize_t ssrc_tls_write(void *fd, const void *b, size_t s) { + SSL *ssl = fd; + ssrc_tls_log_errors(); + int ret = SSL_write(ssl, b, s); + if (ret > 0) + return ret; + return ssrc_tls_check_blocked(ssl, ret); +} +static ssize_t ssrc_tls_read(void *fd, void *b, size_t s) { + SSL *ssl = fd; + ssrc_tls_log_errors(); + int ret = SSL_read(ssl, b, s); + if (ret > 0) + return ret; + return ssrc_tls_check_blocked(ssl, ret); +} + static void packet_free(void *p) { packet_t *packet = p; if (!packet) @@ -26,18 +82,73 @@ static void packet_free(void *p) { } +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) + SSL_free(ssrc->ssl); + ssrc->ssl = NULL; + if (ssrc->ssl_ctx) + SSL_CTX_free(ssrc->ssl_ctx); + ssrc->ssl_ctx = NULL; + close_socket(&ssrc->tls_fwd_sock); + ssrc->sent_intro = 0; +} + + +void ssrc_tls_state(ssrc_t *ssrc) { + int ret; + + ssrc_tls_log_errors(); + 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)); + ssrc->tls_fwd_poller.state = PS_OPEN; + streambuf_writeable(ssrc->tls_fwd_stream); + } + else + ssrc_tls_check_blocked(ssrc->ssl, ret); + } + else if (status < 0) { + ilog(LOG_ERR, "Failed to connect TLS 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); + } + 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; + streambuf_writeable(ssrc->tls_fwd_stream); + } + else if (ssrc->tls_fwd_poller.state == PS_ERROR) + ssrc_tls_shutdown(ssrc); + ssrc_tls_log_errors(); +} + + void ssrc_free(void *p) { ssrc_t *s = p; packet_sequencer_destroy(&s->sequencer); output_close(s->output); for (int i = 0; i < G_N_ELEMENTS(s->decoders); i++) decoder_free(s->decoders[i]); - if (s->tcp_fwd_stream) { - close_socket(&s->tcp_fwd_sock); - streambuf_destroy(s->tcp_fwd_stream); - s->tcp_fwd_stream = NULL; - resample_shutdown(&s->tcp_fwd_resampler); - } + if (s->tls_fwd_stream) + ssrc_tls_shutdown(s); g_slice_free1(sizeof(*s), s); } @@ -71,37 +182,51 @@ out: ret->output = output_new(output_dir, buf); db_do_stream(mf, ret->output, "single", stream, ssrc); } - if ((stream->forwarding_on || mf->forwarding_on) && !ret->tcp_fwd_stream) { - ZERO(ret->tcp_fwd_poller); - dbg("Starting TCP connection to %s", endpoint_print_buf(&tcp_send_to_ep)); - int status = connect_socket_nb(&ret->tcp_fwd_sock, SOCK_STREAM, &tcp_send_to_ep); - if (status >= 0) { - ret->tcp_fwd_stream = streambuf_new(&ret->tcp_fwd_poller, ret->tcp_fwd_sock.fd); - if (status == 1) - ret->tcp_fwd_poller.blocked = 1; - else { - dbg("TCP connection to %s established", - endpoint_print_buf(&tcp_send_to_ep)); - ret->tcp_fwd_poller.connected = 1; - } + if ((stream->forwarding_on || mf->forwarding_on) && !ret->tls_fwd_stream) { + // initialise the connection + ZERO(ret->tls_fwd_poller); + dbg("Starting TLS connection to %s", endpoint_print_buf(&tls_send_to_ep)); + ret->ssl_ctx = SSL_CTX_new(TLS_client_method()); + if (!ret->ssl_ctx) { + ilog(LOG_ERR, "Failed to create TLS context"); + ssrc_tls_shutdown(ret); + goto tls_out; } - else - ilog(LOG_ERR, "Failed to open/connect TCP socket to %s: %s", - endpoint_print_buf(&tcp_send_to_ep), + 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; + } + 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", + endpoint_print_buf(&tls_send_to_ep), strerror(errno)); - ret->tcp_fwd_format = (format_t) { - .clockrate = tcp_resample, + 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; + } + 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) { + .clockrate = tls_resample, .channels = 1, .format = AV_SAMPLE_FMT_S16, }; +tls_out: + ; } - else if (!(stream->forwarding_on || mf->forwarding_on) && ret->tcp_fwd_stream) { - // XXX same as above - unify - close_socket(&ret->tcp_fwd_sock); - streambuf_destroy(ret->tcp_fwd_stream); - ret->tcp_fwd_stream = NULL; - resample_shutdown(&ret->tcp_fwd_resampler); - } + else if (!(stream->forwarding_on || mf->forwarding_on) && ret->tls_fwd_stream) + ssrc_tls_shutdown(ret); return ret; } diff --git a/recording-daemon/packet.h b/recording-daemon/packet.h index c261189b3..31b0c1640 100644 --- a/recording-daemon/packet.h +++ b/recording-daemon/packet.h @@ -7,4 +7,6 @@ void ssrc_free(void *p); void packet_process(stream_t *, unsigned char *, unsigned len); +void ssrc_tls_state(ssrc_t *ssrc); + #endif diff --git a/recording-daemon/poller.c b/recording-daemon/poller.c index 4fb1eb3ea..48d75e3b7 100644 --- a/recording-daemon/poller.c +++ b/recording-daemon/poller.c @@ -1,10 +1,11 @@ #include "poller.h" void poller_blocked(struct poller *p, void *fdp) { - p->blocked = 1; + p->state = PS_WRITE_BLOCKED; } int poller_isblocked(struct poller *p, void *fdp) { - return p->blocked ? 1 : 0; + return p->state != PS_OPEN; } void poller_error(struct poller *p, void *fdp) { + p->state = PS_ERROR; } diff --git a/recording-daemon/poller.h b/recording-daemon/poller.h index 89218c14a..887a52c16 100644 --- a/recording-daemon/poller.h +++ b/recording-daemon/poller.h @@ -4,10 +4,14 @@ // dummy poller struct poller { - int blocked:1; - int connected:1; - int error:1; - int intro:1; + enum { + PS_CLOSED = 0, + PS_CONNECTING, + PS_HANDSHAKE, + PS_OPEN, + PS_WRITE_BLOCKED, + PS_ERROR, + } state; }; void poller_blocked(struct poller *, void *); diff --git a/recording-daemon/types.h b/recording-daemon/types.h index 41ce7a87b..5217ba7c2 100644 --- a/recording-daemon/types.h +++ b/recording-daemon/types.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "str.h" #include "codeclib.h" #include "poller.h" @@ -80,11 +82,16 @@ struct ssrc_s { decode_t *decoders[128]; output_t *output; - format_t tcp_fwd_format; - resample_t tcp_fwd_resampler; - socket_t tcp_fwd_sock; - struct streambuf *tcp_fwd_stream; - struct poller tcp_fwd_poller; + // TLS output + format_t tls_fwd_format; + resample_t tls_fwd_resampler; + socket_t tls_fwd_sock; + //BIO *bio; + SSL_CTX *ssl_ctx; + SSL *ssl; + struct streambuf *tls_fwd_stream; + struct poller tls_fwd_poller; + int sent_intro:1; }; typedef struct ssrc_s ssrc_t; @@ -103,6 +110,7 @@ struct metafile_s { char *parent; char *call_id; char *metadata; + char *metadata_db; off_t pos; unsigned long long db_id;