From b9802690d160c8cae3e66b1c40e7b0e5e7fd4958 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 00:49:28 +0200 Subject: [PATCH 001/128] First code to implement prometheus metrics --- Makefile.in | 4 +- configure | 3 ++ src/apps/relay/prom_server.c | 91 ++++++++++++++++++++++++++++++++++++ src/apps/relay/prom_server.h | 49 +++++++++++++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 src/apps/relay/prom_server.c create mode 100644 src/apps/relay/prom_server.h diff --git a/Makefile.in b/Makefile.in index 078f50c3..a4479e15 100755 --- a/Makefile.in +++ b/Makefile.in @@ -30,8 +30,8 @@ HIREDIS_MODS = src/apps/common/hiredis_libevent2.c USERDB_HEADERS = src/apps/relay/dbdrivers/dbdriver.h src/apps/relay/dbdrivers/dbd_sqlite.h src/apps/relay/dbdrivers/dbd_pgsql.h src/apps/relay/dbdrivers/dbd_mysql.h src/apps/relay/dbdrivers/dbd_mongo.h src/apps/relay/dbdrivers/dbd_redis.h USERDB_MODS = src/apps/relay/dbdrivers/dbdriver.c src/apps/relay/dbdrivers/dbd_sqlite.c src/apps/relay/dbdrivers/dbd_pgsql.c src/apps/relay/dbdrivers/dbd_mysql.c src/apps/relay/dbdrivers/dbd_mongo.c src/apps/relay/dbdrivers/dbd_redis.c -SERVERAPP_HEADERS = src/apps/relay/userdb.h src/apps/relay/tls_listener.h src/apps/relay/mainrelay.h src/apps/relay/turn_admin_server.h src/apps/relay/dtls_listener.h src/apps/relay/libtelnet.h ${HIREDIS_HEADERS} ${USERDB_HEADERS} -SERVERAPP_MODS = src/apps/relay/mainrelay.c src/apps/relay/netengine.c src/apps/relay/libtelnet.c src/apps/relay/turn_admin_server.c src/apps/relay/userdb.c src/apps/relay/tls_listener.c src/apps/relay/dtls_listener.c ${HIREDIS_MODS} ${USERDB_MODS} +SERVERAPP_HEADERS = src/apps/relay/userdb.h src/apps/relay/tls_listener.h src/apps/relay/mainrelay.h src/apps/relay/turn_admin_server.h src/apps/relay/dtls_listener.h src/apps/relay/libtelnet.h src/apps/relay/prom_server.h ${HIREDIS_HEADERS} ${USERDB_HEADERS} +SERVERAPP_MODS = src/apps/relay/mainrelay.c src/apps/relay/netengine.c src/apps/relay/libtelnet.c src/apps/relay/turn_admin_server.c src/apps/relay/userdb.c src/apps/relay/tls_listener.c src/apps/relay/dtls_listener.c src/apps/relay/prom_server.c ${HIREDIS_MODS} ${USERDB_MODS} SERVERAPP_DEPS = ${SERVERTURN_MODS} ${SERVERTURN_DEPS} ${SERVERAPP_MODS} ${SERVERAPP_HEADERS} ${COMMON_DEPS} ${IMPL_DEPS} lib/libturnclient.a TURN_BUILD_RESULTS = bin/turnutils_oauth bin/turnutils_natdiscovery bin/turnutils_stunclient bin/turnutils_rfc5769check bin/turnutils_uclient bin/turnserver bin/turnutils_peer lib/libturnclient.a include/turn/ns_turn_defs.h sqlite_empty_db diff --git a/configure b/configure index a7af75af..f9283117 100755 --- a/configure +++ b/configure @@ -876,6 +876,9 @@ testlib wldap64 testlib intl testlib nsl testlib resolv +testlib prom +testlib promhttp +testlib microhttpd ########################### # Test sockets compilation diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c new file mode 100644 index 00000000..fccb676c --- /dev/null +++ b/src/apps/relay/prom_server.c @@ -0,0 +1,91 @@ +#include "prom_server.h" + +int start_prometheus_server(void){ + prom_collector_registry_default_init(); + turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); + turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + promhttp_set_active_collector_registry(NULL); + + + struct MHD_Daemon *daemon = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY, DEFAULT_PROM_SERVER_PORT, NULL, NULL); + if (daemon == NULL) { + return 1; + } + return 0; +} + +void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime){ + char allocation_chars[1024]; + char lifetime_chars[1024]; + + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + snprintf(lifetime_chars, sizeof(lifetime_chars), "%lu", lifetime); + + prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, lifetime_chars }); +} + +void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_sub(turn_status, 1, (const char *[]) { realm , user, allocation_chars, (char *)"new", (char *)"600" }); + prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, NULL }); + +} + +void prom_set_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); +} + +void prom_set_peer_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_peer_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_peer_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); +} +void prom_set_peer_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); +} diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h new file mode 100644 index 00000000..bfe3a288 --- /dev/null +++ b/src/apps/relay/prom_server.h @@ -0,0 +1,49 @@ + +#ifndef __PROM_SERVER_H__ +#define __PROM_SERVER_H__ + +#include +#include +#include +#include + +#include +#include +#include + +#define DEFAULT_PROM_SERVER_PORT (9121) + +prom_gauge_t *turn_status; +prom_gauge_t *turn_traffic_rcvp; +prom_gauge_t *turn_traffic_rcvb; +prom_gauge_t *turn_traffic_sentp; +prom_gauge_t *turn_traffic_sentb; +prom_gauge_t *turn_traffic_peer_rcvp; +prom_gauge_t *turn_traffic_peer_rcvb; +prom_gauge_t *turn_traffic_peer_sentp; +prom_gauge_t *turn_traffic_peer_sentb; + +#ifdef __cplusplus +extern "C" { +#endif + +int start_prometheus_server(void); + +void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime); +void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status); +void prom_set_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp); +void prom_set_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb); +void prom_set_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp); +void prom_set_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb); +void prom_set_peer_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp); +void prom_set_peer_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb); +void prom_set_peer_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp); +void prom_set_peer_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb); + + + +#ifdef __cplusplus +} +#endif /* __clplusplus */ + +#endif /* __PROM_SERVER_H__ */ \ No newline at end of file From 9ed631c49579fa52d12321b8edc1488cb543a5da Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 00:51:42 +0200 Subject: [PATCH 002/128] Prometheus server init and first metrics --- src/apps/relay/mainrelay.c | 3 +++ src/apps/relay/ns_ioalib_engine_impl.c | 35 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 6710da6d..a35fad40 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -30,6 +30,8 @@ #include "mainrelay.h" #include "dbdrivers/dbdriver.h" +#include "prom_server.h" + #if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) #undef OPENSSL_VERSION_NUMBER @@ -2432,6 +2434,7 @@ int main(int argc, char **argv) event_add(ev, NULL); drop_privileges(); + start_prometheus_server(); run_listener_server(&(turn_params.listener)); diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 60db2cd8..9ee51b60 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -38,6 +38,8 @@ #include "ns_ioalib_impl.h" +#include "prom_server.h" + #if TLS_SUPPORTED #include #endif @@ -3528,6 +3530,11 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) send_message_to_redis(e->rch, "publish", key, "%s lifetime=%lu", status, (unsigned long)lifetime); } #endif + if(ss->realm_options.name[0]) { + prom_set_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); + } else { + prom_set_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); + } } } } @@ -3571,6 +3578,12 @@ void turn_report_allocation_delete(void *a) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes)); } #endif + if(ss->realm_options.name[0]){ + prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + } else { + prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + + } } } } @@ -3606,6 +3619,28 @@ void turn_report_session_usage(void *session, int force_invalid) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); } #endif + if(ss->realm_options.name[0]){ + prom_set_rcvp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets)); + prom_set_rcvb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_bytes)); + prom_set_sentp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_packets)); + prom_set_sentb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_bytes)); + + prom_set_peer_rcvp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets)); + prom_set_peer_rcvb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_bytes)); + prom_set_peer_sentp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_packets)); + prom_set_peer_sentb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_bytes)); + } else { + prom_set_rcvp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets)); + prom_set_rcvb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_bytes)); + prom_set_sentp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_packets)); + prom_set_sentb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_bytes)); + + prom_set_peer_rcvp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets)); + prom_set_peer_rcvb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_bytes)); + prom_set_peer_sentp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_packets)); + prom_set_peer_sentb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_bytes)); + } + ss->t_received_packets += ss->received_packets; ss->t_received_bytes += ss->received_bytes; ss->t_sent_packets += ss->sent_packets; From 3e22d7e1993542f05cd7c80be7a03c955806f58f Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 10:26:01 +0200 Subject: [PATCH 003/128] Refactor to use only one function to set metrics --- src/apps/relay/ns_ioalib_engine_impl.c | 22 ++-------- src/apps/relay/prom_server.c | 60 +++++++------------------- src/apps/relay/prom_server.h | 23 ++++++---- 3 files changed, 33 insertions(+), 72 deletions(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 9ee51b60..f6a951b8 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3620,25 +3620,11 @@ void turn_report_session_usage(void *session, int force_invalid) } #endif if(ss->realm_options.name[0]){ - prom_set_rcvp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets)); - prom_set_rcvb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_bytes)); - prom_set_sentp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_packets)); - prom_set_sentb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_bytes)); - - prom_set_peer_rcvp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets)); - prom_set_peer_rcvb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_bytes)); - prom_set_peer_sentp(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_packets)); - prom_set_peer_sentb(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_bytes)); + prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); + prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); } else { - prom_set_rcvp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets)); - prom_set_rcvb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_bytes)); - prom_set_sentp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_packets)); - prom_set_sentb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->sent_bytes)); - - prom_set_peer_rcvp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets)); - prom_set_peer_rcvb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_bytes)); - prom_set_peer_sentp(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_packets)); - prom_set_peer_sentb(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_sent_bytes)); + prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); + prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); } ss->t_received_packets += ss->received_packets; diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index fccb676c..8cad6b61 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -3,14 +3,17 @@ int start_prometheus_server(void){ prom_collector_registry_default_init(); turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); + turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + promhttp_set_active_collector_registry(NULL); @@ -39,53 +42,20 @@ void prom_del_status(const char* realm, const char* user, unsigned long long all prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, NULL }); } - -void prom_set_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp){ +void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ char allocation_chars[1024]; snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + if (peer){ + prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } else { + prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } } -void prom_set_peer_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_peer_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_peer_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); -} -void prom_set_peer_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); -} diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index bfe3a288..0ab1f23a 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -14,15 +15,27 @@ #define DEFAULT_PROM_SERVER_PORT (9121) prom_gauge_t *turn_status; + prom_gauge_t *turn_traffic_rcvp; prom_gauge_t *turn_traffic_rcvb; prom_gauge_t *turn_traffic_sentp; prom_gauge_t *turn_traffic_sentb; + +prom_gauge_t *turn_total_traffic_rcvp; +prom_gauge_t *turn_total_traffic_rcvb; +prom_gauge_t *turn_total_traffic_sentp; +prom_gauge_t *turn_total_traffic_sentb; + prom_gauge_t *turn_traffic_peer_rcvp; prom_gauge_t *turn_traffic_peer_rcvb; prom_gauge_t *turn_traffic_peer_sentp; prom_gauge_t *turn_traffic_peer_sentb; +prom_gauge_t *turn_total_traffic_peer_rcvp; +prom_gauge_t *turn_total_traffic_peer_rcvb; +prom_gauge_t *turn_total_traffic_peer_sentp; +prom_gauge_t *turn_total_traffic_peer_sentb; + #ifdef __cplusplus extern "C" { #endif @@ -31,15 +44,7 @@ int start_prometheus_server(void); void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime); void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status); -void prom_set_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp); -void prom_set_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb); -void prom_set_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp); -void prom_set_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb); -void prom_set_peer_rcvp(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp); -void prom_set_peer_rcvb(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvb); -void prom_set_peer_sentp(const char* realm, const char* user, unsigned long long allocation, unsigned long sentp); -void prom_set_peer_sentb(const char* realm, const char* user, unsigned long long allocation, unsigned long sentb); - +void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); #ifdef __cplusplus From d4850884099ee8e1f37cb2337882b9731b78af4a Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 10:35:50 +0200 Subject: [PATCH 004/128] Added metrics for total traffic --- src/apps/relay/ns_ioalib_engine_impl.c | 5 ++++- src/apps/relay/prom_server.c | 30 ++++++++++++++++++++++++-- src/apps/relay/prom_server.h | 1 + 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index f6a951b8..7d5563f9 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3580,9 +3580,12 @@ void turn_report_allocation_delete(void *a) #endif if(ss->realm_options.name[0]){ prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); } else { prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); - + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } } } diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 8cad6b61..8a1ba69a 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -7,12 +7,22 @@ int start_prometheus_server(void){ turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + + turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvp", "Represents total received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvb", "Represents total received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentp", "Represents total sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentb", "Represents total sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + + turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvp", "Represents total peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvb", "Represents total peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_sentp", "Represents total peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_sentb", "Represents total peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); promhttp_set_active_collector_registry(NULL); @@ -59,3 +69,19 @@ void prom_set_traffic(const char* realm, const char* user, unsigned long long al } } +void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + + if (peer){ + prom_gauge_set(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } else { + prom_gauge_set(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } +} diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index 0ab1f23a..b94c6d2d 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -45,6 +45,7 @@ int start_prometheus_server(void); void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime); void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status); void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); +void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); #ifdef __cplusplus From aeb04743444edc1aed6546bab53a8f18cefb5466 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 10:45:32 +0200 Subject: [PATCH 005/128] Added some comments --- .vscode/c_cpp_properties.json | 16 +++++++++++++++ .vscode/launch.json | 27 +++++++++++++++++++++++++ .vscode/settings.json | 10 +++++++++ libprom-dev-0.1.1-Linux.deb | Bin 0 -> 31754 bytes libpromhttp-dev-0.1.1-Linux.deb | Bin 0 -> 4474 bytes src/apps/relay/ns_ioalib_engine_impl.c | 8 ++++++++ src/apps/relay/prom_server.c | 5 +++++ 7 files changed, 66 insertions(+) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 libprom-dev-0.1.1-Linux.deb create mode 100644 libpromhttp-dev-0.1.1-Linux.deb diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..0b0eed01 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..447de6d2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.out", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..e062fa61 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "files.associations": { + "prom_server.h": "c", + "stdlib.h": "c", + "stdio.h": "c", + "signal.h": "c", + "prom.h": "c", + "unistd.h": "c" + } +} \ No newline at end of file diff --git a/libprom-dev-0.1.1-Linux.deb b/libprom-dev-0.1.1-Linux.deb new file mode 100644 index 0000000000000000000000000000000000000000..8b0ca1001f58502c71010b5ea99b2c0f07619617 GIT binary patch literal 31754 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%0DXvHV^q!vPv$ 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 Pa0I5Hj#fMwJiPw`42Z^o literal 0 HcmV?d00001 diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 7d5563f9..a55f5bbc 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3530,6 +3530,7 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) send_message_to_redis(e->rch, "publish", key, "%s lifetime=%lu", status, (unsigned long)lifetime); } #endif + // Set status on prometheus metric if(ss->realm_options.name[0]) { prom_set_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); } else { @@ -3579,11 +3580,17 @@ void turn_report_allocation_delete(void *a) } #endif if(ss->realm_options.name[0]){ + // Set prometheus del metric and update status prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + + // Set prometheus total traffic metrics prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); } else { + // Set prometheus del metric and update status prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + + // Set prometheus total traffic metrics prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } @@ -3622,6 +3629,7 @@ void turn_report_session_usage(void *session, int force_invalid) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); } #endif + // Set prometheus traffic metrics if(ss->realm_options.name[0]){ prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 8a1ba69a..28879f4e 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -2,23 +2,28 @@ int start_prometheus_server(void){ prom_collector_registry_default_init(); + // Create status gauge metric turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); + // Create traffic gauge metrics turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create traffic for peers gauge metrics turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create total traffic gauge metrics turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvp", "Represents total received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvb", "Represents total received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentp", "Represents total sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentb", "Represents total sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create tota traffic for peers gauge metrics turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvp", "Represents total peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvb", "Represents total peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_sentp", "Represents total peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); From 9c7c9dbf0add0057a9375ba7c1c14a94a1eceba7 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 11:16:54 +0200 Subject: [PATCH 006/128] Remove IDE files and ignore it --- .gitignore | 1 + .vscode/c_cpp_properties.json | 16 ---------------- .vscode/launch.json | 27 --------------------------- .vscode/settings.json | 10 ---------- 4 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index fcc5638e..9af96895 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build include lib sqlite +.vscode diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 0b0eed01..00000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c11", - "cppStandard": "c++17", - "intelliSenseMode": "clang-x64" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 447de6d2..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "(gdb) Launch", - "type": "cppdbg", - "request": "launch", - "program": "enter program name, for example ${workspaceFolder}/a.out", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ] - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index e062fa61..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "files.associations": { - "prom_server.h": "c", - "stdlib.h": "c", - "stdio.h": "c", - "signal.h": "c", - "prom.h": "c", - "unistd.h": "c" - } -} \ No newline at end of file From accb2301401796ab48589bb4fe11abf40304850c Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 11:41:00 +0200 Subject: [PATCH 007/128] Removed .deb libraries included --- libprom-dev-0.1.1-Linux.deb | Bin 31754 -> 0 bytes libpromhttp-dev-0.1.1-Linux.deb | Bin 4474 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 libprom-dev-0.1.1-Linux.deb delete mode 100644 libpromhttp-dev-0.1.1-Linux.deb diff --git a/libprom-dev-0.1.1-Linux.deb b/libprom-dev-0.1.1-Linux.deb deleted file mode 100644 index 8b0ca1001f58502c71010b5ea99b2c0f07619617..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31754 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%0DXvHV^q!vPv$ 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 Pa0I5Hj#fMwJiPw`42Z^o From fb3bd0d353c464b416d8b1ba02bf62ac44f897c4 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Thu, 2 Apr 2020 17:28:21 +0200 Subject: [PATCH 008/128] Added checks to make prometheus optional --- configure | 44 ++++++++++++++++-- src/apps/relay/mainrelay.c | 6 +++ src/apps/relay/ns_ioalib_engine_impl.c | 64 ++++++++++++++++---------- src/apps/relay/prom_server.c | 4 ++ src/apps/relay/prom_server.h | 4 ++ 5 files changed, 94 insertions(+), 28 deletions(-) diff --git a/configure b/configure index f9283117..c816ee6c 100755 --- a/configure +++ b/configure @@ -876,9 +876,6 @@ testlib wldap64 testlib intl testlib nsl testlib resolv -testlib prom -testlib promhttp -testlib microhttpd ########################### # Test sockets compilation @@ -1054,6 +1051,47 @@ else fi fi +########################### +# Test Prometheus +########################### + +if [ -z "${TURN_NO_PROMETHEUS}" ] ; then + + testlib prom + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Prometheus lib found." + testlib promhttp + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Prometheus http lib found." + testlib microhttpd + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Microhttpd lib found." + else + ${ECHO_CMD} "ERROR: microhttpd development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi + else + ${ECHO_CMD} "ERROR: Libpromhttp development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi + else + ${ECHO_CMD} "ERROR: Libprom development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi + +else + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" +fi + ########################### # Test SQLite setup ########################### diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index a35fad40..fc951916 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -30,7 +30,10 @@ #include "mainrelay.h" #include "dbdrivers/dbdriver.h" + +#if !defined(TURN_NO_PROMETHEUS) #include "prom_server.h" +#endif #if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) @@ -2434,7 +2437,10 @@ int main(int argc, char **argv) event_add(ev, NULL); drop_privileges(); +#if !defined(TURN_NO_PROMETHEUS) start_prometheus_server(); +#endif + run_listener_server(&(turn_params.listener)); diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index a55f5bbc..bbc2a11d 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -38,7 +38,9 @@ #include "ns_ioalib_impl.h" +#if !defined(TURN_NO_PROMETHEUS) #include "prom_server.h" +#endif #if TLS_SUPPORTED #include @@ -3530,12 +3532,16 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) send_message_to_redis(e->rch, "publish", key, "%s lifetime=%lu", status, (unsigned long)lifetime); } #endif - // Set status on prometheus metric - if(ss->realm_options.name[0]) { - prom_set_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); - } else { - prom_set_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); +#if !defined(TURN_NO_PROMETHEUS) + { + // Set status on prometheus metric + if(ss->realm_options.name[0]) { + prom_set_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); + } else { + prom_set_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); + } } +#endif } } } @@ -3579,21 +3585,25 @@ void turn_report_allocation_delete(void *a) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes)); } #endif - if(ss->realm_options.name[0]){ - // Set prometheus del metric and update status - prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); +#if !defined(TURN_NO_PROMETHEUS) + { + if(ss->realm_options.name[0]){ + // Set prometheus del metric and update status + prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); - // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); - } else { - // Set prometheus del metric and update status - prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); + // Set prometheus total traffic metrics + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); + } else { + // Set prometheus del metric and update status + prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); - // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + // Set prometheus total traffic metrics + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + } } +#endif } } } @@ -3629,15 +3639,19 @@ void turn_report_session_usage(void *session, int force_invalid) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); } #endif - // Set prometheus traffic metrics - if(ss->realm_options.name[0]){ - prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); - prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); - } else { - prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); - prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); +#if !defined(TURN_NO_PROMETHEUS) + { + // Set prometheus traffic metrics + if(ss->realm_options.name[0]){ + prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); + prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); + } else { + prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); + prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); + } } - +#endif + ss->t_received_packets += ss->received_packets; ss->t_received_bytes += ss->received_bytes; ss->t_sent_packets += ss->sent_packets; diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 28879f4e..0f66de0f 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -1,3 +1,5 @@ +#if !defined(TURN_NO_PROMETHEUS) + #include "prom_server.h" int start_prometheus_server(void){ @@ -90,3 +92,5 @@ void prom_set_total_traffic(const char* realm, const char* user, unsigned long l prom_gauge_set(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); } } + +#endif /* TURN_NO_PROMETHEUS */ diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index b94c6d2d..fcaa9759 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -2,6 +2,8 @@ #ifndef __PROM_SERVER_H__ #define __PROM_SERVER_H__ +#if !defined(TURN_NO_PROMETHEUS) + #include #include #include @@ -40,6 +42,7 @@ prom_gauge_t *turn_total_traffic_peer_sentb; extern "C" { #endif + int start_prometheus_server(void); void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime); @@ -47,6 +50,7 @@ void prom_del_status(const char* realm, const char* user, unsigned long long all void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); +#endif /* TURN_NO_PROMETHEUS */ #ifdef __cplusplus } From 2789a27fb9425261a510d89a0615f82f09b8418c Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 5 May 2020 15:49:50 +0200 Subject: [PATCH 009/128] Added no-promethsu CLI option --- src/apps/relay/mainrelay.c | 14 +++++++ src/apps/relay/mainrelay.h | 4 ++ src/apps/relay/prom_server.c | 81 ++++++++++++++++++++---------------- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index fc951916..3e1b4e28 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -155,6 +155,7 @@ TURN_CREDENTIALS_NONE, /* ct */ 0, /* bps_capacity_allocated */ 0, /* total_quota */ 0, /* user_quota */ +1, /* prometheus enabled by default */ ///////////// Users DB ////////////// { (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} }, ///////////// CPUs ////////////////// @@ -528,6 +529,10 @@ static char Usage[] = "Usage: turnserver [options]\n" " and delivering traffic and allocation event notifications.\n" " The connection string has the same parameters as redis-userdb connection string.\n" #endif +#if !defined(TURN_NO_PROMETHEUS) +" --no-prometheus Disable prometheus metrics. By default it is enabled and listening on port 9121 unther the path /metrics\n" +" also the path / on this port can be used as a health check\n" +#endif " --use-auth-secret TURN REST API flag.\n" " Flag that sets a special authorization option that is based upon authentication secret\n" " (TURN Server REST API, see TURNServerRESTAPI.pdf). This option is used with timestamp.\n" @@ -734,6 +739,7 @@ enum EXTRA_OPTS { MAX_ALLOCATE_LIFETIME_OPT, CHANNEL_LIFETIME_OPT, PERMISSION_LIFETIME_OPT, + NO_PROMETHEUS_OPT, AUTH_SECRET_OPT, DEL_ALL_AUTH_SECRETS_OPT, STATIC_AUTH_SECRET_VAL_OPT, @@ -835,6 +841,9 @@ static const struct myoption long_options[] = { #if !defined(TURN_NO_HIREDIS) { "redis-userdb", required_argument, NULL, 'N' }, { "redis-statsdb", required_argument, NULL, 'O' }, +#endif +#if !defined(TURN_NO_PROMETHEUS) + { "no-prometheus", optional_argument, NULL, NO_PROMETHEUS_OPT }, #endif { "use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT }, { "static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT }, @@ -1427,6 +1436,11 @@ static void set_option(int c, char *value) STRCPY(turn_params.redis_statsdb, value); turn_params.use_redis_statsdb = 1; break; +#endif +#if !defined(TURN_NO_PROMETHEUS) + case NO_PROMETHEUS_OPT: + turn_params.prometheus = 0; + break; #endif case AUTH_SECRET_OPT: turn_params.use_auth_secret_with_timestamp = 1; diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index ea139846..c6fd8d2c 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -309,6 +309,10 @@ typedef struct _turn_params_ { band_limit_t bps_capacity_allocated; vint total_quota; vint user_quota; + #if !defined(TURN_NO_PROMETHEUS) + int prometheus; + #endif + /////// Users DB /////////// diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 0f66de0f..6c79db5e 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -1,8 +1,12 @@ #if !defined(TURN_NO_PROMETHEUS) +#include "mainrelay.h" #include "prom_server.h" int start_prometheus_server(void){ + if (turn_params.prometheus == 0){ + return 0; + } prom_collector_registry_default_init(); // Create status gauge metric turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); @@ -42,54 +46,61 @@ int start_prometheus_server(void){ } void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime){ - char allocation_chars[1024]; - char lifetime_chars[1024]; - - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - snprintf(lifetime_chars, sizeof(lifetime_chars), "%lu", lifetime); + if (turn_params.prometheus == 1){ + char allocation_chars[1024]; + char lifetime_chars[1024]; + + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + snprintf(lifetime_chars, sizeof(lifetime_chars), "%lu", lifetime); - prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, lifetime_chars }); + prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, lifetime_chars }); + } } void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_sub(turn_status, 1, (const char *[]) { realm , user, allocation_chars, (char *)"new", (char *)"600" }); - prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, NULL }); + if (turn_params.prometheus == 0){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + prom_gauge_sub(turn_status, 1, (const char *[]) { realm , user, allocation_chars, (char *)"new", (char *)"600" }); + prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, NULL }); + } } void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + if (turn_params.prometheus == 1){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - if (peer){ - prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); - } else { - prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + if (peer){ + prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } else { + prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } } } void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + if (turn_params.prometheus == 1){ + char allocation_chars[1024]; + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - if (peer){ - prom_gauge_set(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); - } else { - prom_gauge_set(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + if (peer){ + prom_gauge_set(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } else { + prom_gauge_set(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_gauge_set(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + } } } From fdfa4b859414815fe18a9a4626e4ea158655d959 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 5 May 2020 19:32:25 +0200 Subject: [PATCH 010/128] Added no-prometheus flag on example configuration --- examples/etc/turnserver.conf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index e9174077..8db25e42 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -178,6 +178,18 @@ # #no-auth +# Disable prometheus exporter +# By default the turnserver will expose an endpoint with stats on a prometheus format +# this endpoint is on a different port to conflict with other configurations. +# +# You can simply run the turnserver and access the port 9121 and path /metrics +# +# For mor info on the prometheus exporter and metrics +# https://prometheus.io/docs/introduction/overview/ +# https://prometheus.io/docs/concepts/data_model/ +# +# no-prometheus + # TURN REST API flag. # (Time Limited Long Term Credential) # Flag that sets a special authorization option that is based upon authentication secret. From 6680bf17ba0fbda790c35cd2bf8a3cf41b995448 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 5 May 2020 19:42:37 +0200 Subject: [PATCH 011/128] Added prometheus to README --- README.md | 2 ++ README.turnserver | 3 +++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index a4d8ff7d..6831ec08 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ Supported user databases (for user repository, with passwords or keys, if authen Redis can also be used for status and statistics storage and notification. +By default a [prometheus](https://prometheus.io/) exporter endpoint is enabled on port 9121 under path /metrics + Supported message integrity digest algorithms: * HMAC-SHA1, with MD5-hashed keys (as required by STUN and TURN standards) diff --git a/README.turnserver b/README.turnserver index 4f2b28d0..cec85e72 100644 --- a/README.turnserver +++ b/README.turnserver @@ -265,6 +265,9 @@ Flags: check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). + --no-prometheus Disable prometheus metrics. By default it is + enabled and listening on port 9121 unther the path /metrics + also the path / on this port can be used as a health check -h Help. From 5105dfafd36c2d06f7a4d52310a39155cb5dde6b Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 012/128] support of --acme-redirect --- src/apps/relay/http_server.c | 77 ++++++++++++++++++++++++++++++++++++ src/apps/relay/mainrelay.c | 14 ++++++- src/apps/relay/mainrelay.h | 1 + src/apps/relay/netengine.c | 1 + src/server/ns_turn_ioalib.h | 1 + src/server/ns_turn_server.c | 17 +++++--- src/server/ns_turn_server.h | 4 ++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2ac08fcf..56b4c8af 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -109,7 +109,7 @@ NULL, PTHREAD_MUTEX_INITIALIZER, //////////////// Common params //////////////////// TURN_VERBOSE_NONE,0,0,0,0, -"/var/run/turnserver.pid", +"/var/run/turnserver.pid","", DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,0,1, 0,0,0,0,0, "", @@ -615,6 +615,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" +" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" @@ -793,7 +795,8 @@ enum EXTRA_OPTS { OAUTH_OPT, NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, - SECRET_KEY_OPT + SECRET_KEY_OPT, + ACME_REDIRECT_OPT }; struct myoption { @@ -922,6 +925,7 @@ static const struct myoption long_options[] = { { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT }, { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, + { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1560,6 +1564,9 @@ static void set_option(int c, char *value) case PIDFILE_OPT: STRCPY(turn_params.pidfile,value); break; + case ACME_REDIRECT_OPT: + STRCPY(turn_params.acme_redirect,value); + break; case 'C': if(value && *value) { turn_params.rest_api_separator=*value; @@ -2238,6 +2245,9 @@ int main(int argc, char **argv) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); + if(turn_params.acme_redirect[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n",turn_params.acme_redirect); + } if(turn_params.oauth && turn_params.oauth_server_name[0]) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 4b584f74..75ba63b8 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -219,6 +219,7 @@ typedef struct _turn_params_ { int do_not_use_config_file; char pidfile[1025]; + char acme_redirect[1025]; //////////////// Listener server ///////////////// diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index ca88056e..20f558cd 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1667,6 +1667,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int allocate_bps, turn_params.oauth, turn_params.oauth_server_name, + turn_params.acme_redirect, turn_params.keep_address_family); if(to_set_rfc5780) { diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 6737711d..3a25b03e 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 38a15134..3d3eaa74 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,14 +4624,19 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { + char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); + size_t l = ioa_network_buffer_get_size(in_buffer->nbh); + if(is_http(str, l)) { const char *proto = "HTTP"; - ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0; - if (*server->web_admin_listen_on_workers) { + str[l] = 0; + if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + ss->to_be_closed = 1; + return 0; + } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4644,7 +4649,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); } handle_http_echo(ss->client_socket); } @@ -4915,6 +4920,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family) { if (!server) @@ -4944,6 +4950,7 @@ void init_turn_server(turn_turnserver* server, server->oauth_server_name = oauth_server_name; if(mobility) server->mobile_connections_map = ur_map_create(); + server->acme_redirect = acme_redirect; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id); diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 924a507a..0df99716 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -171,6 +171,9 @@ struct _turn_turnserver { int oauth; const char* oauth_server_name; + /* ACME redirect URL */ + const char* acme_redirect; + /* Keep Address Family */ int keep_address_family; }; @@ -218,6 +221,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 7e2c98bc1f28f12be9e47834da3a21d41da926f7 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 013/128] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ src/apps/relay/mainrelay.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index df298c54..e6a377e1 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -770,6 +770,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 56b4c8af..854c080d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -615,7 +615,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" " Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" From 798349fb5bcb781cc47471433210ce8aa5737473 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Fri, 5 Jun 2020 11:29:22 +0200 Subject: [PATCH 014/128] Change gauge to counters metrics --- src/apps/relay/prom_server.c | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 6c79db5e..368e3e7a 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -12,28 +12,28 @@ int start_prometheus_server(void){ turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); // Create traffic gauge metrics - turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_sentb", "Represents sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); // Create traffic for peers gauge metrics - turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_traffic_peer_sentb", "Represents peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); // Create total traffic gauge metrics - turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvp", "Represents total received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_rcvb", "Represents total received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentp", "Represents total sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_sentb", "Represents total sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvp", "Represents total received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvb", "Represents total received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentp", "Represents total sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentb", "Represents total sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); // Create tota traffic for peers gauge metrics - turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvp", "Represents total peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_rcvb", "Represents total peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_sentp", "Represents total peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_gauge_new("turn_total_traffic_peer_sentb", "Represents total peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvp", "Represents total peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvb", "Represents total peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentp", "Represents total peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); + turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentb", "Represents total peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); promhttp_set_active_collector_registry(NULL); @@ -72,15 +72,15 @@ void prom_set_traffic(const char* realm, const char* user, unsigned long long al snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); if (peer){ - prom_gauge_set(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); } else { - prom_gauge_set(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); } } } @@ -91,15 +91,15 @@ void prom_set_total_traffic(const char* realm, const char* user, unsigned long l snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); if (peer){ - prom_gauge_set(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); } else { - prom_gauge_set(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_gauge_set(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); } } } From 93a8c8aa782e2862054207b472401fd8bae411bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 2 Jul 2020 12:45:16 +0200 Subject: [PATCH 015/128] Fix null pointer dereferenceThanks to Thomas Moeller for the report! --- ChangeLog | 4 ++++ src/apps/relay/ns_ioalib_engine_impl.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 218d6f46..5307220a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +24/06/2020 Oleg Moskalenko Mihály Mészáros +Version 4.5.2 'dan Eider': + - Fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) + 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': - merge PR #575: (by osterik) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 22cc640a..f7f72b51 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -293,8 +293,9 @@ static stun_buffer_list_elem *new_blist_elem(ioa_engine_handle e) if(!ret) { ret = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); - ret->next = NULL; - if (!ret) { + if (ret) { + ret->next = NULL; + } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate memory for STUN buffer!\n", __FUNCTION__); } } From 2acb952670af2e23106b32487382f083753eead1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 7 Jul 2020 20:29:49 +0200 Subject: [PATCH 016/128] tidy after PR #517 --- ChangeLog | 5 +++-- README.turnserver | 2 +- configure | 4 ++-- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 10 +++++++++- man/man1/turnutils.1 | 2 +- src/apps/relay/prom_server.c | 4 ++-- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5307220a..1ac72709 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,8 @@ 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.2 'dan Eider': - - Fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - + - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) + - merge PR #517 (by wolmi) + * add prometheus metrics 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': - merge PR #575: (by osterik) diff --git a/README.turnserver b/README.turnserver index d45930ca..b2064d28 100644 --- a/README.turnserver +++ b/README.turnserver @@ -267,7 +267,7 @@ Flags: initially used by the session). --no-prometheus Disable prometheus metrics. By default it is enabled and listening on port 9121 unther the path /metrics - also the path / on this port can be used as a health check + also the path / on this port can be used as a health check -h Help. diff --git a/configure b/configure index c816ee6c..d11f3717 100755 --- a/configure +++ b/configure @@ -1078,7 +1078,7 @@ if [ -z "${TURN_NO_PROMETHEUS}" ] ; then else ${ECHO_CMD} "ERROR: Libpromhttp development libraries are not installed properly in required location." ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} "See the INSTALL file." OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi else @@ -1087,7 +1087,7 @@ if [ -z "${TURN_NO_PROMETHEUS}" ] ; then ${ECHO_CMD} "See the INSTALL file." OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi - + else OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 7432c99c..c301131e 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "29 April 2020" "" "" +.TH TURN 1 "08 July 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index df298c54..33146643 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "29 April 2020" "" "" +.TH TURN 1 "08 July 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -396,6 +396,14 @@ The flag that sets the origin consistency check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). +.RS +.TP +.B +\fB\-\-no\-prometheus\fP +Disable prometheus metrics. By default it is +enabled and listening on port 9121 unther the path /metrics +also the path / on this port can be used as a health check +.RE .TP .B \fB\-h\fP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 01dd4f86..6b4930d4 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "29 April 2020" "" "" +.TH TURN 1 "08 July 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 368e3e7a..ec395125 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -36,7 +36,7 @@ int start_prometheus_server(void){ turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentb", "Represents total peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); promhttp_set_active_collector_registry(NULL); - + struct MHD_Daemon *daemon = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY, DEFAULT_PROM_SERVER_PORT, NULL, NULL); if (daemon == NULL) { @@ -49,7 +49,7 @@ void prom_set_status(const char* realm, const char* user, unsigned long long all if (turn_params.prometheus == 1){ char allocation_chars[1024]; char lifetime_chars[1024]; - + snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); snprintf(lifetime_chars, sizeof(lifetime_chars), "%lu", lifetime); From 2f9ac538f591eb168aa22e7fde9810fae0664c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 8 Jul 2020 10:00:53 +0200 Subject: [PATCH 017/128] Add ifdef around default value --- src/apps/relay/mainrelay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 54d3f060..245e932f 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -155,7 +155,9 @@ TURN_CREDENTIALS_NONE, /* ct */ 0, /* bps_capacity_allocated */ 0, /* total_quota */ 0, /* user_quota */ +#if !defined(TURN_NO_PROMETHEUS) 1, /* prometheus enabled by default */ +#endif ///////////// Users DB ////////////// { (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} }, ///////////// CPUs ////////////////// From dca83e9b9f14dfb3abff9c02c5a7c59133e963f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 8 Jul 2020 10:03:04 +0200 Subject: [PATCH 018/128] Make error more visible and separated with newlines --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index d11f3717..f5289718 100755 --- a/configure +++ b/configure @@ -1082,9 +1082,9 @@ if [ -z "${TURN_NO_PROMETHEUS}" ] ; then OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi else - ${ECHO_CMD} "ERROR: Libprom development libraries are not installed properly in required location." + ${ECHO_CMD} "\nERROR: Libprom development libraries are not installed properly in required location." ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} "See the INSTALL file.\n" OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi From 5b6739a793f40749b3354c372a95f4577dc05f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sun, 19 Jul 2020 10:48:44 +0200 Subject: [PATCH 019/128] Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL Fix #552 --- src/apps/common/ns_turn_openssl.h | 5 ----- src/apps/relay/ns_ioalib_engine_impl.c | 4 ++-- src/client/ns_turn_msg.c | 4 ++-- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/apps/common/ns_turn_openssl.h b/src/apps/common/ns_turn_openssl.h index eb33c143..8272f99c 100644 --- a/src/apps/common/ns_turn_openssl.h +++ b/src/apps/common/ns_turn_openssl.h @@ -42,9 +42,4 @@ #include #include -#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L) -#undef OPENSSL_VERSION_NUMBER -#define OPENSSL_VERSION_NUMBER 0x1000107FL -#endif - #endif //__NST_OPENSSL_LIB__ diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 22cc640a..b5721f47 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -1828,7 +1828,7 @@ int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int ve BIO* rbio = BIO_new_mem_buf(buffer, old_buffer_len); BIO_set_mem_eof_return(rbio, -1); -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER ssl->rbio = rbio; #else SSL_set0_rbio(ssl,rbio); @@ -1923,7 +1923,7 @@ int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int ve if(ret>0) { ioa_network_buffer_add_offset_size(nbh, (uint16_t)buf_size, 0, (size_t)ret); } -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER ssl->rbio = NULL; BIO_free(rbio); #else diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index e9386eb0..d0c8d889 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -244,7 +244,7 @@ int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, c unsigned int keylen = 0; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); -#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW +#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && !defined(LIBRESSL_VERSION_NUMBER) if (FIPS_mode()) { EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } @@ -256,7 +256,7 @@ int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, c #else unsigned int keylen = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); -#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW +#if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER) if (FIPS_mode()) { EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } From 8f7938a374ef22e55cd88e99aa60165295f99fef Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 28 Jul 2020 10:50:58 +0200 Subject: [PATCH 020/128] Fix peer and realm on delete --- src/apps/relay/ns_ioalib_engine_impl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 34f01fdc..4ba8bb35 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3672,15 +3672,15 @@ void turn_report_allocation_delete(void *a) prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } else { // Set prometheus del metric and update status prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } } #endif From a2200f5c5cb57a916fb77a9b9f7a0d71a1fcf34c Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 28 Jul 2020 11:04:06 +0200 Subject: [PATCH 021/128] Change prometheus exporter port to 9641 In order to avoid conflicts using the same port userd by redis exporter looking at the [prometheus wiki](https://github.com/prometheus/prometheus/wiki/Default-port-allocations) the port 9641 is the first FREE for allocation --- README.md | 2 +- examples/etc/turnserver.conf | 2 +- src/apps/relay/mainrelay.c | 2 +- src/apps/relay/prom_server.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6831ec08..b13c8d32 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Supported user databases (for user repository, with passwords or keys, if authen Redis can also be used for status and statistics storage and notification. -By default a [prometheus](https://prometheus.io/) exporter endpoint is enabled on port 9121 under path /metrics +By default a [prometheus](https://prometheus.io/) exporter endpoint is enabled on port 9641 under path /metrics Supported message integrity digest algorithms: diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 743058eb..adf49422 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -190,7 +190,7 @@ # By default the turnserver will expose an endpoint with stats on a prometheus format # this endpoint is on a different port to conflict with other configurations. # -# You can simply run the turnserver and access the port 9121 and path /metrics +# You can simply run the turnserver and access the port 9641 and path /metrics # # For mor info on the prometheus exporter and metrics # https://prometheus.io/docs/introduction/overview/ diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 54d3f060..02ef9fe6 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -535,7 +535,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " The connection string has the same parameters as redis-userdb connection string.\n" #endif #if !defined(TURN_NO_PROMETHEUS) -" --no-prometheus Disable prometheus metrics. By default it is enabled and listening on port 9121 unther the path /metrics\n" +" --no-prometheus Disable prometheus metrics. By default it is enabled and listening on port 9641 unther the path /metrics\n" " also the path / on this port can be used as a health check\n" #endif " --use-auth-secret TURN REST API flag.\n" diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index fcaa9759..0211038d 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -14,7 +14,7 @@ #include #include -#define DEFAULT_PROM_SERVER_PORT (9121) +#define DEFAULT_PROM_SERVER_PORT (9641) prom_gauge_t *turn_status; From c9cd99e4f58a5b3d892de3c41dddb7a7c59746e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 3 Aug 2020 10:25:56 +0200 Subject: [PATCH 022/128] Disable prometheus by default --- README.md | 2 +- configure | 16 +++++--- examples/etc/turnserver.conf | 8 ++-- man/man1/turnadmin.1 | 32 +++++++-------- man/man1/turnserver.1 | 79 ++++++++++++++++++------------------ man/man1/turnutils.1 | 61 +++++++++++++--------------- src/apps/relay/mainrelay.c | 12 +++--- 7 files changed, 105 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index 6831ec08..ab5c4bfe 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Supported user databases (for user repository, with passwords or keys, if authen Redis can also be used for status and statistics storage and notification. -By default a [prometheus](https://prometheus.io/) exporter endpoint is enabled on port 9121 under path /metrics +By default a [prometheus](https://prometheus.io/) exporter endpoint is disabled, if it is enabeled it will listen on port 9121 under path /metrics Supported message integrity digest algorithms: diff --git a/configure b/configure index f5289718..38227c6e 100755 --- a/configure +++ b/configure @@ -1070,21 +1070,27 @@ if [ -z "${TURN_NO_PROMETHEUS}" ] ; then if ! [ ${ER} -eq 0 ] ; then ${ECHO_CMD} "Microhttpd lib found." else - ${ECHO_CMD} "ERROR: microhttpd development libraries are not installed properly in required location." + ${ECHO_CMD} + ${ECHO_CMD} "Warning: microhttpd development libraries are not installed properly in required location." ${ECHO_CMD} "Prometheus support will be disabled." ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi else - ${ECHO_CMD} "ERROR: Libpromhttp development libraries are not installed properly in required location." + ${ECHO_CMD} + ${ECHO_CMD} "Warning: Libpromhttp development libraries are not installed properly in required location." ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi else - ${ECHO_CMD} "\nERROR: Libprom development libraries are not installed properly in required location." + ${ECHO_CMD} + ${ECHO_CMD} "Warning: Libprom development libraries are not installed properly in required location." ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file.\n" + ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 743058eb..f8ee3a45 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -186,9 +186,9 @@ # #no-auth -# Disable prometheus exporter -# By default the turnserver will expose an endpoint with stats on a prometheus format -# this endpoint is on a different port to conflict with other configurations. +# Enable prometheus exporter +# If enabled the turnserver will expose an endpoint with stats on a prometheus format +# this endpoint is listening on a different port to not conflict with other configurations. # # You can simply run the turnserver and access the port 9121 and path /metrics # @@ -196,7 +196,7 @@ # https://prometheus.io/docs/introduction/overview/ # https://prometheus.io/docs/concepts/data_model/ # -# no-prometheus +#prometheus # TURN REST API flag. # (Time Limited Long Term Credential) diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index c301131e..e24dc1e9 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 July 2020" "" "" +.TH TURN 1 "28 July 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage @@ -48,8 +48,8 @@ is equivalent to: .fi You have always the use the \fB\-r\fP option with commands for long term credentials \- because data for multiple realms can be stored in the same database. -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnadmin \fP\- a TURN relay administration tool. @@ -288,8 +288,8 @@ $ \fIturnadmin\fP \fB\-\-file\-key\-path\fP \fB\-v\fP Help: .PP $ \fIturnadmin\fP \fB\-h\fP -.PP -======================================= +.SH ======================================= + .SS DOCS After installation, run the \fIcommand\fP: @@ -301,8 +301,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnadmin\fP .PP to see the man page. -.PP -===================================== +.SH ===================================== + .SS FILES /etc/turnserver.conf @@ -314,8 +314,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -===================================== +.SH ===================================== + .SS DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -323,14 +323,13 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -====================================== +.SH ====================================== + .SS SEE ALSO \fIturnserver\fP, \fIturnutils\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -344,9 +343,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.RE -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 33146643..9b97159b 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 July 2020" "" "" +.TH TURN 1 "28 July 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -78,7 +78,8 @@ is equivalent to: .fam T .fi -===================================== +.SH ===================================== + .SS NAME \fB \fBturnserver \fP\- a TURN relay server implementation. @@ -839,15 +840,15 @@ By default it is disabled for security resons! .B \fB\-\-ne\fP=[1|2|3] Set network engine type for the process (for internal purposes). -.PP -================================== +.SH ================================== + .SH LOAD BALANCE AND PERFORMANCE TUNING This topic is covered in the wiki page: .PP https://github.com/coturn/coturn/wiki/turn_performance_and_load_balance -.PP -=================================== +.SH =================================== + .SH WEBRTC USAGE This is a set of notes for the WebRTC users: @@ -884,8 +885,8 @@ Usually WebRTC uses fingerprinting (\fB\-f\fP). .IP 5) 4 \fB\-\-min\-port\fP and \fB\-\-max\-port\fP may be needed if you want to limit the relay endpoints ports number range. -.PP -=================================== +.SH =================================== + .SH TURN REST API In WebRTC, the browser obtains the TURN connection information from the web @@ -1023,8 +1024,8 @@ examples/scripts/restapi/shared_secret_maintainer.pl . .PP A very important thing is that the nonce must be totally random and it must be different for different clients and different sessions. -.PP -=================================== +.SH =================================== + .SH DATABASES For the user database, the \fIturnserver\fP has the following \fIoptions\fP: @@ -1087,8 +1088,8 @@ it will set the users for you (see the \fIturnadmin\fP manuals). If you are usin \fIturnserver\fP or \fIturnadmin\fP will initialize the empty database, for you, when started. The TURN server installation process creates an empty initialized SQLite database in the default location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system). -.PP -================================= +.SH ================================= + .SH ALPN The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when @@ -1097,16 +1098,16 @@ ClientHello message that contains one or both of those ALPNs, then the server chooses the first stun.* label and sends it back (in the ServerHello) in the ALPN extension field. If no stun.* label is found, then the server does not include the ALPN information into the ServerHello. -.PP -================================= +.SH ================================= + .SH LIBRARIES In the lib/ sub\-directory the build process will create TURN client messaging library. In the include/ sub\-directory, the necessary include files will be placed. The C++ wrapper for the messaging functionality is located in TurnMsgLib.h header. An example of C++ code can be found in stunclient.c file. -.PP -================================= +.SH ================================= + .SH DOCS After installation, run the command: @@ -1121,8 +1122,8 @@ to see the man page. .PP In the docs/html subdirectory of the original archive tree, you will find the client library reference. After the installation, it will be placed in PREFIX/share/doc/\fIturnserver\fP/html. -.PP -================================= +.SH ================================= + .SH LOGS When the \fBTURN Server\fP starts, it makes efforts to create a log file turn_.log @@ -1145,8 +1146,8 @@ log messages are sent only to the standard output of the process. .PP This behavior can be controlled by \fB\-\-log\-file\fP, \fB\-\-syslog\fP and \fB\-\-no\-stdout\-log\fP \fIoptions\fP. -.PP -================================= +.SH ================================= + .SH HTTPS MANAGEMENT INTERFACE The \fIturnserver\fP process provides an HTTPS Web access as statistics and basic @@ -1159,8 +1160,8 @@ populated with the admin user \fBaccount\fP(s). An admin user can be a superuser (if not assigned to a particular realm) or a restricted user (if assigned to a realm). The restricted admin users can perform only limited actions, within their corresponding realms. -.PP -================================= +.SH ================================= + .SH TELNET CLI The \fIturnserver\fP process provides a telnet CLI access as statistics and basic management @@ -1168,8 +1169,8 @@ interface. By default, the \fIturnserver\fP starts a telnet CLI listener on IP 1 port 5766. That can be changed by the command\-cline \fIoptions\fP of the \fIturnserver\fP process (see \fB\-\-cli\-ip\fP and \fB\-\-cli\-port\fP \fIoptions\fP). The full list of telnet CLI commands is provided in "help" command output in the telnet CLI. -.PP -================================= +.SH ================================= + .SH CLUSTERS \fBTURN Server\fP can be a part of the cluster installation. But, to support the "even port" functionality @@ -1178,8 +1179,8 @@ in "help" command output in the telnet CLI. the RTP and RTCP relaying endpoints must be allocated on the same relay IP. It would be possible to design a scheme with the application\-level requests forwarding (and we may do that later) but it would affect the performance. -.PP -================================= +.SH ================================= + .SH FILES /etc/turnserver.conf @@ -1191,8 +1192,8 @@ it would affect the performance. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -================================= +.SH ================================= + .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -1200,16 +1201,15 @@ it would affect the performance. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -================================= +.SH ================================= + .SH STANDARDS obsolete STUN RFC 3489 .PP new STUN RFC 5389 -.PP -TURN RFC 5766 -.PP +.SH TURN RFC 5766 + TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -1217,14 +1217,13 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.PP -================================= +.SH ================================= + .SH SEE ALSO \fIturnadmin\fP, \fIturnutils\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -1238,8 +1237,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 6b4930d4..dcc4dbc6 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 July 2020" "" "" +.TH TURN 1 "28 July 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -63,8 +63,8 @@ script in examples/scripts/oauth.sh. .RE .PP -.RS -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only. @@ -276,8 +276,8 @@ the ORIGIN STUN attribute value. Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. .PP See the examples in the "examples/scripts" directory. -.PP -====================================== +.SH ====================================== + .SS NAME \fB \fBturnutils_peer \fP\- a simple UDP\-only echo backend server. @@ -314,8 +314,8 @@ If no listener \fBaddress\fP(es) defined, then it listens on all IPv4 and IPv6 a .B \fB\-v\fP Verbose -.PP -======================================== +.SH ======================================== + .SS NAME \fB \fBturnutils_stunclient \fP\- a basic STUN client. @@ -354,8 +354,8 @@ and if it finds that the STUN server supports RFC 5780 requests with different parameters, to demonstrate the NAT discovery capabilities. .PP This utility does not support the "old" "classic" STUN protocol (RFC 3489). -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_rfc5769check \fP\- a utility that tests the correctness of STUN protocol implementation. @@ -380,8 +380,8 @@ check procedure, it is not copied to the installation destination. Usage: .PP $ \fIturnutils_rfc5769check\fP -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_natdiscovery \fP\- a utility that discovers NAT mapping and filtering @@ -462,8 +462,8 @@ Used by mapping lifetime behavior discovery Usage: .PP $ \fIturnutils_natdiscovery\fP \fB\-m\fP \fB\-f\fP stun.example.com -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_oauth \fP\- a utility that helps OAuth access_token generation/encryption and validation/decyption @@ -568,8 +568,8 @@ stun client hmac algorithm Usage: .PP $ \fIturnutils_natdiscovery\fP -.PP -=================================== +.SH =================================== + .SH DOCS After installation, run the command: @@ -581,8 +581,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnutils\fP .PP to see the man page. -.PP -===================================== +.SH ===================================== + .SH FILES /etc/turnserver.conf @@ -594,8 +594,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -================================= +.SH ================================= + .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -603,14 +603,13 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -=================================== +.SH =================================== + .SH STANDARDS new STUN RFC 5389 -.PP -TURN RFC 5766 -.PP +.SH TURN RFC 5766 + TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -618,14 +617,13 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.PP -==================================== +.SH ==================================== + .SH SEE ALSO \fIturnserver\fP, \fIturnadmin\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -639,9 +637,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.RE -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 245e932f..fa6de44c 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -156,7 +156,7 @@ TURN_CREDENTIALS_NONE, /* ct */ 0, /* total_quota */ 0, /* user_quota */ #if !defined(TURN_NO_PROMETHEUS) -1, /* prometheus enabled by default */ +0, /* prometheus disabled by default */ #endif ///////////// Users DB ////////////// { (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} }, @@ -537,7 +537,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " The connection string has the same parameters as redis-userdb connection string.\n" #endif #if !defined(TURN_NO_PROMETHEUS) -" --no-prometheus Disable prometheus metrics. By default it is enabled and listening on port 9121 unther the path /metrics\n" +" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9121 unther the path /metrics\n" " also the path / on this port can be used as a health check\n" #endif " --use-auth-secret TURN REST API flag.\n" @@ -750,7 +750,7 @@ enum EXTRA_OPTS { MAX_ALLOCATE_LIFETIME_OPT, CHANNEL_LIFETIME_OPT, PERMISSION_LIFETIME_OPT, - NO_PROMETHEUS_OPT, + PROMETHEUS_OPT, AUTH_SECRET_OPT, NO_AUTH_PINGS_OPT, NO_DYNAMIC_IP_LIST_OPT, @@ -858,7 +858,7 @@ static const struct myoption long_options[] = { { "redis-statsdb", required_argument, NULL, 'O' }, #endif #if !defined(TURN_NO_PROMETHEUS) - { "no-prometheus", optional_argument, NULL, NO_PROMETHEUS_OPT }, + { "prometheus", optional_argument, NULL, PROMETHEUS_OPT }, #endif { "use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT }, { "static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT }, @@ -1461,8 +1461,8 @@ static void set_option(int c, char *value) break; #endif #if !defined(TURN_NO_PROMETHEUS) - case NO_PROMETHEUS_OPT: - turn_params.prometheus = 0; + case PROMETHEUS_OPT: + turn_params.prometheus = 1; break; #endif case AUTH_SECRET_OPT: From c65ce15fdeaee71c6a280c1130a20b829600d111 Mon Sep 17 00:00:00 2001 From: Miquel Ortega Date: Tue, 28 Jul 2020 10:50:58 +0200 Subject: [PATCH 023/128] Fix peer and realm on delete --- src/apps/relay/ns_ioalib_engine_impl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index f4f521b8..9e801918 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3677,15 +3677,15 @@ void turn_report_allocation_delete(void *a) prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), false); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } else { // Set prometheus del metric and update status prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); + prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } } #endif From 388d939ed9851fbc53b316fc0143de97e14707ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 3 Aug 2020 14:24:20 +0200 Subject: [PATCH 024/128] Change prometheus exporter port to 9641 --- README.md | 2 +- README.turnserver | 2 +- examples/etc/turnserver.conf | 2 +- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 4 ++-- man/man1/turnutils.1 | 2 +- src/apps/relay/mainrelay.c | 2 +- src/apps/relay/ns_ioalib_engine_impl.c | 2 +- src/apps/relay/prom_server.h | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ab5c4bfe..448df3f3 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Supported user databases (for user repository, with passwords or keys, if authen Redis can also be used for status and statistics storage and notification. -By default a [prometheus](https://prometheus.io/) exporter endpoint is disabled, if it is enabeled it will listen on port 9121 under path /metrics +By default a [prometheus](https://prometheus.io/) exporter endpoint is disabled, if it is enabeled it will listen on port 9641 under path /metrics Supported message integrity digest algorithms: diff --git a/README.turnserver b/README.turnserver index b2064d28..320021e9 100644 --- a/README.turnserver +++ b/README.turnserver @@ -266,7 +266,7 @@ Flags: main ORIGIN attribute value (if the ORIGIN was initially used by the session). --no-prometheus Disable prometheus metrics. By default it is - enabled and listening on port 9121 unther the path /metrics + enabled and listening on port 9641 unther the path /metrics also the path / on this port can be used as a health check -h Help. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index f8ee3a45..515ed131 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -190,7 +190,7 @@ # If enabled the turnserver will expose an endpoint with stats on a prometheus format # this endpoint is listening on a different port to not conflict with other configurations. # -# You can simply run the turnserver and access the port 9121 and path /metrics +# You can simply run the turnserver and access the port 9641 and path /metrics # # For mor info on the prometheus exporter and metrics # https://prometheus.io/docs/introduction/overview/ diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index e24dc1e9..5ef28f7a 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "28 July 2020" "" "" +.TH TURN 1 "03 August 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 9b97159b..5b19c10f 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "28 July 2020" "" "" +.TH TURN 1 "03 August 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -402,7 +402,7 @@ initially used by the session). .B \fB\-\-no\-prometheus\fP Disable prometheus metrics. By default it is -enabled and listening on port 9121 unther the path /metrics +enabled and listening on port 9641 unther the path /metrics also the path / on this port can be used as a health check .RE .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index dcc4dbc6..d379b923 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "28 July 2020" "" "" +.TH TURN 1 "03 August 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index fa6de44c..c142599d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -537,7 +537,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " The connection string has the same parameters as redis-userdb connection string.\n" #endif #if !defined(TURN_NO_PROMETHEUS) -" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9121 unther the path /metrics\n" +" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9641 unther the path /metrics\n" " also the path / on this port can be used as a health check\n" #endif " --use-auth-secret TURN REST API flag.\n" diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 9e801918..ba1e387f 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -299,7 +299,7 @@ static stun_buffer_list_elem *new_blist_elem(ioa_engine_handle e) ret = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); if (ret) { ret->next = NULL; - } else { + } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate memory for STUN buffer!\n", __FUNCTION__); } } diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index fcaa9759..0211038d 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -14,7 +14,7 @@ #include #include -#define DEFAULT_PROM_SERVER_PORT (9121) +#define DEFAULT_PROM_SERVER_PORT (9641) prom_gauge_t *turn_status; From 2b1d6d4293b639c02224b326d2b26e95376afbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 3 Aug 2020 14:25:57 +0200 Subject: [PATCH 025/128] Add prometheus dependency reference --- INSTALL | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/INSTALL b/INSTALL index a445f4f2..40ce9607 100644 --- a/INSTALL +++ b/INSTALL @@ -1184,3 +1184,8 @@ TLS-over-SCTP. The relay side is not changing - the relay communications will still be UDP or TCP. + +XXV. Prometheus support. + +See for source and releases for debian packages: +https://github.com/digitalocean/prometheus-client-c From 87d85f06bd50f81564ccef49df515d26f7801a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 3 Aug 2020 15:16:09 +0200 Subject: [PATCH 026/128] Add log for prometheus collector start --- src/apps/relay/mainrelay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index c142599d..0aabb3b7 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -2485,7 +2485,12 @@ int main(int argc, char **argv) drop_privileges(); #if !defined(TURN_NO_PROMETHEUS) - start_prometheus_server(); + if (start_prometheus_server()){ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCould not start Prometheus collector!\n"); + } + else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nPrometheus collector started sucessfully.\n"); + } #endif From 63c9ae60155456f7d4c10b16a7dd09f953d6e2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 4 Aug 2020 07:25:05 +0200 Subject: [PATCH 027/128] Update .travis.yml --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e0ff2778..84e024f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,8 +66,11 @@ matrix: - libhiredis-dev - os: osx osx_image: xcode11.3 -# - os: osx -# osx_image: xcode9.4 + - os: osx + osx_image: xcode11.6 + - os: osx + osx_image: xcode12 + notifications: slack: From 599a61eea6aa60c8b8e1ecaa027642f5ebe8331c Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 25 Aug 2020 21:46:15 +1000 Subject: [PATCH 028/128] Print full date and time in logs Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 04b180c5..274dc438 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -178,17 +178,12 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - if (level == TURN_LOG_LEVEL_ERROR) { - snprintf(s,sizeof(s)-100,"%lu: ERROR: ",(unsigned long)log_time()); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); - } else if(!no_stdout_log) { - snprintf(s,sizeof(s)-100,"%lu: ",(unsigned long)log_time()); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); - } + struct tm local_now = localtime(time(NULL)); + strptime(s, sizeof(s)-100, "%Y-%m-%dT%H:%M:%S", &local_now); + snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + size_t slen = strlen(s); + vsnprintf(s+slen,sizeof(s)-slen-1,format, args); + fwrite(s,strlen(s),1,stdout); #endif va_end(args); } From 762ee2348210a5481e00673e3696d0acf84a1f6d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Wed, 26 Aug 2020 21:05:08 +1000 Subject: [PATCH 029/128] Fixing a few errors - C still coming back to me Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 274dc438..dde543fd 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -178,8 +178,8 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - struct tm local_now = localtime(time(NULL)); - strptime(s, sizeof(s)-100, "%Y-%m-%dT%H:%M:%S", &local_now); + time_t now = time(NULL); + strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); size_t slen = strlen(s); vsnprintf(s+slen,sizeof(s)-slen-1,format, args); From c5b0bd0e221b2ae11345151eeae2cba2afdc6426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 27 Aug 2020 20:27:09 +0200 Subject: [PATCH 030/128] Update prometheus gcc 10 compatible --- src/apps/relay/prom_server.c | 22 ++++++++++++++++++++++ src/apps/relay/prom_server.h | 34 +++++++++++++++++----------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index ec395125..8bd82fa8 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -3,6 +3,28 @@ #include "mainrelay.h" #include "prom_server.h" +prom_gauge_t *turn_status; + +prom_gauge_t *turn_traffic_rcvp; +prom_gauge_t *turn_traffic_rcvb; +prom_gauge_t *turn_traffic_sentp; +prom_gauge_t *turn_traffic_sentb; + +prom_gauge_t *turn_total_traffic_rcvp; +prom_gauge_t *turn_total_traffic_rcvb; +prom_gauge_t *turn_total_traffic_sentp; +prom_gauge_t *turn_total_traffic_sentb; + +prom_gauge_t *turn_traffic_peer_rcvp; +prom_gauge_t *turn_traffic_peer_rcvb; +prom_gauge_t *turn_traffic_peer_sentp; +prom_gauge_t *turn_traffic_peer_sentb; + +prom_gauge_t *turn_total_traffic_peer_rcvp; +prom_gauge_t *turn_total_traffic_peer_rcvb; +prom_gauge_t *turn_total_traffic_peer_sentp; +prom_gauge_t *turn_total_traffic_peer_sentb; + int start_prometheus_server(void){ if (turn_params.prometheus == 0){ return 0; diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index 0211038d..cade4849 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -16,27 +16,27 @@ #define DEFAULT_PROM_SERVER_PORT (9641) -prom_gauge_t *turn_status; +extern prom_gauge_t *turn_status; -prom_gauge_t *turn_traffic_rcvp; -prom_gauge_t *turn_traffic_rcvb; -prom_gauge_t *turn_traffic_sentp; -prom_gauge_t *turn_traffic_sentb; +extern prom_gauge_t *turn_traffic_rcvp; +extern prom_gauge_t *turn_traffic_rcvb; +extern prom_gauge_t *turn_traffic_sentp; +extern prom_gauge_t *turn_traffic_sentb; -prom_gauge_t *turn_total_traffic_rcvp; -prom_gauge_t *turn_total_traffic_rcvb; -prom_gauge_t *turn_total_traffic_sentp; -prom_gauge_t *turn_total_traffic_sentb; +extern prom_gauge_t *turn_total_traffic_rcvp; +extern prom_gauge_t *turn_total_traffic_rcvb; +extern prom_gauge_t *turn_total_traffic_sentp; +extern prom_gauge_t *turn_total_traffic_sentb; -prom_gauge_t *turn_traffic_peer_rcvp; -prom_gauge_t *turn_traffic_peer_rcvb; -prom_gauge_t *turn_traffic_peer_sentp; -prom_gauge_t *turn_traffic_peer_sentb; +extern prom_gauge_t *turn_traffic_peer_rcvp; +extern prom_gauge_t *turn_traffic_peer_rcvb; +extern prom_gauge_t *turn_traffic_peer_sentp; +extern prom_gauge_t *turn_traffic_peer_sentb; -prom_gauge_t *turn_total_traffic_peer_rcvp; -prom_gauge_t *turn_total_traffic_peer_rcvb; -prom_gauge_t *turn_total_traffic_peer_sentp; -prom_gauge_t *turn_total_traffic_peer_sentb; +extern prom_gauge_t *turn_total_traffic_peer_rcvp; +extern prom_gauge_t *turn_total_traffic_peer_rcvb; +extern prom_gauge_t *turn_total_traffic_peer_sentp; +extern prom_gauge_t *turn_total_traffic_peer_sentb; #ifdef __cplusplus extern "C" { From 16eeb53e079c973e0254d5ec97444e000c0ff591 Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Mon, 31 Aug 2020 22:34:54 +1000 Subject: [PATCH 031/128] Allow new log format to be turned on if required This provides the 'use_new_timestamp_log_format' variable in `ns_turn_utils.h`. By default it is set to 0 and the old 'seconds since daemon was started' timestamp will be emitted. However, if it is set to 1 or any 'true' number the new date and time timestamp format will be used instead. This has also resulted in a small clean-up of some of the string length handling. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 18 ++++++++++++------ src/apps/common/ns_turn_utils.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index dde543fd..ee3c8bf8 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -158,6 +158,8 @@ void set_no_stdout_log(int val) no_stdout_log = val; } +int use_new_log_timestamp_format = 0; + void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) { #if !defined(TURN_LOG_FUNC_IMPL) @@ -178,12 +180,16 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - time_t now = time(NULL); - strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); - snprintf(s + 19,sizeof(s)-100,(level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); - size_t slen = strlen(s); - vsnprintf(s+slen,sizeof(s)-slen-1,format, args); - fwrite(s,strlen(s),1,stdout); + size_t so_far = 0; + if (use_new_log_timestamp_format) { + time_t now = time(NULL); + so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + } else { + so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); + } + so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); + fwrite(s, so_far, 1, stdout); #endif va_end(args); } diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index 77ade9aa..8aabae07 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -69,6 +69,7 @@ void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); extern volatile int _log_time_value_set; extern volatile turn_time_t _log_time_value; +extern int use_new_log_timestamp_format; void rtpprintf(const char *format, ...); int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args); From 5e87c444693b39e11cabc498450dacbef30ec64a Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 18:35:01 +1000 Subject: [PATCH 032/128] Merge turn_log_func_default and vrtpprintf The function `turn_log_func_default` calls the function `vrtpprintf` to print to syslog or the log file. The latter does exactly the same string formatting as the former, so here we merge the two functions into one to do the string formatting once. This also makes sure that the log line is consistent on all outputs. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 73 +++++++++------------------------ 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index ee3c8bf8..0007a55a 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -160,41 +160,6 @@ void set_no_stdout_log(int val) int use_new_log_timestamp_format = 0; -void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) -{ -#if !defined(TURN_LOG_FUNC_IMPL) - { - va_list args; - va_start(args,format); - vrtpprintf(level, format, args); - va_end(args); - } -#endif - - { - va_list args; - va_start(args,format); -#if defined(TURN_LOG_FUNC_IMPL) - TURN_LOG_FUNC_IMPL(level,format,args); -#else -#define MAX_RTPPRINTF_BUFFER_SIZE (1024) - char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; -#undef MAX_RTPPRINTF_BUFFER_SIZE - size_t so_far = 0; - if (use_new_log_timestamp_format) { - time_t now = time(NULL); - so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); - } else { - so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); - } - so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); - so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); - fwrite(s, so_far, 1, stdout); -#endif - va_end(args); - } -} - void addr_debug_print(int verbose, const ioa_addr *addr, const char* s) { if (verbose) { @@ -513,20 +478,29 @@ static int get_syslog_level(TURN_LOG_LEVEL level) return LOG_INFO; } -int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args) +void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) { + va_list args; + va_start(args,format); +#if defined(TURN_LOG_FUNC_IMPL) + TURN_LOG_FUNC_IMPL(level,format,args); +#else /* Fix for Issue 24, raised by John Selbie: */ #define MAX_RTPPRINTF_BUFFER_SIZE (1024) char s[MAX_RTPPRINTF_BUFFER_SIZE+1]; #undef MAX_RTPPRINTF_BUFFER_SIZE - - size_t sz; - - snprintf(s, sizeof(s), "%lu: ",(unsigned long)log_time()); - sz=strlen(s); - vsnprintf(s+sz, sizeof(s)-1-sz, format, args); - s[sizeof(s)-1]=0; - + size_t so_far = 0; + if (use_new_log_timestamp_format) { + time_t now = time(NULL); + so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + } else { + so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); + } + so_far += snprintf(s + so_far, sizeof(s)-100, (level == TURN_LOG_LEVEL_ERROR) ? ": ERROR: " : ": "); + so_far += vsnprintf(s + so_far,sizeof(s) - (so_far+1), format, args); + /* always write to stdout */ + fwrite(s, so_far, 1, stdout); + /* write to syslog or to log file */ if(to_syslog) { syslog(get_syslog_level(level),"%s",s); } else { @@ -539,16 +513,9 @@ int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args) } log_unlock(); } +#endif + va_end(args); - return 0; -} - -void rtpprintf(const char *format, ...) -{ - va_list args; - va_start (args, format); - vrtpprintf(TURN_LOG_LEVEL_INFO, format, args); - va_end (args); } ///////////// ORIGIN /////////////////// From f59e9f8ad429da71ec2147915ea652e6b9891b9d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 18:43:56 +1000 Subject: [PATCH 033/128] Allow the log timestamp format to be set This allows the timestamp format in log output to be set by a function. Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 10 +++++++++- src/apps/common/ns_turn_utils.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 0007a55a..1f5570d9 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -158,6 +158,14 @@ void set_no_stdout_log(int val) no_stdout_log = val; } +#define MAX_LOG_TIMESTAMP_FORMAT_LEN 48 +static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%Y-%m-%dT%H:%M:%S"; + +void set_turn_log_timestamp_format(char* new_format) +{ + strncpy(turn_log_timestamp_format, new_format, MAX_LOG_TIMESTAMP_FORMAT_LEN-1); +} + int use_new_log_timestamp_format = 0; void addr_debug_print(int verbose, const ioa_addr *addr, const char* s) @@ -492,7 +500,7 @@ void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...) size_t so_far = 0; if (use_new_log_timestamp_format) { time_t now = time(NULL); - so_far += strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S", localtime(&now)); + so_far += strftime(s, sizeof(s), turn_log_timestamp_format, localtime(&now)); } else { so_far += snprintf(s, sizeof(s), "%lu: ", (unsigned long)log_time()); } diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index 8aabae07..d9e9488d 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -61,6 +61,8 @@ void set_no_stdout_log(int val); void set_log_to_syslog(int val); void set_simple_log(int val); +void set_turn_log_timestamp_format(char* new_format); + void turn_log_func_default(TURN_LOG_LEVEL level, const char* format, ...); void addr_debug_print(int verbose, const ioa_addr *addr, const char* s); From ed88f1605ae6deada2045842a66aafae08fd1578 Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 20:57:54 +1000 Subject: [PATCH 034/128] Neater ISO-8601 timestamp format string Signed-off-by: Paul Wayper --- src/apps/common/ns_turn_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/common/ns_turn_utils.c b/src/apps/common/ns_turn_utils.c index 1f5570d9..7022edae 100644 --- a/src/apps/common/ns_turn_utils.c +++ b/src/apps/common/ns_turn_utils.c @@ -159,7 +159,7 @@ void set_no_stdout_log(int val) } #define MAX_LOG_TIMESTAMP_FORMAT_LEN 48 -static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%Y-%m-%dT%H:%M:%S"; +static char turn_log_timestamp_format[MAX_LOG_TIMESTAMP_FORMAT_LEN] = "%FT%T%z"; void set_turn_log_timestamp_format(char* new_format) { From c315c288bd2f52155b27598803933aa89238218d Mon Sep 17 00:00:00 2001 From: Paul Wayper Date: Tue, 1 Sep 2020 21:01:28 +1000 Subject: [PATCH 035/128] Add options for new log timestamp and setting timestamp format This adds the `--new-log-timestamp` and `--new-timestamp-format ` options to the `turnserver` program. Setting `--new-log-timestamp` on the command line, or `new-log-timestamp` in the configuration file, will cause all logs to be written with an ISI-8601 timestamp (`YYYY-MM-DDTHH:MM:SSZZZZZ` with `T` being literal and `ZZZZZ` being `+` or `-` and the hour and minute offset from GMT for the local timezone). This replaces the 'number of seconds since daemon was started' format. Setting the `--new-timestamp-format ` option with a given format, or `new-log-timestamp=` in the configuration file, will use this instead of the standard timestamp format. Timestamp format strings up to 48 characters can be accommodated; more will be truncated. This will only be used when the `--new-log-timestamp` option (above) is set. Thanks to Hendrik Huels for the idea and some of the code for setting the log timestamp string. Signed-off-by: Paul Wayper --- src/apps/relay/mainrelay.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 0aabb3b7..d0134f28 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -603,6 +603,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --simple-log This flag means that no log file rollover will be used, and the log file\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" +" --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" +" --new-timestamp_format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -761,6 +763,8 @@ enum EXTRA_OPTS { NO_STDOUT_LOG_OPT, SYSLOG_OPT, SIMPLE_LOG_OPT, + NEW_LOG_TIMESTAMP_OPT, + NEW_TIMESTAMP_FORMAT_OPT, AUX_SERVER_OPT, UDP_SELF_BALANCE_OPT, ALTERNATE_SERVER_OPT, @@ -899,6 +903,8 @@ static const struct myoption long_options[] = { { "no-stdout-log", optional_argument, NULL, NO_STDOUT_LOG_OPT }, { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, + { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, + { "new-timestamp_format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, @@ -1717,6 +1723,10 @@ static void read_config_file(int argc, char **argv, int pass) set_log_to_syslog(get_bool_value(value)); } else if((pass==0) && (c==SIMPLE_LOG_OPT)) { set_simple_log(get_bool_value(value)); + } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_OPT)) { + use_new_log_timestamp_format=1; + } else if ((pass==0) && (c==NEW_TIMESTAMP_FORMAT_OPT)) { + set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { set_option(c, value); } else if((pass > 0) && (c == 'u')) { From 315341d204cb8b93ee076ea1935a367b48170e62 Mon Sep 17 00:00:00 2001 From: Samuel Date: Mon, 14 Sep 2020 12:34:04 +0200 Subject: [PATCH 036/128] Fix misleading option in doc While that prometheus exporter was initially enabled by default, it looks like there's been a change of plan, resulting in some inconsistencies in the doc. The `--no-prometheus` option was replaced by a `--prometheus` one -- according to https://github.com/wolmi/coturn/blob/master/src/apps/relay/mainrelay.c#L540 --- README.turnserver | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.turnserver b/README.turnserver index 320021e9..a5bf149a 100644 --- a/README.turnserver +++ b/README.turnserver @@ -265,8 +265,8 @@ Flags: check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). - --no-prometheus Disable prometheus metrics. By default it is - enabled and listening on port 9641 unther the path /metrics + --prometheus Enable prometheus metrics. By default it is + disabled. Would listen on port 9641 unther the path /metrics also the path / on this port can be used as a health check -h Help. From bd3dd85a762df5192f5d1fea29f62adbf2d76b14 Mon Sep 17 00:00:00 2001 From: ddeka2910 <60925700+ddeka2910@users.noreply.github.com> Date: Tue, 6 Oct 2020 23:42:47 +0530 Subject: [PATCH 037/128] Add architecture ppc64le to travis build --- .travis.yml | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84e024f2..f3199c79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,42 @@ matrix: osx_image: xcode11.6 - os: osx osx_image: xcode12 - + - os: linux + arch: ppc64le + dist: xenial + sudo: required + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev + - os: linux + arch: ppc64le + dist: bionic + sudo: required + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev notifications: slack: From fad52a0e94edad626150c706ff6013a93d6e77ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 13 Oct 2020 10:13:25 +0200 Subject: [PATCH 038/128] Delete Dockerfile.build It was outdated --- Dockerfile.build | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 Dockerfile.build diff --git a/Dockerfile.build b/Dockerfile.build deleted file mode 100644 index 684805b3..00000000 --- a/Dockerfile.build +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:16.04 - -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ - emacs-nox \ - build-essential \ - libssl-dev sqlite3 \ - libsqlite3-dev \ - libevent-dev \ - g++ \ - libboost-dev From ae2ee1f4e4f4f4119425e3d890a7f6ca44b57d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 13 Oct 2020 10:16:36 +0200 Subject: [PATCH 039/128] Delete build-docker.sh It depended on the remove outdated Docker file so it is also removed. See the docker dir for more up2date docker build files --- build-docker.sh | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100755 build-docker.sh diff --git a/build-docker.sh b/build-docker.sh deleted file mode 100755 index abb51138..00000000 --- a/build-docker.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -o xtrace - -dir=`pwd` -echo "$dir" - -build_image=coturnbuild -dockerargs="--privileged -v ${dir}:/root/coturn -w /root/coturn" -container_env=' -e "INSIDECONTAINER=-incontainer=true"' -docker="docker run --rm -it ${dockerargs} ${container_env} ${build_image}" - -docker build -f Dockerfile.build -t ${build_image} . - -${docker} bash -c "./configure && make" - From 2baacbf89519b35e4dae41223457a7fdaebbba9c Mon Sep 17 00:00:00 2001 From: David Florness Date: Sat, 17 Oct 2020 13:49:07 -0400 Subject: [PATCH 040/128] Delete trailing whitespace in example configuration files --- docker/coturn/turnserver.conf | 188 +++++++++++++++++----------------- examples/etc/turnserver.conf | 186 ++++++++++++++++----------------- 2 files changed, 187 insertions(+), 187 deletions(-) diff --git a/docker/coturn/turnserver.conf b/docker/coturn/turnserver.conf index 00ce8abd..fc9ac1fe 100644 --- a/docker/coturn/turnserver.conf +++ b/docker/coturn/turnserver.conf @@ -1,45 +1,45 @@ # Coturn TURN SERVER configuration file # # Boolean values note: where a boolean value is supposed to be used, -# you can use '0', 'off', 'no', 'false', or 'f' as 'false, -# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' +# you can use '0', 'off', 'no', 'false', or 'f' as 'false, +# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' # If the value is missing, then it means 'true' by default. # # Listener interface device (optional, Linux only). -# NOT RECOMMENDED. +# NOT RECOMMENDED. # #listening-device=eth0 # TURN listener port for UDP and TCP (Default: 3478). -# Note: actually, TLS & DTLS sessions can connect to the +# Note: actually, TLS & DTLS sessions can connect to the # "plain" TCP & UDP port(s), too - if allowed by configuration. # listening-port=3478 # TURN listener port for TLS (Default: 5349). # Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS -# port(s), too - if allowed by configuration. The TURN server +# port(s), too - if allowed by configuration. The TURN server # "automatically" recognizes the type of traffic. Actually, two listening # endpoints (the "plain" one and the "tls" one) are equivalent in terms of # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs. -# For secure TCP connections, Coturn currently supports SSL version 3 and +# For secure TCP connections, Coturn currently supports SSL version 3 and # TLS version 1.0, 1.1 and 1.2. # For secure UDP connections, Coturn supports DTLS version 1. # tls-listening-port=5349 # Alternative listening port for UDP and TCP listeners; -# default (or zero) value means "listening port plus one". +# default (or zero) value means "listening port plus one". # This is needed for RFC 5780 support -# (STUN extension specs, NAT behavior discovery). The TURN Server -# supports RFC 5780 only if it is started with more than one +# (STUN extension specs, NAT behavior discovery). The TURN Server +# supports RFC 5780 only if it is started with more than one # listening IP address of the same family (IPv4 or IPv6). # RFC 5780 is supported only by UDP protocol, other protocols # are listening to that endpoint only for "symmetry". # #alt-listening-port=0 - + # Alternative listening port for TLS and DTLS protocols. # Default (or zero) value means "TLS listening port plus one". # @@ -52,9 +52,9 @@ tls-listening-port=5349 # (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) # #tcp-proxy-port=5555 - + # Listener IP address of relay server. Multiple listeners can be specified. -# If no IP(s) specified in the config file or in the command line options, +# If no IP(s) specified in the config file or in the command line options, # then all IPv4 and IPv6 system IPs will be used for listening. # #listening-ip=172.17.19.101 @@ -69,7 +69,7 @@ tls-listening-port=5349 # they do not support STUN RFC 5780 functionality (CHANGE REQUEST). # # 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply. -# +# # Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6. # # There may be multiple aux-server options, each will be used for listening @@ -81,7 +81,7 @@ tls-listening-port=5349 # (recommended for older Linuxes only) # Automatically balance UDP traffic over auxiliary servers (if configured). # The load balancing is using the ALTERNATE-SERVER mechanism. -# The TURN client must support 300 ALTERNATE-SERVER response for this +# The TURN client must support 300 ALTERNATE-SERVER response for this # functionality. # #udp-self-balance @@ -91,13 +91,13 @@ tls-listening-port=5349 # #relay-device=eth1 -# Relay address (the local IP address that will be used to relay the +# Relay address (the local IP address that will be used to relay the # packets to the peer). # Multiple relay addresses may be used. # The same IP(s) can be used as both listening IP(s) and relay IP(s). # # If no relay IP(s) specified, then the turnserver will apply the default -# policy: it will decide itself which relay addresses to be used, and it +# policy: it will decide itself which relay addresses to be used, and it # will always be using the client socket IP address as the relay IP address # of the TURN session (if the requested relay address family is the same # as the family of the client socket). @@ -120,7 +120,7 @@ tls-listening-port=5349 # that option must be used several times, each entry must # have form "-X ", to map all involved addresses. # RFC5780 NAT discovery STUN functionality will work correctly, -# if the addresses are mapped properly, even when the TURN server itself +# if the addresses are mapped properly, even when the TURN server itself # is behind A NAT. # # By default, this value is empty, and no address mapping is used. @@ -135,18 +135,18 @@ external-ip=193.224.22.37 # Number of the relay threads to handle the established connections # (in addition to authentication thread and the listener thread). -# If explicitly set to 0 then application runs relay process in a -# single thread, in the same thread with the listener process +# If explicitly set to 0 then application runs relay process in a +# single thread, in the same thread with the listener process # (the authentication thread will still be a separate thread). # -# If this parameter is not set, then the default OS-dependent +# If this parameter is not set, then the default OS-dependent # thread pattern algorithm will be employed. Usually the default # algorithm is optimal, so you have to change this option -# if you want to make some fine tweaks. +# if you want to make some fine tweaks. # # In the older systems (Linux kernel before 3.9), # the number of UDP threads is always one thread per network listening -# endpoint - including the auxiliary endpoints - unless 0 (zero) or +# endpoint - including the auxiliary endpoints - unless 0 (zero) or # 1 (one) value is set. # #relay-threads=0 @@ -156,15 +156,15 @@ external-ip=193.224.22.37 # min-port=49152 max-port=65535 - + # Uncomment to run TURN server in 'normal' 'moderate' verbose mode. # By default the verbose mode is off. verbose - + # Uncomment to run TURN server in 'extra' verbose mode. # This mode is very annoying and produces lots of output. # Not recommended under normal circumstances. -# +# #Verbose # Uncomment to use fingerprints in the TURN messages. @@ -177,10 +177,10 @@ fingerprint # lt-cred-mech -# This option is the opposite of lt-cred-mech. +# This option is the opposite of lt-cred-mech. # (TURN Server with no-auth option allows anonymous access). # If neither option is defined, and no users are defined, -# then no-auth is default. If at least one user is defined, +# then no-auth is default. If at least one user is defined, # in this file, in command line or in usersdb file, then # lt-cred-mech is default. # @@ -191,11 +191,11 @@ lt-cred-mech # Flag that sets a special authorization option that is based upon authentication secret. # # This feature's purpose is to support "TURN Server REST API", see -# "TURN REST API" link in the project's page +# "TURN REST API" link in the project's page # https://github.com/coturn/coturn/ # # This option is used with timestamp: -# +# # usercombo -> "timestamp:userid" # turn user -> usercombo # turn password -> base64(hmac(secret key, usercombo)) @@ -205,7 +205,7 @@ lt-cred-mech # This option is enabled by turning on secret-based authentication. # The actual value of the secret is defined either by the option static-auth-secret, # or can be found in the turn_secret table in the database (see below). -# +# # Read more about it: # - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 # - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf @@ -217,13 +217,13 @@ lt-cred-mech # # Note that you can use only one auth mechanism at the same time! This is because, # both mechanisms conduct username and password validation in different ways. -# +# # Use either lt-cred-mech or use-auth-secret in the conf # to avoid any confusion. # #use-auth-secret -# 'Static' authentication secret value (a string) for TURN REST API only. +# 'Static' authentication secret value (a string) for TURN REST API only. # If not set, then the turn server # will try to use the 'dynamic' value in the turn_secret table # in the user database (if present). The database-stored value can be changed on-the-fly @@ -243,7 +243,7 @@ lt-cred-mech # 'Static' user accounts for the long term credentials mechanism, only. # This option cannot be used with TURN REST API. -# 'Static' user accounts are NOT dynamically checked by the turnserver process, +# 'Static' user accounts are NOT dynamically checked by the turnserver process, # so they can NOT be changed while the turnserver is running. # #user=username1:key1 @@ -262,7 +262,7 @@ lt-cred-mech # password. If it has 0x then it is a key, otherwise it is a password). # # The corresponding user account entry in the config file will be: -# +# #user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee # Or, equivalently, with open clear password (less secure): #user=ninefingers:youhavetoberealistic @@ -272,15 +272,15 @@ lt-cred-mech # # The default file name is /var/db/turndb or /usr/local/var/db/turndb or # /var/lib/turn/turndb. -# +# #userdb=/var/db/turndb # PostgreSQL database connection string in the case that you are using PostgreSQL # as the user database. # This database can be used for the long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL -# versions connection string format, see +# versions connection string format, see # http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING # for 9.x and newer connection string formats. # @@ -291,9 +291,9 @@ lt-cred-mech # This database can be used for the long-term credential mechanism # and it can store the secret value for secret-based timed authentication in TURN REST API. # -# Optional connection string parameters for the secure communications (SSL): -# ca, capath, cert, key, cipher -# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the +# Optional connection string parameters for the secure communications (SSL): +# ca, capath, cert, key, cipher +# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the # command options description). # # Use the string format below (space separated parameters, all optional): @@ -303,7 +303,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # If you want to use an encrypted password in the MySQL connection string, # then set the MySQL password encryption secret key file with this option. # -# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! +# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! # If you want to use a cleartext password then do not set this option! # # This is the file path for the aes encrypted secret key used for password encryption. @@ -313,7 +313,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # MongoDB database connection string in the case that you are using MongoDB # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html # #mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]" @@ -321,7 +321,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # Redis database connection string in the case that you are using Redis # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format below (space separated parameters, all optional): # #redis-userdb="ip= dbname= password= port= connect_timeout=" @@ -329,15 +329,15 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used). # This database keeps allocations status information, and it can be also used for publishing # and delivering traffic and allocation event notifications. -# The connection string has the same parameters as redis-userdb connection string. +# The connection string has the same parameters as redis-userdb connection string. # Use the string format below (space separated parameters, all optional): # #redis-statsdb="ip= dbname= password= port= connect_timeout=" -# The default realm to be used for the users when no explicit +# The default realm to be used for the users when no explicit # origin/realm relationship is found in the database, or if the TURN # server is not using any database (just the commands-line settings -# and the userdb file). Must be used with long-term credentials +# and the userdb file). Must be used with long-term credentials # mechanism or with TURN REST API. # # Note: If the default realm is not specified, then realm falls back to the host domain name. @@ -345,7 +345,7 @@ mysql-userdb="host=mysql dbname=coturn user=coturn password=CHANGE_ME port=3306 # realm=example.org -# This flag sets the origin consistency +# This flag sets the origin consistency # check. Across the session, all requests must have the same # main ORIGIN attribute value (if the ORIGIN was # initially used by the session). @@ -412,9 +412,9 @@ realm=example.org # Uncomment if extra security is desired, # with nonce value having a limited lifetime. # By default, the nonce value is unique for a session, -# and has an unlimited lifetime. -# Set this option to limit the nonce lifetime. -# It defaults to 600 secs (10 min) if no value is provided. After that delay, +# and has an unlimited lifetime. +# Set this option to limit the nonce lifetime. +# It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # #stale-nonce=600 @@ -440,14 +440,14 @@ realm=example.org #permission-lifetime=300 # Certificate file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # cert=/etc/ssl/certs/cert.pem # Private key file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # @@ -463,7 +463,7 @@ pkey=/etc/ssl/private/privkey.pem # #cipher-list="DEFAULT" -# CA file in OpenSSL format. +# CA file in OpenSSL format. # Forces TURN server to verify the client SSL certificates. # By default this is not set: there is no default value and the client # certificate is not checked. @@ -471,8 +471,8 @@ pkey=/etc/ssl/private/privkey.pem # Example: #CA-file=/etc/ssh/id_rsa.cert -# Curve name for EC ciphers, if supported by OpenSSL -# library (TLS and DTLS). The default value is prime256v1, +# Curve name for EC ciphers, if supported by OpenSSL +# library (TLS and DTLS). The default value is prime256v1, # if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+, # an optimal curve will be automatically calculated, if not defined # by this option. @@ -493,21 +493,21 @@ pkey=/etc/ssl/private/privkey.pem #dh-file= # Flag to prevent stdout log messages. -# By default, all log messages go to both stdout and to -# the configured log file. With this option everything will +# By default, all log messages go to both stdout and to +# the configured log file. With this option everything will # go to the configured log only (unless the log file itself is stdout). # #no-stdout-log # Option to set the log file name. -# By default, the turnserver tries to open a log file in +# By default, the turnserver tries to open a log file in # /var/log, /var/tmp, /tmp and the current directory # (Whichever file open operation succeeds first will be used). # With this option you can set the definite log file name. -# The special names are "stdout" and "-" - they will force everything +# The special names are "stdout" and "-" - they will force everything # to the stdout. Also, the "syslog" name will force everything to -# the system log (syslog). -# In the runtime, the logfile can be reset with the SIGHUP signal +# the system log (syslog). +# In the runtime, the logfile can be reset with the SIGHUP signal # to the turnserver process. # #log-file=/var/tmp/turn.log @@ -523,40 +523,40 @@ syslog #simple-log # Option to set the "redirection" mode. The value of this option -# will be the address of the alternate server for UDP & TCP service in the form of +# will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute # ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client. # Client will receive only values with the same address family -# as the client network endpoint address family. -# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. +# as the client network endpoint address family. +# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. # The client must use the obtained value for subsequent TURN communications. # If more than one --alternate-server option is provided, then the functionality -# can be more accurately described as "load-balancing" than a mere "redirection". -# If the port number is omitted, then the default port +# can be more accurately described as "load-balancing" than a mere "redirection". +# If the port number is omitted, then the default port # number 3478 for the UDP/TCP protocols will be used. -# Colon (:) characters in IPv6 addresses may conflict with the syntax of -# the option. To alleviate this conflict, literal IPv6 addresses are enclosed -# in square brackets in such resource identifiers, for example: -# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . +# Colon (:) characters in IPv6 addresses may conflict with the syntax of +# the option. To alleviate this conflict, literal IPv6 addresses are enclosed +# in square brackets in such resource identifiers, for example: +# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . # Multiple alternate servers can be set. They will be used in the -# round-robin manner. All servers in the pool are considered of equal weight and -# the load will be distributed equally. For example, if you have 4 alternate servers, -# then each server will receive 25% of ALLOCATE requests. A alternate TURN server -# address can be used more than one time with the alternate-server option, so this +# round-robin manner. All servers in the pool are considered of equal weight and +# the load will be distributed equally. For example, if you have 4 alternate servers, +# then each server will receive 25% of ALLOCATE requests. A alternate TURN server +# address can be used more than one time with the alternate-server option, so this # can emulate "weighting" of the servers. # -# Examples: +# Examples: #alternate-server=1.2.3.4:5678 #alternate-server=11.22.33.44:56789 #alternate-server=5.6.7.8 #alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 - -# Option to set alternative server for TLS & DTLS services in form of -# :. If the port number is omitted, then the default port -# number 5349 for the TLS/DTLS protocols will be used. See the previous + +# Option to set alternative server for TLS & DTLS services in form of +# :. If the port number is omitted, then the default port +# number 5349 for the TLS/DTLS protocols will be used. See the previous # option for the functionality description. # -# Examples: +# Examples: #tls-alternate-server=1.2.3.4:5678 #tls-alternate-server=11.22.33.44:56789 #tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 @@ -584,7 +584,7 @@ syslog # This is the timestamp/username separator symbol (character) in TURN REST API. # The default value is ':'. -# rest-api-separator=: +# rest-api-separator=: # Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1). # This is an extra security measure. @@ -592,9 +592,9 @@ syslog # (To avoid any security issue that allowing loopback access may raise, # the no-loopback-peers option is replaced by allow-loopback-peers.) # -# Allow it only for testing in a development environment! -# In production it adds a possible security vulnerability, so for security reasons -# it is not allowed using it together with empty cli-password. +# Allow it only for testing in a development environment! +# In production it adds a possible security vulnerability, so for security reasons +# it is not allowed using it together with empty cli-password. # #allow-loopback-peers @@ -603,18 +603,18 @@ syslog # #no-multicast-peers -# Option to set the max time, in seconds, allowed for full allocation establishment. +# Option to set the max time, in seconds, allowed for full allocation establishment. # Default is 60 seconds. # #max-allocate-timeout=60 -# Option to allow or ban specific ip addresses or ranges of ip addresses. -# If an ip address is specified as both allowed and denied, then the ip address is -# considered to be allowed. This is useful when you wish to ban a range of ip +# Option to allow or ban specific ip addresses or ranges of ip addresses. +# If an ip address is specified as both allowed and denied, then the ip address is +# considered to be allowed. This is useful when you wish to ban a range of ip # addresses, except for a few specific ips within that range. # # This can be used when you do not want users of the turn server to be able to access -# machines reachable by the turn server, but would otherwise be unreachable from the +# machines reachable by the turn server, but would otherwise be unreachable from the # internet (e.g. when the turn server is sitting behind a NAT) # # Examples: @@ -636,8 +636,8 @@ syslog # #mobility -# Allocate Address Family according -# If enabled then TURN server allocates address family according the TURN +# Allocate Address Family according +# If enabled then TURN server allocates address family according the TURN # Client <=> Server communication address family. # (By default Coturn works according RFC 6156.) # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!! @@ -701,10 +701,10 @@ cli-password=CHANGE_ME # #web-admin-listen-on-workers -# Server relay. NON-STANDARD AND DANGEROUS OPTION. -# Only for those applications when you want to run +# Server relay. NON-STANDARD AND DANGEROUS OPTION. +# Only for those applications when you want to run # server applications on the relay endpoints. -# This option eliminates the IP permissions check on +# This option eliminates the IP permissions check on # the packets incoming to the relay endpoints. # #server-relay diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 515ed131..3af6845c 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -1,25 +1,25 @@ # Coturn TURN SERVER configuration file # # Boolean values note: where a boolean value is supposed to be used, -# you can use '0', 'off', 'no', 'false', or 'f' as 'false, -# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' +# you can use '0', 'off', 'no', 'false', or 'f' as 'false, +# and you can use '1', 'on', 'yes', 'true', or 't' as 'true' # If the value is missing, then it means 'true' by default. # # Listener interface device (optional, Linux only). -# NOT RECOMMENDED. +# NOT RECOMMENDED. # #listening-device=eth0 # TURN listener port for UDP and TCP (Default: 3478). -# Note: actually, TLS & DTLS sessions can connect to the +# Note: actually, TLS & DTLS sessions can connect to the # "plain" TCP & UDP port(s), too - if allowed by configuration. # #listening-port=3478 # TURN listener port for TLS (Default: 5349). # Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS -# port(s), too - if allowed by configuration. The TURN server +# port(s), too - if allowed by configuration. The TURN server # "automatically" recognizes the type of traffic. Actually, two listening # endpoints (the "plain" one and the "tls" one) are equivalent in terms of # functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs. @@ -30,16 +30,16 @@ #tls-listening-port=5349 # Alternative listening port for UDP and TCP listeners; -# default (or zero) value means "listening port plus one". +# default (or zero) value means "listening port plus one". # This is needed for RFC 5780 support -# (STUN extension specs, NAT behavior discovery). The TURN Server -# supports RFC 5780 only if it is started with more than one +# (STUN extension specs, NAT behavior discovery). The TURN Server +# supports RFC 5780 only if it is started with more than one # listening IP address of the same family (IPv4 or IPv6). # RFC 5780 is supported only by UDP protocol, other protocols # are listening to that endpoint only for "symmetry". # #alt-listening-port=0 - + # Alternative listening port for TLS and DTLS protocols. # Default (or zero) value means "TLS listening port plus one". # @@ -52,9 +52,9 @@ # (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) # #tcp-proxy-port=5555 - + # Listener IP address of relay server. Multiple listeners can be specified. -# If no IP(s) specified in the config file or in the command line options, +# If no IP(s) specified in the config file or in the command line options, # then all IPv4 and IPv6 system IPs will be used for listening. # #listening-ip=172.17.19.101 @@ -69,7 +69,7 @@ # they do not support STUN RFC 5780 functionality (CHANGE REQUEST). # # 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply. -# +# # Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6. # # There may be multiple aux-server options, each will be used for listening @@ -81,7 +81,7 @@ # (recommended for older Linuxes only) # Automatically balance UDP traffic over auxiliary servers (if configured). # The load balancing is using the ALTERNATE-SERVER mechanism. -# The TURN client must support 300 ALTERNATE-SERVER response for this +# The TURN client must support 300 ALTERNATE-SERVER response for this # functionality. # #udp-self-balance @@ -91,13 +91,13 @@ # #relay-device=eth1 -# Relay address (the local IP address that will be used to relay the +# Relay address (the local IP address that will be used to relay the # packets to the peer). # Multiple relay addresses may be used. # The same IP(s) can be used as both listening IP(s) and relay IP(s). # # If no relay IP(s) specified, then the turnserver will apply the default -# policy: it will decide itself which relay addresses to be used, and it +# policy: it will decide itself which relay addresses to be used, and it # will always be using the client socket IP address as the relay IP address # of the TURN session (if the requested relay address family is the same # as the family of the client socket). @@ -120,7 +120,7 @@ # that option must be used several times, each entry must # have form "-X ", to map all involved addresses. # RFC5780 NAT discovery STUN functionality will work correctly, -# if the addresses are mapped properly, even when the TURN server itself +# if the addresses are mapped properly, even when the TURN server itself # is behind A NAT. # # By default, this value is empty, and no address mapping is used. @@ -135,18 +135,18 @@ # Number of the relay threads to handle the established connections # (in addition to authentication thread and the listener thread). -# If explicitly set to 0 then application runs relay process in a -# single thread, in the same thread with the listener process +# If explicitly set to 0 then application runs relay process in a +# single thread, in the same thread with the listener process # (the authentication thread will still be a separate thread). # -# If this parameter is not set, then the default OS-dependent +# If this parameter is not set, then the default OS-dependent # thread pattern algorithm will be employed. Usually the default # algorithm is optimal, so you have to change this option -# if you want to make some fine tweaks. +# if you want to make some fine tweaks. # # In the older systems (Linux kernel before 3.9), # the number of UDP threads is always one thread per network listening -# endpoint - including the auxiliary endpoints - unless 0 (zero) or +# endpoint - including the auxiliary endpoints - unless 0 (zero) or # 1 (one) value is set. # #relay-threads=0 @@ -156,15 +156,15 @@ # #min-port=49152 #max-port=65535 - + # Uncomment to run TURN server in 'normal' 'moderate' verbose mode. # By default the verbose mode is off. #verbose - + # Uncomment to run TURN server in 'extra' verbose mode. # This mode is very annoying and produces lots of output. # Not recommended under normal circumstances. -# +# #Verbose # Uncomment to use fingerprints in the TURN messages. @@ -177,10 +177,10 @@ # #lt-cred-mech -# This option is the opposite of lt-cred-mech. +# This option is the opposite of lt-cred-mech. # (TURN Server with no-auth option allows anonymous access). # If neither option is defined, and no users are defined, -# then no-auth is default. If at least one user is defined, +# then no-auth is default. If at least one user is defined, # in this file, in command line or in usersdb file, then # lt-cred-mech is default. # @@ -203,11 +203,11 @@ # Flag that sets a special authorization option that is based upon authentication secret. # # This feature's purpose is to support "TURN Server REST API", see -# "TURN REST API" link in the project's page +# "TURN REST API" link in the project's page # https://github.com/coturn/coturn/ # # This option is used with timestamp: -# +# # usercombo -> "timestamp:userid" # turn user -> usercombo # turn password -> base64(hmac(secret key, usercombo)) @@ -217,7 +217,7 @@ # This option is enabled by turning on secret-based authentication. # The actual value of the secret is defined either by the option static-auth-secret, # or can be found in the turn_secret table in the database (see below). -# +# # Read more about it: # - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00 # - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf @@ -229,13 +229,13 @@ # # Note that you can use only one auth mechanism at the same time! This is because, # both mechanisms conduct username and password validation in different ways. -# +# # Use either lt-cred-mech or use-auth-secret in the conf # to avoid any confusion. # #use-auth-secret -# 'Static' authentication secret value (a string) for TURN REST API only. +# 'Static' authentication secret value (a string) for TURN REST API only. # If not set, then the turn server # will try to use the 'dynamic' value in the turn_secret table # in the user database (if present). The database-stored value can be changed on-the-fly @@ -255,7 +255,7 @@ # 'Static' user accounts for the long term credentials mechanism, only. # This option cannot be used with TURN REST API. -# 'Static' user accounts are NOT dynamically checked by the turnserver process, +# 'Static' user accounts are NOT dynamically checked by the turnserver process, # so they can NOT be changed while the turnserver is running. # #user=username1:key1 @@ -274,7 +274,7 @@ # password. If it has 0x then it is a key, otherwise it is a password). # # The corresponding user account entry in the config file will be: -# +# #user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee # Or, equivalently, with open clear password (less secure): #user=ninefingers:youhavetoberealistic @@ -284,15 +284,15 @@ # # The default file name is /var/db/turndb or /usr/local/var/db/turndb or # /var/lib/turn/turndb. -# +# #userdb=/var/db/turndb # PostgreSQL database connection string in the case that you are using PostgreSQL # as the user database. # This database can be used for the long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL -# versions connection string format, see +# versions connection string format, see # http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING # for 9.x and newer connection string formats. # @@ -303,9 +303,9 @@ # This database can be used for the long-term credential mechanism # and it can store the secret value for secret-based timed authentication in TURN REST API. # -# Optional connection string parameters for the secure communications (SSL): -# ca, capath, cert, key, cipher -# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the +# Optional connection string parameters for the secure communications (SSL): +# ca, capath, cert, key, cipher +# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the # command options description). # # Use the string format below (space separated parameters, all optional): @@ -315,7 +315,7 @@ # If you want to use an encrypted password in the MySQL connection string, # then set the MySQL password encryption secret key file with this option. # -# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! +# Warning: If this option is set, then the mysql password must be set in "mysql-userdb" in an encrypted format! # If you want to use a cleartext password then do not set this option! # # This is the file path for the aes encrypted secret key used for password encryption. @@ -325,7 +325,7 @@ # MongoDB database connection string in the case that you are using MongoDB # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html # #mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]" @@ -333,7 +333,7 @@ # Redis database connection string in the case that you are using Redis # as the user database. # This database can be used for long-term credential mechanism -# and it can store the secret value for secret-based timed authentication in TURN REST API. +# and it can store the secret value for secret-based timed authentication in TURN REST API. # Use the string format below (space separated parameters, all optional): # #redis-userdb="ip= dbname= password= port= connect_timeout=" @@ -341,15 +341,15 @@ # Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used). # This database keeps allocations status information, and it can be also used for publishing # and delivering traffic and allocation event notifications. -# The connection string has the same parameters as redis-userdb connection string. +# The connection string has the same parameters as redis-userdb connection string. # Use the string format below (space separated parameters, all optional): # #redis-statsdb="ip= dbname= password= port= connect_timeout=" -# The default realm to be used for the users when no explicit +# The default realm to be used for the users when no explicit # origin/realm relationship is found in the database, or if the TURN # server is not using any database (just the commands-line settings -# and the userdb file). Must be used with long-term credentials +# and the userdb file). Must be used with long-term credentials # mechanism or with TURN REST API. # # Note: If the default realm is not specified, then realm falls back to the host domain name. @@ -357,7 +357,7 @@ # #realm=mycompany.org -# This flag sets the origin consistency +# This flag sets the origin consistency # check. Across the session, all requests must have the same # main ORIGIN attribute value (if the ORIGIN was # initially used by the session). @@ -424,9 +424,9 @@ # Uncomment if extra security is desired, # with nonce value having a limited lifetime. # By default, the nonce value is unique for a session, -# and has an unlimited lifetime. -# Set this option to limit the nonce lifetime. -# It defaults to 600 secs (10 min) if no value is provided. After that delay, +# and has an unlimited lifetime. +# Set this option to limit the nonce lifetime. +# It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # #stale-nonce=600 @@ -452,14 +452,14 @@ #permission-lifetime=300 # Certificate file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # #cert=/usr/local/etc/turn_server_cert.pem # Private key file. -# Use an absolute path or path relative to the +# Use an absolute path or path relative to the # configuration file. # Use PEM file format. # @@ -475,7 +475,7 @@ # #cipher-list="DEFAULT" -# CA file in OpenSSL format. +# CA file in OpenSSL format. # Forces TURN server to verify the client SSL certificates. # By default this is not set: there is no default value and the client # certificate is not checked. @@ -483,8 +483,8 @@ # Example: #CA-file=/etc/ssh/id_rsa.cert -# Curve name for EC ciphers, if supported by OpenSSL -# library (TLS and DTLS). The default value is prime256v1, +# Curve name for EC ciphers, if supported by OpenSSL +# library (TLS and DTLS). The default value is prime256v1, # if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+, # an optimal curve will be automatically calculated, if not defined # by this option. @@ -505,21 +505,21 @@ #dh-file= # Flag to prevent stdout log messages. -# By default, all log messages go to both stdout and to -# the configured log file. With this option everything will +# By default, all log messages go to both stdout and to +# the configured log file. With this option everything will # go to the configured log only (unless the log file itself is stdout). # #no-stdout-log # Option to set the log file name. -# By default, the turnserver tries to open a log file in +# By default, the turnserver tries to open a log file in # /var/log, /var/tmp, /tmp and the current directory # (Whichever file open operation succeeds first will be used). # With this option you can set the definite log file name. -# The special names are "stdout" and "-" - they will force everything +# The special names are "stdout" and "-" - they will force everything # to the stdout. Also, the "syslog" name will force everything to -# the system log (syslog). -# In the runtime, the logfile can be reset with the SIGHUP signal +# the system log (syslog). +# In the runtime, the logfile can be reset with the SIGHUP signal # to the turnserver process. # #log-file=/var/tmp/turn.log @@ -535,40 +535,40 @@ #simple-log # Option to set the "redirection" mode. The value of this option -# will be the address of the alternate server for UDP & TCP service in the form of +# will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute # ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client. # Client will receive only values with the same address family -# as the client network endpoint address family. -# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. +# as the client network endpoint address family. +# See RFC 5389 and RFC 5766 for the description of ALTERNATE-SERVER functionality. # The client must use the obtained value for subsequent TURN communications. # If more than one --alternate-server option is provided, then the functionality -# can be more accurately described as "load-balancing" than a mere "redirection". -# If the port number is omitted, then the default port +# can be more accurately described as "load-balancing" than a mere "redirection". +# If the port number is omitted, then the default port # number 3478 for the UDP/TCP protocols will be used. -# Colon (:) characters in IPv6 addresses may conflict with the syntax of -# the option. To alleviate this conflict, literal IPv6 addresses are enclosed -# in square brackets in such resource identifiers, for example: -# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . +# Colon (:) characters in IPv6 addresses may conflict with the syntax of +# the option. To alleviate this conflict, literal IPv6 addresses are enclosed +# in square brackets in such resource identifiers, for example: +# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 . # Multiple alternate servers can be set. They will be used in the -# round-robin manner. All servers in the pool are considered of equal weight and -# the load will be distributed equally. For example, if you have 4 alternate servers, -# then each server will receive 25% of ALLOCATE requests. A alternate TURN server -# address can be used more than one time with the alternate-server option, so this +# round-robin manner. All servers in the pool are considered of equal weight and +# the load will be distributed equally. For example, if you have 4 alternate servers, +# then each server will receive 25% of ALLOCATE requests. A alternate TURN server +# address can be used more than one time with the alternate-server option, so this # can emulate "weighting" of the servers. # -# Examples: +# Examples: #alternate-server=1.2.3.4:5678 #alternate-server=11.22.33.44:56789 #alternate-server=5.6.7.8 #alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 - -# Option to set alternative server for TLS & DTLS services in form of -# :. If the port number is omitted, then the default port -# number 5349 for the TLS/DTLS protocols will be used. See the previous + +# Option to set alternative server for TLS & DTLS services in form of +# :. If the port number is omitted, then the default port +# number 5349 for the TLS/DTLS protocols will be used. See the previous # option for the functionality description. # -# Examples: +# Examples: #tls-alternate-server=1.2.3.4:5678 #tls-alternate-server=11.22.33.44:56789 #tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 @@ -596,7 +596,7 @@ # This is the timestamp/username separator symbol (character) in TURN REST API. # The default value is ':'. -# rest-api-separator=: +# rest-api-separator=: # Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1). # This is an extra security measure. @@ -604,9 +604,9 @@ # (To avoid any security issue that allowing loopback access may raise, # the no-loopback-peers option is replaced by allow-loopback-peers.) # -# Allow it only for testing in a development environment! -# In production it adds a possible security vulnerability, so for security reasons -# it is not allowed using it together with empty cli-password. +# Allow it only for testing in a development environment! +# In production it adds a possible security vulnerability, so for security reasons +# it is not allowed using it together with empty cli-password. # #allow-loopback-peers @@ -615,18 +615,18 @@ # #no-multicast-peers -# Option to set the max time, in seconds, allowed for full allocation establishment. +# Option to set the max time, in seconds, allowed for full allocation establishment. # Default is 60 seconds. # #max-allocate-timeout=60 -# Option to allow or ban specific ip addresses or ranges of ip addresses. -# If an ip address is specified as both allowed and denied, then the ip address is -# considered to be allowed. This is useful when you wish to ban a range of ip +# Option to allow or ban specific ip addresses or ranges of ip addresses. +# If an ip address is specified as both allowed and denied, then the ip address is +# considered to be allowed. This is useful when you wish to ban a range of ip # addresses, except for a few specific ips within that range. # # This can be used when you do not want users of the turn server to be able to access -# machines reachable by the turn server, but would otherwise be unreachable from the +# machines reachable by the turn server, but would otherwise be unreachable from the # internet (e.g. when the turn server is sitting behind a NAT) # # Examples: @@ -648,8 +648,8 @@ # #mobility -# Allocate Address Family according -# If enabled then TURN server allocates address family according the TURN +# Allocate Address Family according +# If enabled then TURN server allocates address family according the TURN # Client <=> Server communication address family. # (By default Coturn works according RFC 6156.) # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!! @@ -713,10 +713,10 @@ # #web-admin-listen-on-workers -# Server relay. NON-STANDARD AND DANGEROUS OPTION. -# Only for those applications when you want to run +# Server relay. NON-STANDARD AND DANGEROUS OPTION. +# Only for those applications when you want to run # server applications on the relay endpoints. -# This option eliminates the IP permissions check on +# This option eliminates the IP permissions check on # the packets incoming to the relay endpoints. # #server-relay From 9980f846015a77c87a311749b5935dc019fc767c Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Sat, 6 Oct 2018 19:41:52 +0100 Subject: [PATCH 041/128] configure: Fix CC detection when 'unknown' is on PATH We can't be sure that a program called 'unknown' will never exist. --- configure | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/configure b/configure index 38227c6e..c7a1e266 100755 --- a/configure +++ b/configure @@ -783,22 +783,28 @@ int main(int argc, char** argv) { ########################## if [ -z "${CC}" ] ; then - CC=cc + for CC in cc gcc clang; do + ${CC} ${TMPCPROGC} ${OSCFLAGS} -o ${TMPCPROGB} 2>>/dev/null + ER=$? + if [ ${ER} -eq 0 ] ; then + break + fi + CC= + done + + if [ -z "$CC" ] ; then + ${ECHO_CMD} "ERROR: failed to a find working C compiler" + cleanup + exit + fi +else ${CC} ${TMPCPROGC} ${OSCFLAGS} -o ${TMPCPROGB} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - CC=gcc - ${CC} ${TMPCPROGC} ${OSCFLAGS} -o ${TMPCPROGB} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - CC=clang - ${CC} ${TMPCPROGC} ${OSCFLAGS} -o ${TMPCPROGB} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - CC=unknown - fi - fi - fi + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "ERROR: cannot use compiler ${CC} properly" + cleanup + exit + fi fi ${ECHO_CMD} "Compiler: ${CC}" @@ -811,14 +817,6 @@ if [ -z "${TURN_ACCEPT_RPATH}" ] ; then fi fi -${CC} ${TMPCPROGC} ${OSCFLAGS} -o ${TMPCPROGB} 2>>/dev/null -ER=$? -if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "ERROR: cannot use compiler ${CC} properly" - cleanup - exit -fi - ########################### # Check if we can use GNU # or Clang compiler flags From 28352b12ace0d78e126e5d7c9724e2afb17ed1b1 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 18:52:02 +0200 Subject: [PATCH 042/128] configure: simplify pthreads detection Also make `pthread_testlib` return success on success and failure on failure. --- configure | 93 +++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/configure b/configure index c7a1e266..7a905b66 100755 --- a/configure +++ b/configure @@ -183,61 +183,58 @@ testlib() { } pthread_testlib() { - - SYSTEM=`uname` - - if [ "${SYSTEM}" = "DragonFly" ] ; then - OSLIBS="${OSLIBS} -pthread" - TURN_NO_SCTP=1 + if [ -n "${PTHREAD_LIBS}" ] ; then + OSLIBS="${OSLIBS} ${PTHREAD_LIBS}" + return fi - ISBSD=`uname | grep -i bsd` - if ! [ -z "${ISBSD}" ] ; then - OSLIBS="${OSLIBS} -pthread" + if [ "$(uname)" = "DragonFly" ] ; then + OSLIBS="${OSLIBS} -pthread" + TURN_NO_SCTP=1 + return fi - if [ -z "${PTHREAD_LIBS}" ] ; then - ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} 2>>/dev/null - ER=$? - if [ ${ER} -eq 0 ] ; then - return 1 - else - ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -pthread 2>>/dev/null - ER=$? - if [ ${ER} -eq 0 ] ; then - OSLIBS="${OSLIBS} -pthread" - return 1 - else - ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -lpthread 2>>/dev/null - ER=$? - if [ ${ER} -eq 0 ] ; then - OSLIBS="${OSLIBS} -lpthread" - return 1 - fi - fi - fi - else - OSLIBS="${OSLIBS} ${PTHREAD_LIBS}" + if [ -n "$(uname | grep -i bsd)" ] ; then + OSLIBS="${OSLIBS} -pthread" + return fi - ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} 2>>/dev/null ER=$? if [ ${ER} -eq 0 ] ; then - return 1 - else - ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -D_GNU_SOURCE 2>>/dev/null - ER=$? - if [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Older GNU pthread library found" - OSCFLAGS="${OSCFLAGS} -D_GNU_SOURCE" - return 1 - else - ${ECHO_CMD} "Do not use pthreads" - fi + return fi - - return 0 + + ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -pthread 2>>/dev/null + ER=$? + if [ ${ER} -eq 0 ] ; then + OSLIBS="${OSLIBS} -pthread" + return + fi + + ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -lpthread 2>>/dev/null + ER=$? + if [ ${ER} -eq 0 ] ; then + OSLIBS="${OSLIBS} -lpthread" + return + fi + + ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} 2>>/dev/null + ER=$? + if [ ${ER} -eq 0 ] ; then + return + fi + + ${CC} ${TH_TMPCPROGC} -o ${TH_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -D_GNU_SOURCE 2>>/dev/null + ER=$? + if [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Older GNU pthread library found" + OSCFLAGS="${OSCFLAGS} -D_GNU_SOURCE" + return + fi + + ${ECHO_CMD} "Do not use pthreads" + return 1 } pthread_testbarriers() { @@ -887,9 +884,9 @@ test_sin_len pthread_testlib ER=$? -if [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "ERROR: Cannot find pthread library functions." - exit +if [ ${ER} -ne 0 ] ; then + ${ECHO_CMD} "ERROR: Cannot find pthread library functions." + exit fi if [ -z ${TURN_NO_THREAD_BARRIERS} ] ; then From 30acc0a5635eaae1c28aca2724de958e9c9c1edf Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Sat, 6 Oct 2018 19:39:25 +0100 Subject: [PATCH 043/128] configure: remove unnecessary include/library paths Everything should be provided by pkg-config now. --- configure | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/configure b/configure index 7a905b66..c5083e70 100755 --- a/configure +++ b/configure @@ -534,15 +534,8 @@ if [ -z "${MORECMD}" ]; then MORECMD="cat" fi -OSCFLAGS="-I${INCLUDEDIR} -I${PREFIX}/include/ -I/usr/local/include ${CFLAGS}" +OSCFLAGS="${CFLAGS}" OSLIBS="${LDFLAGS}" -for ilib in ${PREFIX}/lib/event2/ ${PREFIX}/lib/ /usr/local/lib/event2/ /usr/local/lib/ ${PREFIX}/lib64/event2/ ${PREFIX}/lib64/ /usr/local/lib64/event2/ /usr/local/lib64/ -do - if [ -d ${ilib} ] ; then - OSLIBS="${OSLIBS} -L${ilib}" - TURN_RPATH="${TURN_RPATH} -Wl,-rpath,${ilib}" - fi -done SYSTEM=`uname` if [ "${SYSTEM}" = "NetBSD" ] ; then From a6ee955e4476d3405f751cb0cd21b5abb73a5977 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 18:57:02 +0200 Subject: [PATCH 044/128] configure: add pkg-config helpers --- configure | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/configure b/configure index c5083e70..9bad90a1 100755 --- a/configure +++ b/configure @@ -38,6 +38,35 @@ testlibraw() { fi } +# testpkg pkg1 pkg2 ... +# If all libraries are found, sets PKG_CFLAGS/PKG_LIBS and returns success. +# Otherwise, returns failure. +testpkg() { + PKG_LIBS="$($PKGCONFIG --libs "$@" 2>/dev/null)" + if [ $? -ne 0 ] ; then + return 1 + fi + PKG_CFLAGS="$($PKGCONFIG --cflags "$@")" +} + +# testpkg_db pkg1 pkg2 ... +# If all libraries are found, adds them to DBCFLAGS/DBLIBS and returns success. +# Otherwise, returns failure. +testpkg_db() { + testpkg "$@" || return $? + DBCFLAGS="${DBCFLAGS} ${PKG_CFLAGS}" + DBLIBS="${DBLIBS} ${PKG_LIBS}" +} + +# testpkg_common pkg1 pkg2 ... +# If all libraries are found, adds them to OSCFLAGS/OSLIBS and returns success. +# Otherwise, returns failure. +testpkg_common() { + testpkg "$@" || return $? + OSCFLAGS="${OSCFLAGS} ${PKG_CFLAGS}" + OSLIBS="${OSLIBS} ${PKG_LIBS}" +} + testsqlite_comp() { SQLITE_LIBS=-lsqlite3 ${CC} -c ${SQL_TMPCPROGC} -o ${SQL_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null @@ -807,6 +836,33 @@ if [ -z "${TURN_ACCEPT_RPATH}" ] ; then fi fi +########################## +# Which pkg-config? +########################## + +if [ -z "$PKGCONFIG" ] ; then + for PKGCONFIG in pkgconf pkg-config ; do + if type "$PKGCONFIG" 2>/dev/null ; then + break + fi + PKGCONFIG= + done + + if [ -z "$PKGCONFIG" ] ; then + ${ECHO_CMD} "ERROR: pkg-config not found" + cleanup + exit + fi +else + if ! type "$PKGCONFIG" 2>/dev/null ; then + ${ECHO_CMD} "ERROR: cannot use $PKGCONFIG" + cleanup + exit + fi +fi + +${ECHO_CMD} "pkg-config: $PKGCONFIG" + ########################### # Check if we can use GNU # or Clang compiler flags From af437e6751a1208a24dc9ad3879446bcebf5f6b7 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:00:36 +0200 Subject: [PATCH 045/128] configure: use pkg-config for sqlite3 --- configure | 67 ++++++++----------------------------------------------- 1 file changed, 9 insertions(+), 58 deletions(-) diff --git a/configure b/configure index 9bad90a1..262e5769 100755 --- a/configure +++ b/configure @@ -17,8 +17,6 @@ cleanup() { rm -rf ${MONGO_TMPCPROGB} rm -rf ${D_TMPCPROGC} rm -rf ${D_TMPCPROGB} - rm -rf ${SQL_TMPCPROGC} - rm -rf ${SQL_TMPCPROGO} rm -rf ${E_TMPCPROGC} rm -rf ${E_TMPCPROGO} rm -rf ${HR_TMPCPROGC} @@ -67,19 +65,6 @@ testpkg_common() { OSLIBS="${OSLIBS} ${PKG_LIBS}" } -testsqlite_comp() { - SQLITE_LIBS=-lsqlite3 - ${CC} -c ${SQL_TMPCPROGC} -o ${SQL_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "SQLite development is not installed properly" - return 0 - else - DBLIBS="${DBLIBS} ${SQLITE_LIBS}" - return 1 - fi -} - testlibevent2_comp() { ${CC} -c ${E_TMPCPROGC} -o ${E_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null ER=$? @@ -732,18 +717,6 @@ int main(int argc, char** argv) { } ! -SQL_TMPCPROG=__test__ccomp__sqlite__$$ -SQL_TMPCPROGC=${TMPDIR}/${SQL_TMPCPROG}.c -SQL_TMPCPROGO=${TMPDIR}/${SQL_TMPCPROG}.o - -cat > ${SQL_TMPCPROGC} < -#include -int main(int argc, char** argv) { - return (int)(argv[argc][0]); -} -! - HR_TMPCPROG=__test__ccomp__hiredis__$$ HR_TMPCPROGC=${TMPDIR}/${HR_TMPCPROG}.c HR_TMPCPROGB=${TMPDIR}/${HR_TMPCPROG} @@ -1143,41 +1116,19 @@ else fi ########################### -# Test SQLite setup +# Test SQLite3 setup ########################### if [ -z "${TURN_NO_SQLITE}" ] ; then - - testlib sqlite3 - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "SQLite library found." - else - ${ECHO_CMD} "SQLite3 development library cannot be found." - TURN_NO_SQLITE="-DTURN_NO_SQLITE" - fi - - if [ -z "${TURN_NO_SQLITE}" ] ; then - testsqlite_comp - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "SQLite development found." - else - ${ECHO_CMD} "SQLite development libraries are not installed properly in required location." - TURN_NO_SQLITE="-DTURN_NO_SQLITE" - fi - fi - - if ! [ -z "${TURN_NO_SQLITE}" ] ; then - ${ECHO_CMD} - ${ECHO_CMD} "SQLite DEVELOPMENT LIBRARY (libsqlite3) AND/OR HEADER (sqlite3.h)" - ${ECHO_CMD} " ARE NOT INSTALLED PROPERLY ON THIS SYSTEM." - ${ECHO_CMD} " THAT'S OK BUT THE TURN SERVER IS BUILDING WITHOUT SQLITE SUPPORT." - ${ECHO_CMD} - fi + if testpkg_db sqlite3; then + ${ECHO_CMD} "SQLite3 library found." + else + ${ECHO_CMD} "SQLite3 development library not found. Building without SQLite3 support." + TURN_NO_SQLITE="-DTURN_NO_SQLITE" + fi else - TURN_NO_SQLITE="-DTURN_NO_SQLITE" - SQLITE_CMD=${ECHO_CMD} + TURN_NO_SQLITE="-DTURN_NO_SQLITE" + SQLITE_CMD=${ECHO_CMD} fi if [ -z "${TURNDBDIR}" ] ; then From e7940bb849eac4486800b4e021a8f4ebf644cfcc Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:02:53 +0200 Subject: [PATCH 046/128] configure: use pkg-config for hiredis --- configure | 61 +++++++------------------------------------------------ 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/configure b/configure index 262e5769..3da209aa 100755 --- a/configure +++ b/configure @@ -19,8 +19,6 @@ cleanup() { rm -rf ${D_TMPCPROGB} rm -rf ${E_TMPCPROGC} rm -rf ${E_TMPCPROGO} - rm -rf ${HR_TMPCPROGC} - rm -rf ${HR_TMPCPROGB} rm -rf ${TMPCADDRPROGO} } @@ -76,32 +74,6 @@ testlibevent2_comp() { fi } -testhiredis() { - if [ -z "${HIREDIS_CFLAGS}" ] || [ -z "${HIREDIS_LIBS}" ]; then - for inc in ${INCLUDEDIR}/hiredis /usr/local/include/hiredis /usr/hiredis /usr/include/hiredis - do - if [ -d ${inc} ] ; then - HIREDIS_CFLAGS="${HIREDIS_CFLAGS} -I${inc}" - fi - done - HIREDIS_LIBS=-lhiredis - fi - ${CC} ${HR_TMPCPROGC} -o ${HR_TMPCPROGB} ${OSCFLAGS} ${DBLIBS} ${HIREDIS_CFLAGS} ${HIREDIS_LIBS} ${OSLIBS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} - ${ECHO_CMD} "HIREDIS DEVELOPMENT LIBRARY (libhiredis.*) AND/OR HEADERS (hiredis/*.h)" - ${ECHO_CMD} " ARE NOT INSTALLED PROPERLY ON THIS SYSTEM." - ${ECHO_CMD} " THAT'S OK BUT THE TURN SERVER IS BUILDING WITHOUT REDIS SUPPORT." - ${ECHO_CMD} - return 0 - else - DBCFLAGS="${DBCFLAGS} ${HIREDIS_CFLAGS}" - DBLIBS="${DBLIBS} ${HIREDIS_LIBS}" - return 1 - fi -} - testlibpq() { if [ -z "${PSQL_CFLAGS}" ] || [ -z "${PSQL_LIBS}" ]; then PSQL_CFLAGS="-I${PREFIX}/pgsql/include -I${PREFIX}/include/pgsql/ -I${PREFIX}/include/postgres/ -I${PREFIX}/postgres/include/ -I${PREFIX}/include/postgresql/ -I${PREFIX}/postgresql/include/" @@ -717,20 +689,6 @@ int main(int argc, char** argv) { } ! -HR_TMPCPROG=__test__ccomp__hiredis__$$ -HR_TMPCPROGC=${TMPDIR}/${HR_TMPCPROG}.c -HR_TMPCPROGB=${TMPDIR}/${HR_TMPCPROG} - -cat > ${HR_TMPCPROGC} < -#include -#include -int main(int argc, char** argv) { - redisAsyncHandleRead(NULL); - return (int)(argv[argc][0]); -} -! - PQ_TMPCPROG=__test__ccomp__libpq__$$ PQ_TMPCPROGC=${TMPDIR}/${PQ_TMPCPROG}.c PQ_TMPCPROGB=${TMPDIR}/${PQ_TMPCPROG} @@ -1191,19 +1149,14 @@ fi ########################### if [ -z "${TURN_NO_HIREDIS}" ] ; then - - testhiredis - - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Hiredis found." - else - TURN_NO_HIREDIS="-DTURN_NO_HIREDIS" - fi - + if testpkg_db hiredis; then + ${ECHO_CMD} "Hiredis found." + else + ${ECHO_CMD} "Hiredis not found. Building without hiredis support." + TURN_NO_HIREDIS="-DTURN_NO_HIREDIS" + fi else - TURN_NO_HIREDIS="-DTURN_NO_HIREDIS" - + TURN_NO_HIREDIS="-DTURN_NO_HIREDIS" fi ############################### From 651ea27ebf0c77ed6131c85acb2cbaeef36d1fcc Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:06:41 +0200 Subject: [PATCH 047/128] configure: use pkg-config for postgresql --- configure | 62 +++++++------------------------------------------------ 1 file changed, 7 insertions(+), 55 deletions(-) diff --git a/configure b/configure index 3da209aa..948a6930 100755 --- a/configure +++ b/configure @@ -9,8 +9,6 @@ cleanup() { rm -rf ${TH_TMPCPROGB} rm -rf ${GCM_TMPCPROGC} rm -rf ${GCM_TMPCPROGB} - rm -rf ${PQ_TMPCPROGC} - rm -rf ${PQ_TMPCPROGB} rm -rf ${MYSQL_TMPCPROGC} rm -rf ${MYSQL_TMPCPROGB} rm -rf ${MONGO_TMPCPROGC} @@ -74,38 +72,6 @@ testlibevent2_comp() { fi } -testlibpq() { - if [ -z "${PSQL_CFLAGS}" ] || [ -z "${PSQL_LIBS}" ]; then - PSQL_CFLAGS="-I${PREFIX}/pgsql/include -I${PREFIX}/include/pgsql/ -I${PREFIX}/include/postgres/ -I${PREFIX}/postgres/include/ -I${PREFIX}/include/postgresql/ -I${PREFIX}/postgresql/include/" - PSQL_CFLAGS="${PSQL_CFLAGS} -I/usr/local/pgsql/include -I/usr/local/include/pgsql/ -I/usr/local/include/postgres/ -I/usr/local/postgres/include/ -I/usr/local/include/postgresql/ -I/usr/local/postgresql/include/" - PSQL_CFLAGS="${PSQL_CFLAGS} -I/usr/pgsql/include -I/usr/include/pgsql/ -I/usr/include/postgres/ -I/usr/postgres/include/ -I/usr/include/postgresql/ -I/usr/postgresql/include/" - for ilib in ${PREFIX}/pgsql/lib ${PREFIX}/lib/pgsql ${PREFIX}/lib64/pgsql /usr/local/pgsql/lib /usr/local/lib/pgsql /usr/local/lib64/pgsql /usr/pgsql/lib /usr/lib/pgsql /usr/lib64/pgsql ${PREFIX}/postgres/lib ${PREFIX}/lib/postgres ${PREFIX}/lib64/postgres /usr/local/postgres/lib /usr/local/lib/postgres /usr/local/lib64/postgres /usr/postgres/lib /usr/lib/postgres /usr/lib64/postgres ${PREFIX}/postgresql/lib ${PREFIX}/lib/postgresql ${PREFIX}/lib64/postgresql /usr/local/postgresql/lib /usr/local/lib/postgresql /usr/local/lib64/postgresql /usr/postgresql/lib /usr/lib/postgresql /usr/lib64/postgresql - do - if [ -d ${ilib} ] ; then - PSQL_LIBS="${PSQL_LIBS} -L${ilib}" - if ! [ -z "${TURN_ACCEPT_RPATH}" ] ; then - TURN_RPATH="${TURN_RPATH} -Wl,-rpath,${ilib}" - fi - fi - done - PSQL_LIBS="${OSLIBS} ${PSQL_LIBS} -lpq" - fi - ${CC} ${PQ_TMPCPROGC} -o ${PQ_TMPCPROGB} ${OSCFLAGS} ${DBCFLAGS} ${PSQL_CFLAGS} ${DBLIBS} ${PSQL_LIBS} ${OSLIBS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} - ${ECHO_CMD} "POSTGRESQL DEVELOPMENT LIBRARY (libpq.a) AND/OR HEADER (libpq-fe.h)" - ${ECHO_CMD} " ARE NOT INSTALLED PROPERLY ON THIS SYSTEM." - ${ECHO_CMD} " THAT'S OK BUT THE TURN SERVER IS BUILDING WITHOUT POSTGRESQL DATABASE SUPPORT." - ${ECHO_CMD} - return 0 - else - DBCFLAGS="${DBCFLAGS} ${PSQL_CFLAGS}" - DBLIBS="${DBLIBS} ${PSQL_LIBS}" - return 1 - fi -} - testlibmysql() { if [ -z "${MYSQL_CFLAGS}" ] || [ -z "${MYSQL_LIBS}" ]; then MYSQL_CFLAGS="-I${PREFIX}/mysql/include -I${PREFIX}/include/mysql/" @@ -689,18 +655,6 @@ int main(int argc, char** argv) { } ! -PQ_TMPCPROG=__test__ccomp__libpq__$$ -PQ_TMPCPROGC=${TMPDIR}/${PQ_TMPCPROG}.c -PQ_TMPCPROGB=${TMPDIR}/${PQ_TMPCPROG} - -cat > ${PQ_TMPCPROGC} < -#include -int main(int argc, char** argv) { - return (argc+(PQprotocolVersion(NULL))+(int)(argv[0][0])); -} -! - MYSQL_TMPCPROG=__test__ccomp__libmysql__$$ MYSQL_TMPCPROGC=${TMPDIR}/${MYSQL_TMPCPROG}.c MYSQL_TMPCPROGB=${TMPDIR}/${MYSQL_TMPCPROG} @@ -1098,16 +1052,14 @@ fi ########################### if [ -z "${TURN_NO_PQ}" ] ; then - - testlibpq - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "PostgreSQL found." - else - TURN_NO_PQ="-DTURN_NO_PQ" - fi + if testpkg_db libpq; then + ${ECHO_CMD} "PostgreSQL found." + else + ${ECHO_CMD} "PostgreSQL not found. Building without PostgreSQL support." + TURN_NO_PQ="-DTURN_NO_PQ" + fi else - TURN_NO_PQ="-DTURN_NO_PQ" + TURN_NO_PQ="-DTURN_NO_PQ" fi ########################### From 92d7a114a760851af307eaf98674f3243c3e9586 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:12:11 +0200 Subject: [PATCH 048/128] configure: use pkg-config for libevent --- configure | 85 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 83 deletions(-) diff --git a/configure b/configure index 948a6930..887de9e3 100755 --- a/configure +++ b/configure @@ -15,8 +15,6 @@ cleanup() { rm -rf ${MONGO_TMPCPROGB} rm -rf ${D_TMPCPROGC} rm -rf ${D_TMPCPROGB} - rm -rf ${E_TMPCPROGC} - rm -rf ${E_TMPCPROGO} rm -rf ${TMPCADDRPROGO} } @@ -61,17 +59,6 @@ testpkg_common() { OSLIBS="${OSLIBS} ${PKG_LIBS}" } -testlibevent2_comp() { - ${CC} -c ${E_TMPCPROGC} -o ${E_TMPCPROGO} ${OSCFLAGS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 development is not installed properly" - return 0 - else - return 1 - fi -} - testlibmysql() { if [ -z "${MYSQL_CFLAGS}" ] || [ -z "${MYSQL_LIBS}" ]; then MYSQL_CFLAGS="-I${PREFIX}/mysql/include -I${PREFIX}/include/mysql/" @@ -643,18 +630,6 @@ int main(int argc, char** argv) { } ! -E_TMPCPROG=__test__ccomp__libevent2__$$ -E_TMPCPROGC=${TMPDIR}/${E_TMPCPROG}.c -E_TMPCPROGO=${TMPDIR}/${E_TMPCPROG}.o - -cat > ${E_TMPCPROGC} < -#include -int main(int argc, char** argv) { - return (int)(argv[argc][0]); -} -! - MYSQL_TMPCPROG=__test__ccomp__libmysql__$$ MYSQL_TMPCPROGC=${TMPDIR}/${MYSQL_TMPCPROG}.c MYSQL_TMPCPROGB=${TMPDIR}/${MYSQL_TMPCPROG} @@ -912,10 +887,8 @@ if [ -n "${EVENT_CFLAGS}" ] && [ -n "${EVENT_LIBS}" ]; then OSLIBS="${OSLIBS} ${EVENT_LIBS}" fi else - testlibevent2_comp - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 development found." + if testpkg_common libevent_core libevent_extra libevent_openssl libevent_pthreads || testpkg_common libevent libevent_openssl libevent_pthreads; then + ${ECHO_CMD} "Libevent2 runtime found." else ${ECHO_CMD} "ERROR: Libevent2 development libraries are not installed properly in required location." ${ECHO_CMD} "ERROR: may be you have just too old libevent tool - then you have to upgrade it." @@ -924,60 +897,6 @@ else cleanup exit fi - - testlib event_core - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 runtime found." - testlib event_extra - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 runtime 'extra' found." - else - ${ECHO_CMD} "ERROR: Libevent2 'extra' runtime library is not installed properly in required location." - ${ECHO_CMD} "See the INSTALL file." - ${ECHO_CMD} "Abort." - cleanup - exit - fi - else - testlib event - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 runtime found (old style)." - else - ${ECHO_CMD} "ERROR: Libevent2 runtime libraries are not installed properly in required location." - ${ECHO_CMD} "See the INSTALL file." - ${ECHO_CMD} "Abort." - cleanup - exit - fi - fi - - if [ -z "${TURN_NO_TLS}" ] ; then - - testlib event_openssl - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 openssl found." - else - ${ECHO_CMD} "ERROR: Libevent2 development libraries are not compiled with OpenSSL support." - ${ECHO_CMD} "TLS will be disabled." - TURN_NO_TLS="-DTURN_NO_TLS" - fi - - else - TURN_NO_TLS="-DTURN_NO_TLS" - fi - - testlib event_pthreads - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Libevent2 pthreads found." - else - ${ECHO_CMD} "ERROR: Libevent2 development libraries are not compiled with threads support." - exit - fi fi ########################### From 29b5e23f0559744d7b2996153ee5496ce0b2e622 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:14:15 +0200 Subject: [PATCH 049/128] configure: use pkg-config for mysql --- configure | 64 ++++++------------------------------------------------- 1 file changed, 7 insertions(+), 57 deletions(-) diff --git a/configure b/configure index 887de9e3..4e917b6f 100755 --- a/configure +++ b/configure @@ -9,8 +9,6 @@ cleanup() { rm -rf ${TH_TMPCPROGB} rm -rf ${GCM_TMPCPROGC} rm -rf ${GCM_TMPCPROGB} - rm -rf ${MYSQL_TMPCPROGC} - rm -rf ${MYSQL_TMPCPROGB} rm -rf ${MONGO_TMPCPROGC} rm -rf ${MONGO_TMPCPROGB} rm -rf ${D_TMPCPROGC} @@ -59,38 +57,6 @@ testpkg_common() { OSLIBS="${OSLIBS} ${PKG_LIBS}" } -testlibmysql() { - if [ -z "${MYSQL_CFLAGS}" ] || [ -z "${MYSQL_LIBS}" ]; then - MYSQL_CFLAGS="-I${PREFIX}/mysql/include -I${PREFIX}/include/mysql/" - MYSQL_CFLAGS="${MYSQL_CFLAGS} -I/usr/local/mysql/include -I/usr/local/include/mysql/" - MYSQL_CFLAGS="${MYSQL_CFLAGS} -I/usr/mysql/include -I/usr/include/mysql/" - for ilib in ${PREFIX}/mysql/lib ${PREFIX}/lib/mysql ${PREFIX}/lib64/mysql /usr/local/mysql/lib /usr/local/lib/mysql /usr/local/lib64/mysql /usr/mysql/lib /usr/lib/mysql /usr/lib64/mysql - do - if [ -d ${ilib} ] ; then - MYSQL_LIBS="${MYSQL_LIBS} -L${ilib}" - if ! [ -z "${TURN_ACCEPT_RPATH}" ] ; then - TURN_RPATH="${TURN_RPATH} -Wl,-rpath,${ilib}" - fi - fi - done - MYSQL_LIBS="${OSLIBS} ${MYSQL_LIBS} -lmysqlclient" - fi - ${CC} ${MYSQL_TMPCPROGC} -o ${MYSQL_TMPCPROGB} ${OSCFLAGS} ${DBCFLAGS} ${DBLIBS} ${MYSQL_CFLAGS} ${MYSQL_LIBS} ${OSLIBS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} - ${ECHO_CMD} "MYSQL DEVELOPMENT LIBRARY (libmysqlclient) AND/OR HEADER (mysql.h)" - ${ECHO_CMD} " ARE NOT INSTALLED PROPERLY ON THIS SYSTEM." - ${ECHO_CMD} " THAT'S OK BUT THE TURN SERVER IS BUILDING WITHOUT MYSQL DATABASE SUPPORT." - ${ECHO_CMD} - return 0 - else - DBCFLAGS="${DBCFLAGS} ${MYSQL_CFLAGS}" - DBLIBS="${DBLIBS} ${MYSQL_LIBS}" - return 1 - fi -} - testlibmongoc() { if [ -z "${MONGO_CFLAGS}" ] || [ -z "${MONGO_LIBS}" ]; then for inc in ${INCLUDEDIR}/libmongoc-1.0 ${INCLUDEDIR}/libbson-1.0 /usr/local/include/libmongoc-1.0 /usr/local/include/libbson-1.0 /usr/libmongoc-1.0 /usr/libbson-1.0 /usr/include/libbson-1.0/ /usr/include/libmongoc-1.0/ @@ -630,20 +596,6 @@ int main(int argc, char** argv) { } ! -MYSQL_TMPCPROG=__test__ccomp__libmysql__$$ -MYSQL_TMPCPROGC=${TMPDIR}/${MYSQL_TMPCPROG}.c -MYSQL_TMPCPROGB=${TMPDIR}/${MYSQL_TMPCPROG} - -cat > ${MYSQL_TMPCPROGC} < -#include -int main(int argc, char** argv) { - return (argc+ - (int)(mysql_real_connect(NULL, NULL, NULL, NULL, NULL, 0, NULL, 0)!=0)+ - (int)(argv[0][0])); -} -! - MONGO_TMPCPROG=__test__ccomp__libmongoc__$$ MONGO_TMPCPROGC=${TMPDIR}/${MONGO_TMPCPROG}.c MONGO_TMPCPROGB=${TMPDIR}/${MONGO_TMPCPROG} @@ -986,16 +938,14 @@ fi ########################### if [ -z "${TURN_NO_MYSQL}" ] ; then - - testlibmysql - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "MySQL found." - else - TURN_NO_MYSQL="-DTURN_NO_MYSQL" - fi + if testpkg_server mariadb || testpkg_server mysqlclient ; then + ${ECHO_CMD} "MySQL found." + else + ${ECHO_CMD} "MySQL not found. Building without MySQL support." + TURN_NO_MYSQL="-DTURN_NO_MYSQL" + fi else - TURN_NO_MYSQL="-DTURN_NO_MYSQL" + TURN_NO_MYSQL="-DTURN_NO_MYSQL" fi ########################### From 63e5f078b439c09b7a0cc90b04c33e8056f42e47 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:15:45 +0200 Subject: [PATCH 050/128] configure: use pkg-config for mongodb --- configure | 57 +++++++------------------------------------------------ 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/configure b/configure index 4e917b6f..b7973fdd 100755 --- a/configure +++ b/configure @@ -9,8 +9,6 @@ cleanup() { rm -rf ${TH_TMPCPROGB} rm -rf ${GCM_TMPCPROGC} rm -rf ${GCM_TMPCPROGB} - rm -rf ${MONGO_TMPCPROGC} - rm -rf ${MONGO_TMPCPROGB} rm -rf ${D_TMPCPROGC} rm -rf ${D_TMPCPROGB} rm -rf ${TMPCADDRPROGO} @@ -57,32 +55,6 @@ testpkg_common() { OSLIBS="${OSLIBS} ${PKG_LIBS}" } -testlibmongoc() { - if [ -z "${MONGO_CFLAGS}" ] || [ -z "${MONGO_LIBS}" ]; then - for inc in ${INCLUDEDIR}/libmongoc-1.0 ${INCLUDEDIR}/libbson-1.0 /usr/local/include/libmongoc-1.0 /usr/local/include/libbson-1.0 /usr/libmongoc-1.0 /usr/libbson-1.0 /usr/include/libbson-1.0/ /usr/include/libmongoc-1.0/ - do - if [ -d ${inc} ] ; then - MONGO_CFLAGS="${MONGO_CFLAGS} -I${inc}" - fi - done - MONGO_LIBS="-lmongoc-1.0 -lbson-1.0" - fi - ${CC} ${MONGO_TMPCPROGC} -o ${MONGO_TMPCPROGB} ${OSCFLAGS} ${DBCFLAGS} ${DBLIBS} ${MONGO_CFLAGS} ${MONGO_LIBS} ${OSLIBS} 2>>/dev/null - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} - ${ECHO_CMD} "MONGODB DEVELOPMENT LIBRARIES (libmongoc-1.0 and libbson-1.0) AND/OR HEADER (mongoc.h)" - ${ECHO_CMD} " ARE NOT INSTALLED PROPERLY ON THIS SYSTEM." - ${ECHO_CMD} " THAT'S OK BUT THE TURN SERVER IS BUILDING WITHOUT MONGODB SUPPORT." - ${ECHO_CMD} - return 0 - else - DBCFLAGS="${DBCFLAGS} ${MONGO_CFLAGS}" - DBLIBS="${DBLIBS} ${MONGO_LIBS}" - return 1 - fi -} - testlib() { testlibraw l${1} } @@ -596,19 +568,6 @@ int main(int argc, char** argv) { } ! -MONGO_TMPCPROG=__test__ccomp__libmongoc__$$ -MONGO_TMPCPROGC=${TMPDIR}/${MONGO_TMPCPROG}.c -MONGO_TMPCPROGB=${TMPDIR}/${MONGO_TMPCPROG} - -cat > ${MONGO_TMPCPROGC} < -int main(int argc, char** argv) { - return (argc+ - (int)(mongoc_client_new("mongodb://localhost:27017")!=0)+ - (int)(argv[0][0])); -} -! - ########################## # What is our compiler ? ########################## @@ -953,16 +912,14 @@ fi ########################### if [ -z "${TURN_NO_MONGO}" ] ; then - - testlibmongoc - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "MongoDB found." - else - TURN_NO_MONGO="-DTURN_NO_MONGO" - fi + if testpkg_server libmongoc-1.0; then + ${ECHO_CMD} "MongoDB found." + else + ${ECHO_CMD} "MongoDB not found. Building without MongoDB support." + TURN_NO_MONGO="-DTURN_NO_MONGO" + fi else - TURN_NO_MONGO="-DTURN_NO_MONGO" + TURN_NO_MONGO="-DTURN_NO_MONGO" fi ########################### From 40b39e2392af5483e9b4afda91aab663cb753c22 Mon Sep 17 00:00:00 2001 From: Hristo Venev Date: Mon, 26 Oct 2020 19:19:32 +0200 Subject: [PATCH 051/128] configure: use pkg-config for openssl --- configure | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/configure b/configure index b7973fdd..0ecff739 100755 --- a/configure +++ b/configure @@ -744,10 +744,8 @@ if [ -n "${SSL_CFLAGS}" ] && [ -n "${SSL_LIBS}" ]; then OSLIBS="${OSLIBS} ${SSL_LIBS}" fi else - testlib crypto - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Crypto SSL lib found." + if testpkg_common libcrypto; then + ${ECHO_CMD} "OpenSSL Crypto lib found." else ${ECHO_CMD} "ERROR: OpenSSL Crypto development libraries are not installed properly in required location." ${ECHO_CMD} "Abort." @@ -755,10 +753,8 @@ else exit fi - testlib ssl - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "SSL lib found." + if testpkg_common libssl; then + ${ECHO_CMD} "OpenSSL lib found." else ${ECHO_CMD} "ERROR: OpenSSL development libraries are not installed properly in required location." ${ECHO_CMD} "Abort." From a83bffd9426baf033b57ea01261b712a3e5480df Mon Sep 17 00:00:00 2001 From: Robert Tupelo-Schneck Date: Fri, 30 Oct 2020 12:34:31 -0400 Subject: [PATCH 052/128] Allow RFC6062 TCP relay data to look like TLS; fixes #605 --- src/apps/relay/ns_ioalib_engine_impl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index ba1e387f..de31bf42 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3374,7 +3374,7 @@ int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, in } } else { #if TLS_SUPPORTED - if(check_tentative_tls(s->fd)) { + if((s->sat != TCP_CLIENT_DATA_SOCKET) && (s->sat != TCP_RELAY_DATA_SOCKET) && check_tentative_tls(s->fd)) { s->tobeclosed = 1; return -1; } From c00d69e67f7161ab96b5df4fa35970d44bad3e0e Mon Sep 17 00:00:00 2001 From: Peter Linss Date: Wed, 18 Nov 2020 16:43:24 -0800 Subject: [PATCH 053/128] Add support for proxy protocol V1 --- src/apps/relay/ns_ioalib_engine_impl.c | 107 ++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index ba1e387f..2eb1b30b 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -2166,6 +2166,101 @@ static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd) } #endif + +static size_t proxy_string_field(char *field, size_t max, uint8_t *buf, size_t index, size_t len) +{ + size_t count = 0; + while((index < len) && (count < max)) { + if((0x20 == buf[index]) || (0x0D == buf[index])) { + field[count] = 0x00; + return ++index; + } + field[count++] = buf[index++]; + } + return 0; +} + +static ssize_t socket_parse_proxy_v1(ioa_socket_handle s, uint8_t *buf, size_t len) +{ + if(len < 11) { + return 0 ; + } + + /* Check for proxy-v1 magic field */ + char magic[] = {0x50, 0x52, 0x4F, 0x58, 0x59, 0x20}; + if(memcmp(magic, buf, sizeof(magic))) { + return -1; + } + + /* Read family */ + char tcp4[] = {0x54, 0x43, 0x50, 0x34, 0x20}; + char tcp6[] = {0x54, 0x43, 0x50, 0x36, 0x20}; + int family; + if(0 == memcmp(tcp4, &buf[6], sizeof(tcp4))) { /* IPv4 */ + family = AF_INET; + } else if(0 == memcmp(tcp6, &buf[6], sizeof(tcp6))) { /* IPv6 */ + family = AF_INET6; + } else { + return -1; + } + + char saddr[40]; + char daddr[40]; + char sport[6]; + char dport[6]; + + size_t tlen = 11; + /* Read source address */ + tlen = proxy_string_field(saddr, sizeof(saddr), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read dest address */ + tlen = proxy_string_field(daddr, sizeof(daddr), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read source port */ + tlen = proxy_string_field(sport, sizeof(sport), buf, tlen, len); + if(0 == tlen) return -1; + + /* Read dest port */ + tlen = proxy_string_field(dport, sizeof(dport), buf, tlen, len); + if(0 == tlen) return -1; + + /* Final line feed */ + if ((len <= tlen) || (0x0A != buf[tlen])) return -1; + + tlen++; + + int sport_int = atoi(sport); + int dport_int = atoi(dport); + if((sport_int < 0) || (0xFFFF < sport_int)) return -1; + if((dport_int < 0) || (0xFFFF < dport_int)) return -1; + + if (AF_INET == family) { + struct sockaddr_in remote, local; + remote.sin_family = local.sin_family = AF_INET; + if(1 != inet_pton(AF_INET, saddr, &remote.sin_addr.s_addr)) return -1; + if(1 != inet_pton(AF_INET, daddr, &local.sin_addr.s_addr)) return -1; + remote.sin_port = htons((uint16_t)sport_int); + local.sin_port = htons((uint16_t)dport_int); + + addr_cpy4(&(s->local_addr), &local); + addr_cpy4(&(s->remote_addr), &remote); + + } else { + struct sockaddr_in6 remote, local; + remote.sin6_family = local.sin6_family = AF_INET6; + if(1 != inet_pton(AF_INET6, saddr, &remote.sin6_addr.s6_addr)) return -1; + if(1 != inet_pton(AF_INET6, daddr, &local.sin6_addr.s6_addr)) return -1; + remote.sin6_port = htons((uint16_t)sport_int); + local.sin6_port = htons((uint16_t)dport_int); + + addr_cpy6(&(s->local_addr), &local); + addr_cpy6(&(s->remote_addr), &remote); + } + return tlen; +} + static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len) { if(len < 16){ @@ -2227,6 +2322,16 @@ static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t l return tlen; } +static ssize_t socket_parse_proxy(ioa_socket_handle s, uint8_t *buf, size_t len) +{ + ssize_t tlen = socket_parse_proxy_v2(s, buf, len); + if(-1 == tlen) { + tlen = socket_parse_proxy_v1(s, buf, len); + } + + return tlen; +} + static int socket_input_worker(ioa_socket_handle s) { int len = 0; @@ -2450,7 +2555,7 @@ static int socket_input_worker(ioa_socket_handle s) blen=(ev_ssize_t)STUN_BUFFER_SIZE; if(s->st == TCP_SOCKET_PROXY){ - ssize_t tlen = socket_parse_proxy_v2(s, buf_elem->buf.buf, blen); + ssize_t tlen = socket_parse_proxy(s, buf_elem->buf.buf, blen); blen = 0; if (tlen < 0){ s->tobeclosed = 1; From ff5e5478a3e1b426bad053828099403cfc5c1f5f Mon Sep 17 00:00:00 2001 From: Sandro Gauci Date: Mon, 30 Nov 2020 14:02:35 +0100 Subject: [PATCH 054/128] ioa_addr_is_loopback now covers 0.0.0.0/8 --- src/client/ns_turn_ioaddr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index 5740e7c8..28a31c8a 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -480,7 +480,7 @@ int ioa_addr_is_loopback(ioa_addr *addr) if(addr) { if(addr->ss.sa_family == AF_INET) { const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); - return (u[0] == 127); + return (u[0] == 127 || u[0] == 0); } else if(addr->ss.sa_family == AF_INET6) { const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); if(u[7] == 1) { From af50d63a152cd9505d38f02bc552848748805e7b Mon Sep 17 00:00:00 2001 From: Sandro Gauci Date: Mon, 30 Nov 2020 14:04:27 +0100 Subject: [PATCH 055/128] ioa_addr_is_loopback ipv6 now properly blocks ::1 --- src/client/ns_turn_ioaddr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index 28a31c8a..e917ef8a 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -483,9 +483,9 @@ int ioa_addr_is_loopback(ioa_addr *addr) return (u[0] == 127 || u[0] == 0); } else if(addr->ss.sa_family == AF_INET6) { const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - if(u[7] == 1) { + if(u[15] == 1) { int i; - for(i=0;i<7;++i) { + for(i=0;i<15;++i) { if(u[i]) return 0; } From 6c774b9fb8d9d76576ece10a6429172ed3800466 Mon Sep 17 00:00:00 2001 From: Sandro Gauci Date: Mon, 30 Nov 2020 14:05:22 +0100 Subject: [PATCH 056/128] ioa_addr_is_loopback now also covers :: --- src/client/ns_turn_ioaddr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index e917ef8a..4d2be204 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -483,7 +483,7 @@ int ioa_addr_is_loopback(ioa_addr *addr) return (u[0] == 127 || u[0] == 0); } else if(addr->ss.sa_family == AF_INET6) { const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - if(u[15] == 1) { + if(u[15] == 1 || u[15] == 0) { int i; for(i=0;i<15;++i) { if(u[i]) From 560684c894498285f9e4271f3c924ebf01f36307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 08:31:43 +0100 Subject: [PATCH 057/128] Tidy: Move zero check to own function --- src/client/ns_turn_ioaddr.c | 25 +++++++++++++++++++++++-- src/client/ns_turn_ioaddr.h | 1 + src/server/ns_turn_server.c | 2 +- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index 4d2be204..86b96886 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -480,10 +480,31 @@ int ioa_addr_is_loopback(ioa_addr *addr) if(addr) { if(addr->ss.sa_family == AF_INET) { const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); - return (u[0] == 127 || u[0] == 0); + return (u[0] == 127); } else if(addr->ss.sa_family == AF_INET6) { const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - if(u[15] == 1 || u[15] == 0) { + if(u[15] == 1) { + int i; + for(i=0;i<15;++i) { + if(u[i]) + return 0; + } + return 1; + } + } + } + return 0; +} + +int ioa_addr_is_zero(ioa_addr *addr) +{ + if(addr) { + if(addr->ss.sa_family == AF_INET) { + const uint8_t *u = ((const uint8_t*)&(addr->s4.sin_addr)); + return (u[0] == 0); + } else if(addr->ss.sa_family == AF_INET6) { + const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); + if(u[15] == 0) { int i; for(i=0;i<15;++i) { if(u[i]) diff --git a/src/client/ns_turn_ioaddr.h b/src/client/ns_turn_ioaddr.h index a83d0fab..bdd21dd7 100644 --- a/src/client/ns_turn_ioaddr.h +++ b/src/client/ns_turn_ioaddr.h @@ -89,6 +89,7 @@ void ioa_addr_range_cpy(ioa_addr_range* dest, const ioa_addr_range* src); int ioa_addr_is_multicast(ioa_addr *a); int ioa_addr_is_loopback(ioa_addr *addr); +int ioa_addr_is_zero(ioa_addr *addr); /////// Map "public" address to "private" address ////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 38a15134..bf8e279e 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -271,7 +271,7 @@ static int good_peer_addr(turn_turnserver *server, const char* realm, ioa_addr * if(server && peer_addr) { if(*(server->no_multicast_peers) && ioa_addr_is_multicast(peer_addr)) return 0; - if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr)) + if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr) && ioa_addr_is_zero(peer_addr)) return 0; { From 649cbf966181846ecdd7847e4543dd287a78d295 Mon Sep 17 00:00:00 2001 From: Sandro Gauci Date: Mon, 7 Dec 2020 12:27:25 +0100 Subject: [PATCH 058/128] fixed logic for banning loopback and zero addr --- src/server/ns_turn_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index bf8e279e..9f1e4ef1 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -271,7 +271,7 @@ static int good_peer_addr(turn_turnserver *server, const char* realm, ioa_addr * if(server && peer_addr) { if(*(server->no_multicast_peers) && ioa_addr_is_multicast(peer_addr)) return 0; - if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr) && ioa_addr_is_zero(peer_addr)) + if( !*(server->allow_loopback_peers) && (ioa_addr_is_loopback(peer_addr) || ioa_addr_is_zero(peer_addr))) return 0; { From 9c7deff4b8ed8c323c87b9ede75481bd6bc3154d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 14:28:23 +0100 Subject: [PATCH 059/128] Separate addr zero check from allow_loopback_peers --- src/server/ns_turn_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 9f1e4ef1..2d2ef00b 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -271,7 +271,9 @@ static int good_peer_addr(turn_turnserver *server, const char* realm, ioa_addr * if(server && peer_addr) { if(*(server->no_multicast_peers) && ioa_addr_is_multicast(peer_addr)) return 0; - if( !*(server->allow_loopback_peers) && (ioa_addr_is_loopback(peer_addr) || ioa_addr_is_zero(peer_addr))) + if( !*(server->allow_loopback_peers) && ioa_addr_is_loopback(peer_addr)) + return 0; + if (ioa_addr_is_zero(peer_addr)) return 0; { From 3b3c5849cc276da9447287a1548a1f63bc0265e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:26:00 +0100 Subject: [PATCH 060/128] bump version --- examples/scripts/pack.sh | 2 +- rpm/build.settings.sh | 2 +- rpm/turnserver.spec | 2 +- src/ns_turn_defs.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/scripts/pack.sh b/examples/scripts/pack.sh index d86f10df..4d3cc98e 100755 --- a/examples/scripts/pack.sh +++ b/examples/scripts/pack.sh @@ -2,7 +2,7 @@ # Run it from the root of the coturn source tree -V=4.5.1.3 +V=4.5.2 PACKDIR=`pwd`/../coturn-releases/ SRCDIR=`pwd` diff --git a/rpm/build.settings.sh b/rpm/build.settings.sh index 19a39c12..7d3397af 100755 --- a/rpm/build.settings.sh +++ b/rpm/build.settings.sh @@ -2,7 +2,7 @@ # Common settings script. -TURNVERSION=4.5.1.3 +TURNVERSION=4.5.2 BUILDDIR=~/rpmbuild ARCH=`uname -p` diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index e6748ede..09ea214b 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -1,5 +1,5 @@ Name: turnserver -Version: 4.5.1.3 +Version: 4.5.2 Release: 0%{dist} Summary: Coturn TURN Server diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index a3f45bf5..336e0485 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -31,7 +31,7 @@ #ifndef __IOADEFS__ #define __IOADEFS__ -#define TURN_SERVER_VERSION "4.5.1.3" +#define TURN_SERVER_VERSION "4.5.2" #define TURN_SERVER_VERSION_NAME "dan Eider" #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'" From 2bc61f483e503fa8cd48066e085233830dc43897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:26:40 +0100 Subject: [PATCH 061/128] Add changelog to merged PRs --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1ac72709..04e133d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,13 @@ Version 4.5.2 'dan Eider': - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - merge PR #517 (by wolmi) * add prometheus metrics + - merge PR #637 (by David Florness) + * Delete trailing whitespace in example configuration files + - merge PR #631 (by Debabrata Deka) + * Add architecture ppc64le to travis build + - merge PR #627 (by Samuel) + * Fix misleading option in doc (prometheus) + 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': - merge PR #575: (by osterik) From 29d5c66263510c2f907d765e99f9a02cc690180e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Mon, 7 Dec 2020 15:28:05 +0100 Subject: [PATCH 062/128] Update man after README change --- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 8 ++++---- man/man1/turnutils.1 | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 5ef28f7a..2faea944 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 5b19c10f..b7fe4a15 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -400,9 +400,9 @@ initially used by the session). .RS .TP .B -\fB\-\-no\-prometheus\fP -Disable prometheus metrics. By default it is -enabled and listening on port 9641 unther the path /metrics +\fB\-\-prometheus\fP +Enable prometheus metrics. By default it is +disabled. Would listen on port 9641 unther the path /metrics also the path / on this port can be used as a health check .RE .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index d379b923..e6d0e9c7 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "03 August 2020" "" "" +.TH TURN 1 "07 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used From 032d35271638e69eadfc9a679dd5b7d73374d40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 08:35:07 +0100 Subject: [PATCH 063/128] Changelog for PR#643 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 04e133d2..ae6cd83d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,8 @@ Version 4.5.2 'dan Eider': * Add architecture ppc64le to travis build - merge PR #627 (by Samuel) * Fix misleading option in doc (prometheus) + - merge PR #643 (by tupelo-schneck) + * Allow RFC6062 TCP relay data to look like TLS 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From b13cc41a825809c7f2d147bc293c58b161b23a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 08:49:51 +0100 Subject: [PATCH 064/128] Add to changelog PR #655 #618 #599 --- ChangeLog | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ae6cd83d..2a10aa16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,9 +8,15 @@ Version 4.5.2 'dan Eider': - merge PR #631 (by Debabrata Deka) * Add architecture ppc64le to travis build - merge PR #627 (by Samuel) - * Fix misleading option in doc (prometheus) + * Fix misleading option in doc (prometheus) - merge PR #643 (by tupelo-schneck) - * Allow RFC6062 TCP relay data to look like TLS + * Allow RFC6062 TCP relay data to look like TLS + - merge PR #655 (by plinss) + * Add support for proxy protocol V1 + - merge PR #618 (by Paul Wayper) + * Print full date and time in logs + - merge PR #599 (by Cédric Krier) + * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From 9c354943515fb52eb6bccf2b6debff98d30ad391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 09:37:45 +0100 Subject: [PATCH 065/128] Update Docker MongoDB libs and fix systemctl --- ChangeLog | 1 + docker/coturn/Dockerfile | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a10aa16..3bdf5a6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ Version 4.5.2 'dan Eider': * Print full date and time in logs - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL + - update Docker mongoDB and fix with workaround the missing systemctl 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index b8fd207f..0a18362b 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -34,14 +34,17 @@ COPY --from=coturn-build ${BUILD_PREFIX}/coturn/turndb ${INSTALL_PREFIX}/turndb # Install lib dependencies RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install -y libc6>=2.15 libevent-core-2.1-6>=libevent-core-2.1-6 libevent-extra-2.1-6>=2.1.8-stable-4 libevent-openssl-2.1-6>=2.1.8-stable-4 libevent-pthreads-2.1-6>=2.1.8-stable-4 libhiredis0.14>=0.14.0 libmariadbclient-dev>=10.3.17 libpq5>=8.4~ libsqlite3-0>=3.6.0 libssl1.1>=1.1.0 libmongoc-1.0 libbson-1.0 + apt-get install -y libc6 libevent-core-2.1-6 libevent-extra-2.1-6 libevent-openssl-2.1-6 libevent-pthreads-2.1-6 libhiredis0.14 libmariadbclient-dev libpq5 libsqlite3-0 libssl1.1 libmongoc-1.0-0 libbson-1.0-0 RUN apt-get install -y default-mysql-client postgresql-client redis-tools +# Workaround for MongoDB +RUN ln -s /bin/echo /bin/systemctl + # Install MongoDB RUN apt-get update && \ apt-get install -y wget gnupg && \ - wget -qO - https://www.mongodb.org/static/pgp/server-4.0.asc | apt-key add - && \ - echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.0 main" | tee /etc/apt/sources.list.d/mongodb-org-4.0.list && \ + wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add - && \ + echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \ echo "deb http://deb.debian.org/debian/ stretch main" | tee /etc/apt/sources.list.d/debian-stretch.list && \ apt-get update && \ apt-get install -y libcurl3 mongodb-org mongodb-org-server mongodb-org From 3c7021979872fb1c3e16d841c172fa2778135ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 09:45:56 +0100 Subject: [PATCH 066/128] Fix docker lint warn: workdir need to be absolute --- docker/coturn/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index 0a18362b..fc109980 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -13,7 +13,7 @@ WORKDIR ${BUILD_PREFIX} RUN git clone https://github.com/coturn/coturn.git # Build Coturn -WORKDIR coturn +WORKDIR ${BUILD_PREFIX}/coturn RUN ./configure RUN make From 50f789ab5ad4ac5b7db2eb977de8ceabeea22065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 10:44:40 +0100 Subject: [PATCH 067/128] Add new timestamp options to the README and man --- ChangeLog | 1 + README.turnserver | 4 ++++ man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 10 +++++++++- man/man1/turnutils.1 | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3bdf5a6f..31fe1b79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs + * Add new options: "new-log-timestamp" and "new-timestamp_format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index a5bf149a..4e773c1d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -225,6 +225,10 @@ Flags: name will be constructed as-is, without PID and date appendage. This option can be used, for example, together with the logrotate tool. +--new-log-timestamp Enable full ISO-8601 timestamp in all logs. + +--new-timestamp_format Set timestamp format (in strftime(1) format) + --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 2faea944..8fcdfd54 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index b7fe4a15..6a8941ef 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -338,6 +338,14 @@ name will be constructed as\-is, without PID and date appendage. This option can be used, for example, together with the logrotate tool. .TP .B +\fB\-\-new\-log\-timestamp\fP +Enable full ISO\-8601 timestamp in all logs. +.TP +.B +\fB\-\-new\-timestamp_format\fP + Set timestamp format (in \fBstrftime\fP(1) format) +.TP +.B \fB\-\-secure\-stun\fP Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index e6d0e9c7..24bcf6e0 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 December 2020" "" "" +.TH TURN 1 "08 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used From 9a0d9d8c5da8665a80226164df650b2eb50e3749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:07:53 +0100 Subject: [PATCH 068/128] Replace new-timestamp_format=>new-timestamp-format --- ChangeLog | 2 +- README.turnserver | 2 +- man/man1/turnserver.1 | 2 +- src/apps/relay/mainrelay.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 31fe1b79..7c0acdbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs - * Add new options: "new-log-timestamp" and "new-timestamp_format" + * Add new options: "new-log-timestamp" and "new-timestamp-format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index 4e773c1d..0468a091 100644 --- a/README.turnserver +++ b/README.turnserver @@ -227,7 +227,7 @@ Flags: --new-log-timestamp Enable full ISO-8601 timestamp in all logs. ---new-timestamp_format Set timestamp format (in strftime(1) format) +--new-timestamp-format Set timestamp format (in strftime(1) format) --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 6a8941ef..7464114b 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -342,7 +342,7 @@ This option can be used, for example, together with the logrotate tool. Enable full ISO\-8601 timestamp in all logs. .TP .B -\fB\-\-new\-timestamp_format\fP +\fB\-\-new\-timestamp\-format\fP Set timestamp format (in \fBstrftime\fP(1) format) .TP .B diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index d0134f28..ff357299 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -604,7 +604,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" -" --new-timestamp_format Set timestamp format (in strftime(1) format)\n" +" --new-timestamp-format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -904,7 +904,7 @@ static const struct myoption long_options[] = { { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, - { "new-timestamp_format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, + { "new-timestamp-format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, From 37b61993e501eaaeb88cf489ef329de25fa82e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:10:15 +0100 Subject: [PATCH 069/128] Add new log options to config file --- examples/etc/turnserver.conf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 3af6845c..028d59b6 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -534,6 +534,12 @@ # #simple-log +# Enable full ISO-8601 timestamp in all logs. +#new-log-timestamp + +# Set timestamp format (in strftime(1) format) +#new-timestamp-format "%FT%T%z" + # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute From b0fb4a9a0a97a243f47c874282e4ca0bfcec501a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 11:48:54 +0100 Subject: [PATCH 070/128] Rename new timestamp options, and fix these cli handling --- ChangeLog | 2 +- README.turnserver | 2 +- examples/etc/turnserver.conf | 2 +- man/man1/turnserver.1 | 2 +- src/apps/relay/mainrelay.c | 15 +++++++++++---- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c0acdbb..808632a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ Version 4.5.2 'dan Eider': * Add support for proxy protocol V1 - merge PR #618 (by Paul Wayper) * Print full date and time in logs - * Add new options: "new-log-timestamp" and "new-timestamp-format" + * Add new options: "new-log-timestamp" and "new-log-timestamp-format" - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl diff --git a/README.turnserver b/README.turnserver index 0468a091..77b205b9 100644 --- a/README.turnserver +++ b/README.turnserver @@ -227,7 +227,7 @@ Flags: --new-log-timestamp Enable full ISO-8601 timestamp in all logs. ---new-timestamp-format Set timestamp format (in strftime(1) format) +--new-log-timestamp-format Set timestamp format (in strftime(1) format) --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 028d59b6..aa919642 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -538,7 +538,7 @@ #new-log-timestamp # Set timestamp format (in strftime(1) format) -#new-timestamp-format "%FT%T%z" +#new-log-timestamp-format "%FT%T%z" # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 7464114b..e3bd3251 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -342,7 +342,7 @@ This option can be used, for example, together with the logrotate tool. Enable full ISO\-8601 timestamp in all logs. .TP .B -\fB\-\-new\-timestamp\-format\fP +\fB\-\-new\-log\-timestamp\-format\fP Set timestamp format (in \fBstrftime\fP(1) format) .TP .B diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index ff357299..7da6d1b9 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -604,7 +604,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " name will be constructed as-is, without PID and date appendage.\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" -" --new-timestamp-format Set timestamp format (in strftime(1) format)\n" +" --new-log-timestamp-format Set timestamp format (in strftime(1) format)\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -764,7 +764,7 @@ enum EXTRA_OPTS { SYSLOG_OPT, SIMPLE_LOG_OPT, NEW_LOG_TIMESTAMP_OPT, - NEW_TIMESTAMP_FORMAT_OPT, + NEW_LOG_TIMESTAMP_FORMAT_OPT, AUX_SERVER_OPT, UDP_SELF_BALANCE_OPT, ALTERNATE_SERVER_OPT, @@ -904,7 +904,7 @@ static const struct myoption long_options[] = { { "syslog", optional_argument, NULL, SYSLOG_OPT }, { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT }, { "new-log-timestamp", optional_argument, NULL, NEW_LOG_TIMESTAMP_OPT }, - { "new-timestamp-format", required_argument, NULL, NEW_TIMESTAMP_FORMAT_OPT }, + { "new-log-timestamp-format", required_argument, NULL, NEW_LOG_TIMESTAMP_FORMAT_OPT }, { "aux-server", required_argument, NULL, AUX_SERVER_OPT }, { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT }, { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT }, @@ -1592,6 +1592,13 @@ static void set_option(int c, char *value) turn_params.rest_api_separator=*value; } break; + case NEW_LOG_TIMESTAMP_OPT: + use_new_log_timestamp_format=1; + break; + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + set_turn_log_timestamp_format(value); + break; + /* these options have been already taken care of before: */ case 'l': case NO_STDOUT_LOG_OPT: @@ -1725,7 +1732,7 @@ static void read_config_file(int argc, char **argv, int pass) set_simple_log(get_bool_value(value)); } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_OPT)) { use_new_log_timestamp_format=1; - } else if ((pass==0) && (c==NEW_TIMESTAMP_FORMAT_OPT)) { + } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { set_option(c, value); From 08bb62ea8871c09f7961388d0fad9c9c50b2ee37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 8 Dec 2020 13:40:49 +0100 Subject: [PATCH 071/128] Update README to fix #658 --- README.md | 3 ++- README.turnadmin | 6 +++++- README.turnserver | 6 +++++- README.turnutils | 6 +++++- man/man1/turnadmin.1 | 5 ++++- man/man1/turnserver.1 | 6 +++++- man/man1/turnutils.1 | 5 ++++- 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 448df3f3..59997efb 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,8 @@ Contact information: https://groups.google.com/forum/#!forum/turn-server-project-rfc5766-turn-server -email:mom040267@gmail.com +email:misi@majd.eu + mom040267@gmail.com ### Feedback is very welcome (bugs, issues, suggestions, stories, questions). ### diff --git a/README.turnadmin b/README.turnadmin index 4b64583d..8e177010 100644 --- a/README.turnadmin +++ b/README.turnadmin @@ -271,4 +271,8 @@ to see the man page. Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros \ No newline at end of file diff --git a/README.turnserver b/README.turnserver index 77b205b9..5969ba6d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -1001,4 +1001,8 @@ https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766- Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros diff --git a/README.turnutils b/README.turnutils index ab2dd832..da89c5dd 100644 --- a/README.turnutils +++ b/README.turnutils @@ -474,4 +474,8 @@ SEE ALSO Bradley T. Hughes - Mihaly Meszaros + Mihály Mészáros + + ACTIVE MAINTAINERS + + Mihály Mészáros \ No newline at end of file diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 8fcdfd54..dc2982c2 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -373,4 +373,7 @@ Federico Pinna .PP Bradley T. Hughes .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index e3bd3251..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1274,5 +1274,9 @@ Mutsutoshi Yoshimoto Federico Pinna .PP Bradley T. Hughes +.RE .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 24bcf6e0..93a03ef3 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -667,4 +667,7 @@ Federico Pinna .PP Bradley T. Hughes .PP -Mihaly Meszaros +Mihály Mészáros +.SS ACTIVE MAINTAINERS + +Mihály Mészáros From 0880d7cd0fe9641d65f42100d6012f46c3878759 Mon Sep 17 00:00:00 2001 From: Camden Narzt Date: Wed, 9 Dec 2020 16:15:40 -0700 Subject: [PATCH 072/128] fix compilation on macOS Big Sur You must define `__APPLE_USE_RFC_3542` in order to use the `IPV6_DONTFRAG` sockopt: https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/netinet6/in6.h.auto.html ``` * To use the new IPv6 Sockets options introduced by RFC 3542 * the constant __APPLE_USE_RFC_3542 must be defined before * including ``` --- src/ns_turn_defs.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index 336e0485..461ceccd 100644 --- a/src/ns_turn_defs.h +++ b/src/ns_turn_defs.h @@ -39,6 +39,10 @@ #include #endif +#if defined(__APPLE__) || defined(__DARWIN__) || defined(__MACH__) +#define __APPLE_USE_RFC_3542 +#endif + #include #include #include From 9b1cca1fbe909e7cc7c7ac28865f9c190af3515b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 10 Dec 2020 11:11:40 +0100 Subject: [PATCH 073/128] Add PR#660 to changelog --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 808632a6..85ffb0aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,8 @@ Version 4.5.2 'dan Eider': - merge PR #599 (by Cédric Krier) * Do not use FIPS and remove hardcode OPENSSL_VERSION_NUMBER with LibreSSL - update Docker mongoDB and fix with workaround the missing systemctl + - merge PR #660 (by Camden Narzt) + * fix compilation on macOS Big Sur 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From dd0ffdb51a4cddaf1d6662079fa91f6f32bd26a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 10 Dec 2020 14:15:26 +0100 Subject: [PATCH 074/128] Add comment to ioa_addr_is_zero --- src/client/ns_turn_ioaddr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index 86b96886..c8c0faf9 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -496,6 +496,12 @@ int ioa_addr_is_loopback(ioa_addr *addr) return 0; } +/* +To avoid a vulnerability this function checks whether the addr is in 0.0.0.0/8 or ::/128. +Source from (INADDR_ANY) 0.0.0.0/32 and (in6addr_any) ::/128 routed to loopback on Linux systems for old BSD backward compatibility. +https://github.com/torvalds/linux/blob/a2f5ea9e314ba6778f885c805c921e9362ec0420/net/ipv6/tcp_ipv6.c#L182 +To avoid any trouble we match the whole 0.0.0.0/8 that defined in RFC6890 as local network "this". +*/ int ioa_addr_is_zero(ioa_addr *addr) { if(addr) { From d84028b6dbc9eb7d3f8828ec37ae02a0963257b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 10 Dec 2020 14:17:00 +0100 Subject: [PATCH 075/128] Simplify the ipv6 ::/128 (in6addr_any) check --- src/client/ns_turn_ioaddr.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/client/ns_turn_ioaddr.c b/src/client/ns_turn_ioaddr.c index c8c0faf9..810476fe 100644 --- a/src/client/ns_turn_ioaddr.c +++ b/src/client/ns_turn_ioaddr.c @@ -510,14 +510,12 @@ int ioa_addr_is_zero(ioa_addr *addr) return (u[0] == 0); } else if(addr->ss.sa_family == AF_INET6) { const uint8_t *u = ((const uint8_t*)&(addr->s6.sin6_addr)); - if(u[15] == 0) { - int i; - for(i=0;i<15;++i) { - if(u[i]) - return 0; - } - return 1; + int i; + for(i=0;i<=15;++i) { + if(u[i]) + return 0; } + return 1; } } return 0; From 7e525c8e1c09c0055fb00fbcac091c4d87d19937 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 076/128] support of --acme-redirect --- src/apps/relay/http_server.c | 77 ++++++++++++++++++++++++++++++++++++ src/apps/relay/mainrelay.c | 14 ++++++- src/apps/relay/mainrelay.h | 1 + src/apps/relay/netengine.c | 1 + src/server/ns_turn_ioalib.h | 1 + src/server/ns_turn_server.c | 17 +++++--- src/server/ns_turn_server.h | 4 ++ 7 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 7da6d1b9..2baa7705 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -114,7 +114,7 @@ NULL, PTHREAD_MUTEX_INITIALIZER, //////////////// Common params //////////////////// TURN_VERBOSE_NONE,0,0,0,0, -"/var/run/turnserver.pid", +"/var/run/turnserver.pid","", DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,0,1, 0,0,0,0,0, "", @@ -629,6 +629,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" +" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" @@ -810,7 +812,8 @@ enum EXTRA_OPTS { OAUTH_OPT, NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, - SECRET_KEY_OPT + SECRET_KEY_OPT, + ACME_REDIRECT_OPT }; struct myoption { @@ -944,6 +947,7 @@ static const struct myoption long_options[] = { { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT }, { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, + { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1587,6 +1591,9 @@ static void set_option(int c, char *value) case PIDFILE_OPT: STRCPY(turn_params.pidfile,value); break; + case ACME_REDIRECT_OPT: + STRCPY(turn_params.acme_redirect,value); + break; case 'C': if(value && *value) { turn_params.rest_api_separator=*value; @@ -2276,6 +2283,9 @@ int main(int argc, char **argv) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name); + if(turn_params.acme_redirect[0]) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect URL: %s\n",turn_params.acme_redirect); + } if(turn_params.oauth && turn_params.oauth_server_name[0]) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name); } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 106f25a2..0bcdbbd4 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -219,6 +219,7 @@ typedef struct _turn_params_ { int do_not_use_config_file; char pidfile[1025]; + char acme_redirect[1025]; //////////////// Listener server ///////////////// diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index ca88056e..20f558cd 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1667,6 +1667,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int allocate_bps, turn_params.oauth, turn_params.oauth_server_name, + turn_params.acme_redirect, turn_params.keep_address_family); if(to_set_rfc5780) { diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 6737711d..3a25b03e 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 38a15134..3d3eaa74 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,14 +4624,19 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { + char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); + size_t l = ioa_network_buffer_get_size(in_buffer->nbh); + if(is_http(str, l)) { const char *proto = "HTTP"; - ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0; - if (*server->web_admin_listen_on_workers) { + str[l] = 0; + if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + ss->to_be_closed = 1; + return 0; + } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4644,7 +4649,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh)); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); } handle_http_echo(ss->client_socket); } @@ -4915,6 +4920,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family) { if (!server) @@ -4944,6 +4950,7 @@ void init_turn_server(turn_turnserver* server, server->oauth_server_name = oauth_server_name; if(mobility) server->mobile_connections_map = ur_map_create(); + server->acme_redirect = acme_redirect; TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"turn server id=%d created\n",(int)id); diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 924a507a..0df99716 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -171,6 +171,9 @@ struct _turn_turnserver { int oauth; const char* oauth_server_name; + /* ACME redirect URL */ + const char* acme_redirect; + /* Keep Address Family */ int keep_address_family; }; @@ -218,6 +221,7 @@ void init_turn_server(turn_turnserver* server, allocate_bps_cb allocate_bps_func, int oauth, const char* oauth_server_name, + const char* acme_redirect, int keep_address_family); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 9b0dd4380cb0e2c68c22cbbad9d03bd62b3b6deb Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 077/128] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ src/apps/relay/mainrelay.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..4fbd2673 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,6 +787,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2baa7705..2343a1cd 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -629,7 +629,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect <\"URL\"> Redirect HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '<\"URL\">$1'\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" " Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" From d4686750eee289f05e24e9fdcc99c88d4fb217f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sat, 8 Aug 2020 22:47:41 +0200 Subject: [PATCH 078/128] Move acme to new file --- ChangeLog | 4 +- Makefile.in | 2 +- man/man1/turnserver.1 | 7 --- src/apps/relay/acme.c | 111 +++++++++++++++++++++++++++++++++++ src/apps/relay/acme.h | 57 ++++++++++++++++++ src/apps/relay/http_server.c | 77 ------------------------ src/server/ns_turn_ioalib.h | 3 + src/server/ns_turn_server.c | 19 +++--- 8 files changed, 187 insertions(+), 93 deletions(-) create mode 100644 src/apps/relay/acme.c create mode 100644 src/apps/relay/acme.h diff --git a/ChangeLog b/ChangeLog index 85ffb0aa..95f10a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.2 'dan Eider': - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - - merge PR #517 (by wolmi) + - merge PR #517 (by wolmi) * add prometheus metrics - merge PR #637 (by David Florness) * Delete trailing whitespace in example configuration files @@ -21,6 +21,8 @@ Version 4.5.2 'dan Eider': - update Docker mongoDB and fix with workaround the missing systemctl - merge PR #660 (by Camden Narzt) * fix compilation on macOS Big Sur + - merge PR #546 (by jelmd) + * Add ACME redirect url 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/Makefile.in b/Makefile.in index a4479e15..b869d0e6 100755 --- a/Makefile.in +++ b/Makefile.in @@ -21,7 +21,7 @@ COMMON_MODS = src/apps/common/apputils.c src/apps/common/ns_turn_utils.c src/app COMMON_DEPS = ${LIBCLIENTTURN_DEPS} ${COMMON_MODS} ${COMMON_HEADERS} IMPL_HEADERS = src/apps/relay/ns_ioalib_impl.h src/apps/relay/ns_sm.h src/apps/relay/turn_ports.h -IMPL_MODS = src/apps/relay/ns_ioalib_engine_impl.c src/apps/relay/turn_ports.c src/apps/relay/http_server.c +IMPL_MODS = src/apps/relay/ns_ioalib_engine_impl.c src/apps/relay/turn_ports.c src/apps/relay/http_server.c src/apps/relay/acme.c IMPL_DEPS = ${COMMON_DEPS} ${IMPL_HEADERS} ${IMPL_MODS} HIREDIS_HEADERS = src/apps/common/hiredis_libevent2.h diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 4fbd2673..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,13 +787,6 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP -.BI --acme-redirect\ URL -Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. -HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' -to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, -so make sure you do not forget the trailing slash. If \fIURL\fR is an empty -string (the default value), no special handling of such requests will be done. -.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c new file mode 100644 index 00000000..3e6d0c5e --- /dev/null +++ b/src/apps/relay/acme.c @@ -0,0 +1,111 @@ + +/* + * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "acme.h" +#include "ns_ioalib_impl.h" + +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + size_t plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + /* + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + */ + // Variant B: via eventbuf does not send anything for whatever reason + + //set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh_acme); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh_acme, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); + + return 0; +} diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h new file mode 100644 index 00000000..133c22d1 --- /dev/null +++ b/src/apps/relay/acme.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __TURN_ACME__ +#define __TURN_ACME__ + +#include "ns_turn_utils.h" +#include "ns_turn_server.h" +#include "apputils.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +///////////// ACME ///////////////////// + +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); + +/////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif +/// __TURN_ACME__ /// + diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ca70d77e..ff8e3992 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,83 +99,6 @@ const char* get_http_date_header() return buffer_header; } -static int is_acme_req(char *req, size_t len) { - static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; - int c, i, k; - - // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) - return -1; - // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other - // implementations may choose longer pathes. We define PATHMAX = 127 chars - // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len =- 21; // min size of trailing headers - if (len > 131) - len = 131; - for (i=32; i < (int) len; i++) { - // find the end of the path - if (req[i] != ' ') - continue; - // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) - return -2; - // finally check for allowed chars - for (k=32; k < i; k++) { - c = req[k]; - if ((c > 127) || (A[c] == ' ')) - return -3; - } - // all checks passed: sufficient for us to answer with a redirect - return i; - } - return -4; // end of path not found -} - -int try_acme_redirect(char *req, size_t len, const char *url, - ioa_socket_handle s) -{ - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; - char http_response[1024]; - int plen, rlen; - - if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) - return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) - return 2; - - req[plen] = '\0'; - snprintf(http_response, sizeof(http_response) - 1, - "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %ld\r\n" - "Connection: close\r\n" - "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); - - rlen = strlen(http_response); - - // Variant A: direkt write, no eventbuf stuff - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - - // Variant B: via eventbuf does not send anything for whatever reason - /* - set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); - uint8_t *data = ioa_network_buffer_data(nbh); - bcopy(http_response, data, rlen); - ioa_network_buffer_set_size(nbh, rlen); - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - */ - - return 0; -} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 3a25b03e..da3e7c5a 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,9 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); + +///////////// ACME ///////////////////// + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 3d3eaa74..dafe26ee 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,19 +4624,24 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - char *str = (char*)ioa_network_buffer_data(in_buffer->nbh); - size_t l = ioa_network_buffer_get_size(in_buffer->nbh); - if(is_http(str, l)) { + if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh))) { + const char *proto = "HTTP"; - str[l] = 0; - if ((st == TCP_SOCKET) && (try_acme_redirect(str, l, server->acme_redirect, ss->client_socket) == 0)) { + if ((st == TCP_SOCKET) && + ( + try_acme_redirect((char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), + server->acme_redirect, ss->client_socket) == 0 + ) + ) { ss->to_be_closed = 1; return 0; } else if (*server->web_admin_listen_on_workers) { if(st==TLS_SOCKET) { proto = "HTTPS"; set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), str); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), ioa_network_buffer_get_size(in_buffer->nbh)); if(server->send_https_socket) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket)); ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket); @@ -4649,7 +4654,7 @@ static int read_client_connection(turn_turnserver *server, } else { set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET); if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, str); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, ioa_network_buffer_get_size(in_buffer->nbh)); } handle_http_echo(ss->client_socket); } From 12c7d19a472d29bdeef4a37ccd5075b02ebbc517 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 07:21:56 +0200 Subject: [PATCH 079/128] support of --acme-redirect --- src/apps/relay/http_server.c | 77 +++++++ src/apps/relay/mainrelay.c | 392 +++++++++++++++++------------------ src/server/ns_turn_ioalib.h | 1 + 3 files changed, 274 insertions(+), 196 deletions(-) diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ff8e3992..ca70d77e 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,6 +99,83 @@ const char* get_http_date_header() return buffer_header; } +static int is_acme_req(char *req, size_t len) { + static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; + int c, i, k; + + // Check first request line. Should be like: GET path HTTP/1.x + if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + return -1; + // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other + // implementations may choose longer pathes. We define PATHMAX = 127 chars + // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). + len =- 21; // min size of trailing headers + if (len > 131) + len = 131; + for (i=32; i < (int) len; i++) { + // find the end of the path + if (req[i] != ' ') + continue; + // consider path < 10 chars invalid. Also we wanna see a "trailer". + if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + return -2; + // finally check for allowed chars + for (k=32; k < i; k++) { + c = req[k]; + if ((c > 127) || (A[c] == ' ')) + return -3; + } + // all checks passed: sufficient for us to answer with a redirect + return i; + } + return -4; // end of path not found +} + +int try_acme_redirect(char *req, size_t len, const char *url, + ioa_socket_handle s) +{ + static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + char http_response[1024]; + int plen, rlen; + + if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) + return 1; + if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + return 2; + + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, + "HTTP/1.1 301 Moved Permanently\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %ld\r\n" + "Connection: close\r\n" + "Location: %s%s\r\n" + "\r\n%s", strlen(HTML), url, req + 32, HTML); + + rlen = strlen(http_response); + + // Variant A: direkt write, no eventbuf stuff + if (write(s->fd, http_response, rlen) == -1) { + perror("Sending redirect failed"); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", + url, req + 32); + } + + req[plen] = ' '; + + // Variant B: via eventbuf does not send anything for whatever reason + /* + set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); + ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); + uint8_t *data = ioa_network_buffer_data(nbh); + bcopy(http_response, data, rlen); + ioa_network_buffer_set_size(nbh, rlen); + send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); + */ + + return 0; +} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2343a1cd..e6462d9d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1673,25 +1673,25 @@ static void read_config_file(int argc, char **argv, int pass) if(pass == 0) { - if (argv) { - int i = 0; - for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-c")) { - if (i < argc - 1) { - STRCPY(config_file, argv[i + 1]); - } else { - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); + if (argv) { + int i = 0; + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-c")) { + if (i < argc - 1) { + STRCPY(config_file, argv[i + 1]); + } else { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n"); + } + } else if (!strcmp(argv[i], "-n")) { + turn_params.do_not_use_config_file = 1; + config_file[0]=0; + return; + } else if (!strcmp(argv[i], "-h")) { + printf("\n%s\n",Usage); + exit(0); + } + } } - } else if (!strcmp(argv[i], "-n")) { - turn_params.do_not_use_config_file = 1; - config_file[0]=0; - return; - } else if (!strcmp(argv[i], "-h")) { - printf("\n%s\n",Usage); - exit(0); - } - } - } } if (!turn_params.do_not_use_config_file && config_file[0]) { @@ -1728,7 +1728,7 @@ static void read_config_file(int argc, char **argv, int pass) STRCPY(sarg, s); if (parse_arg_string(sarg, &c, &value) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Bad configuration format: %s\n", - sarg); + sarg); } else if((pass == 0) && (c == 'l')) { set_logfile(value); } else if((pass==0) && (c==NO_STDOUT_LOG_OPT)) { @@ -1742,9 +1742,9 @@ static void read_config_file(int argc, char **argv, int pass) } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); } else if((pass == 0) && (c != 'u')) { - set_option(c, value); + set_option(c, value); } else if((pass > 0) && (c == 'u')) { - set_option(c, value); + set_option(c, value); } if (s[slen - 1] == 59) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Check config! The following line ends with semicolon: \"%s\" \n",s); @@ -1757,7 +1757,7 @@ static void read_config_file(int argc, char **argv, int pass) } else TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Cannot find config file: %s. Default and command-line settings will be used.\n", - config_file); + config_file); if (full_path_to_config_file) { free(full_path_to_config_file); @@ -1770,7 +1770,7 @@ static int disconnect_database(void) { const turn_dbdriver_t * dbd = get_dbdriver(); if (dbd && dbd->disconnect) { - dbd->disconnect(); + dbd->disconnect(); } return 0; } @@ -1801,183 +1801,183 @@ static int adminmain(int argc, char **argv) while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) { switch (c){ - case 'P': - if(pwd[0]) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - print_enc_password = 1; - break; - case 'E': - print_enc_aes_password = 1; - break; - case 'g': - ct = TA_SET_REALM_OPTION; - break; - case 'G': - ct = TA_LIST_REALM_OPTIONS; - break; - case ADMIN_USER_QUOTA_OPT: - po.user_quota = (vint)atoi(optarg); - break; - case ADMIN_TOTAL_QUOTA_OPT: - po.total_quota = (vint)atoi(optarg); - break; - case ADMIN_MAX_BPS_OPT: - po.max_bps = (vint)atoi(optarg); - break; - case 'O': - ct = TA_ADD_ORIGIN; - break; - case 'R': - ct = TA_DEL_ORIGIN; - break; - case 'I': - ct = TA_LIST_ORIGINS; - break; - case 'o': - STRCPY(origin,optarg); - break; - case 'k': - ct = TA_PRINT_KEY; - break; - case 'a': - ct = TA_UPDATE_USER; - break; - case 'd': - ct = TA_DELETE_USER; - break; - case 'A': - ct = TA_UPDATE_USER; - is_admin = 1; - break; - case 'D': - ct = TA_DELETE_USER; - is_admin = 1; - break; - case 'l': - ct = TA_LIST_USERS; - break; - case 'L': - ct = TA_LIST_USERS; - is_admin = 1; - break; - case 's': - ct = TA_SET_SECRET; - STRCPY(secret,optarg); - break; - case 'S': - ct = TA_SHOW_SECRET; - break; - case 'X': - ct = TA_DEL_SECRET; - if(optarg) - STRCPY(secret,optarg); - break; - case DEL_ALL_AUTH_SECRETS_OPT: - ct = TA_DEL_SECRET; - break; + case 'P': + if(pwd[0]) { + char result[257]; + generate_new_enc_password((char*)pwd, result); + printf("%s\n",result); + exit(0); + } + print_enc_password = 1; + break; + case 'E': + print_enc_aes_password = 1; + break; + case 'g': + ct = TA_SET_REALM_OPTION; + break; + case 'G': + ct = TA_LIST_REALM_OPTIONS; + break; + case ADMIN_USER_QUOTA_OPT: + po.user_quota = (vint)atoi(optarg); + break; + case ADMIN_TOTAL_QUOTA_OPT: + po.total_quota = (vint)atoi(optarg); + break; + case ADMIN_MAX_BPS_OPT: + po.max_bps = (vint)atoi(optarg); + break; + case 'O': + ct = TA_ADD_ORIGIN; + break; + case 'R': + ct = TA_DEL_ORIGIN; + break; + case 'I': + ct = TA_LIST_ORIGINS; + break; + case 'o': + STRCPY(origin,optarg); + break; + case 'k': + ct = TA_PRINT_KEY; + break; + case 'a': + ct = TA_UPDATE_USER; + break; + case 'd': + ct = TA_DELETE_USER; + break; + case 'A': + ct = TA_UPDATE_USER; + is_admin = 1; + break; + case 'D': + ct = TA_DELETE_USER; + is_admin = 1; + break; + case 'l': + ct = TA_LIST_USERS; + break; + case 'L': + ct = TA_LIST_USERS; + is_admin = 1; + break; + case 's': + ct = TA_SET_SECRET; + STRCPY(secret,optarg); + break; + case 'S': + ct = TA_SHOW_SECRET; + break; + case 'X': + ct = TA_DEL_SECRET; + if(optarg) + STRCPY(secret,optarg); + break; + case DEL_ALL_AUTH_SECRETS_OPT: + ct = TA_DEL_SECRET; + break; #if !defined(TURN_NO_SQLITE) - case 'b': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; - break; + case 'b': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE; + break; #endif #if !defined(TURN_NO_PQ) - case 'e': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; - break; + case 'e': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ; + break; #endif #if !defined(TURN_NO_MYSQL) - case 'M': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; - break; + case 'M': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL; + break; #endif #if !defined(TURN_NO_MONGO) - case 'J': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; - break; + case 'J': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO; + break; #endif #if !defined(TURN_NO_HIREDIS) - case 'N': - STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); - turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; - break; + case 'N': + STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg); + turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS; + break; #endif - case 'u': - STRCPY(user,optarg); - if(!is_secure_string((uint8_t*)user,1)) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user); - exit(-1); - } - if(SASLprep((uint8_t*)user)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); - exit(-1); - } - break; - case 'r': - set_default_realm_name(optarg); - STRCPY(realm,optarg); - if(SASLprep((uint8_t*)realm)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm); - exit(-1); - } - break; - case 'p': - STRCPY(pwd,optarg); - if(SASLprep((uint8_t*)pwd)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd); - exit(-1); - } - if(print_enc_password) { - char result[257]; - generate_new_enc_password((char*)pwd, result); - printf("%s\n",result); - exit(0); - } - if(print_enc_aes_password){ - encrypt_aes_128(pwd, generated_key); - exit(0); - } - break; - case 'x': - generate_aes_128_key(optarg, generated_key); - exit(0); - break; - case 'f': - fptr = fopen((char*)optarg, "r"); - if(fptr == NULL){ - printf("No such file like %s\n", (char*)optarg); - } - else{ - fseek (fptr, 0, SEEK_SET); - rc = fread(generated_key, sizeof(char), 16, fptr); - if( rc == 0 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); + case 'u': + STRCPY(user,optarg); + if(!is_secure_string((uint8_t*)user,1)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user); + exit(-1); + } + if(SASLprep((uint8_t*)user)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user); + exit(-1); + } + break; + case 'r': + set_default_realm_name(optarg); + STRCPY(realm,optarg); + if(SASLprep((uint8_t*)realm)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm); + exit(-1); + } + break; + case 'p': + STRCPY(pwd,optarg); + if(SASLprep((uint8_t*)pwd)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd); + exit(-1); + } + if(print_enc_password) { + char result[257]; + generate_new_enc_password((char*)pwd, result); + printf("%s\n",result); + exit(0); + } + if(print_enc_aes_password){ + encrypt_aes_128(pwd, generated_key); + exit(0); + } + break; + case 'x': + generate_aes_128_key(optarg, generated_key); + exit(0); + break; + case 'f': + fptr = fopen((char*)optarg, "r"); + if(fptr == NULL){ + printf("No such file like %s\n", (char*)optarg); } else{ - if( rc != 16 ){ - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); + fseek (fptr, 0, SEEK_SET); + rc = fread(generated_key, sizeof(char), 16, fptr); + if( rc == 0 ){ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key file is empty\n",__FUNCTION__); } + else{ + if( rc != 16 ){ + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: Secret-Key length is not enough\n",__FUNCTION__); + } + } + fclose (fptr); } - fclose (fptr); - } - break; - case 'v': - decrypt_aes_128((char*)optarg, generated_key); - exit(0); - case 'h': - printf("\n%s\n", AdminUsage); - exit(0); - break; - default: - fprintf(stderr,"\n%s\n", AdminUsage); - exit(-1); + break; + case 'v': + decrypt_aes_128((char*)optarg, generated_key); + exit(0); + case 'h': + printf("\n%s\n", AdminUsage); + exit(0); + break; + default: + fprintf(stderr,"\n%s\n", AdminUsage); + exit(-1); } } @@ -2021,16 +2021,16 @@ static void print_features(unsigned long mfn) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n"); -/* - Frost stepped forward and opened the polished case with a theatrical - flourish. It was a masterful piece of craftsmanship. As the lid was - pulled back, the many trays inside lifted and fanned out, displaying - Glokta’s tools in all their gruesome glory. There were blades of every - size and shape, needles curved and straight, bottles of oil and acid, - nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood - and glass glittered in the bright lamplight, all polished to mirror - brightness and honed to a murderous sharpness. -*/ + /* + Frost stepped forward and opened the polished case with a theatrical + flourish. It was a masterful piece of craftsmanship. As the lid was + pulled back, the many trays inside lifted and fanned out, displaying + Glokta’s tools in all their gruesome glory. There were blades of every + size and shape, needles curved and straight, bottles of oil and acid, + nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood + and glass glittered in the bright lamplight, all polished to mirror + brightness and honed to a murderous sharpness. + */ #if !TLS_SUPPORTED TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n"); diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index da3e7c5a..4b9f38ad 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,7 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); +int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); ///////////// ACME ///////////////////// From 02d62e828dfcbfab351039f2719d443605460a33 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Mon, 18 May 2020 17:00:31 +0200 Subject: [PATCH 080/128] acme-redirect: add option to man page, fix help text --- man/man1/turnserver.1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..4fbd2673 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,6 +787,13 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP +.BI --acme-redirect\ URL +Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' +to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, +so make sure you do not forget the trailing slash. If \fIURL\fR is an empty +string (the default value), no special handling of such requests will be done. +.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process From fa01cfeed6ceb7a0a16cb7144d4549a4a2d3f710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sat, 8 Aug 2020 22:47:41 +0200 Subject: [PATCH 081/128] Move acme to new file --- ChangeLog | 2 + man/man1/turnserver.1 | 7 ---- src/apps/relay/http_server.c | 77 ------------------------------------ src/server/ns_turn_ioalib.h | 3 ++ 4 files changed, 5 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95f10a8f..f2210baa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ Version 4.5.2 'dan Eider': * fix compilation on macOS Big Sur - merge PR #546 (by jelmd) * Add ACME redirect url + - merge PR #551 (by jelmd) + * support of --acme-redirect 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 4fbd2673..3a9131bd 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -787,13 +787,6 @@ File name to store the pid of the process. Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP -.BI --acme-redirect\ URL -Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. -HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' -to \fIURL\fR$1 with $1 == (.*). No validation of \fIURL\fR will be done, -so make sure you do not forget the trailing slash. If \fIURL\fR is an empty -string (the default value), no special handling of such requests will be done. -.TP .B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index ca70d77e..ff8e3992 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -99,83 +99,6 @@ const char* get_http_date_header() return buffer_header; } -static int is_acme_req(char *req, size_t len) { - static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; - int c, i, k; - - // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) - return -1; - // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other - // implementations may choose longer pathes. We define PATHMAX = 127 chars - // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len =- 21; // min size of trailing headers - if (len > 131) - len = 131; - for (i=32; i < (int) len; i++) { - // find the end of the path - if (req[i] != ' ') - continue; - // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) - return -2; - // finally check for allowed chars - for (k=32; k < i; k++) { - c = req[k]; - if ((c > 127) || (A[c] == ' ')) - return -3; - } - // all checks passed: sufficient for us to answer with a redirect - return i; - } - return -4; // end of path not found -} - -int try_acme_redirect(char *req, size_t len, const char *url, - ioa_socket_handle s) -{ - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; - char http_response[1024]; - int plen, rlen; - - if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) - return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) - return 2; - - req[plen] = '\0'; - snprintf(http_response, sizeof(http_response) - 1, - "HTTP/1.1 301 Moved Permanently\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %ld\r\n" - "Connection: close\r\n" - "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); - - rlen = strlen(http_response); - - // Variant A: direkt write, no eventbuf stuff - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - - // Variant B: via eventbuf does not send anything for whatever reason - /* - set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); - ioa_network_buffer_handle nbh = ioa_network_buffer_allocate(s->e); - uint8_t *data = ioa_network_buffer_data(nbh); - bcopy(http_response, data, rlen); - ioa_network_buffer_set_size(nbh, rlen); - send_data_from_ioa_socket_nbh(s, NULL, nbh, TTL_IGNORE, TOS_IGNORE, NULL); - */ - - return 0; -} /////////////////////////////////////////////// static struct headers_list * post_parse(char *data, size_t data_len) diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 4b9f38ad..e592055f 100644 --- a/src/server/ns_turn_ioalib.h +++ b/src/server/ns_turn_ioalib.h @@ -285,6 +285,9 @@ int get_default_protocol_port(const char* scheme, size_t slen); ///////////// HTTP //////////////////// void handle_http_echo(ioa_socket_handle s); + +///////////// ACME ///////////////////// + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); ///////////// ACME ///////////////////// From 1300021c6f6d828240b88784338539e4738d22cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 15 Dec 2020 13:35:21 +0000 Subject: [PATCH 082/128] Correct acme-redirect man and readme --- README.turnserver | 6 +++ man/man1/turnadmin.1 | 32 ++++++++-------- man/man1/turnserver.1 | 87 ++++++++++++++++++++++++------------------- man/man1/turnutils.1 | 61 +++++++++++++++--------------- 4 files changed, 103 insertions(+), 83 deletions(-) diff --git a/README.turnserver b/README.turnserver index 5969ba6d..df74704b 100644 --- a/README.turnserver +++ b/README.turnserver @@ -547,6 +547,12 @@ Options with values: Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . +--acme-redirect Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. + HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' + to $1 with $1 == (.*). No validation of will be done, + so make sure you do not forget the trailing slash. If is an empty + string (the default value), no special handling of such requests will be done. + --proc-user User name to run the process. After the initialization, the turnserver process will make an attempt to change the current user ID to that user. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index dc2982c2..8540085b 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage @@ -48,8 +48,8 @@ is equivalent to: .fi You have always the use the \fB\-r\fP option with commands for long term credentials \- because data for multiple realms can be stored in the same database. -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnadmin \fP\- a TURN relay administration tool. @@ -288,8 +288,8 @@ $ \fIturnadmin\fP \fB\-\-file\-key\-path\fP \fB\-v\fP Help: .PP $ \fIturnadmin\fP \fB\-h\fP -.SH ======================================= - +.PP +======================================= .SS DOCS After installation, run the \fIcommand\fP: @@ -301,8 +301,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnadmin\fP .PP to see the man page. -.SH ===================================== - +.PP +===================================== .SS FILES /etc/turnserver.conf @@ -314,8 +314,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ===================================== - +.PP +===================================== .SS DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -323,13 +323,14 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH ====================================== - +.PP +====================================== .SS SEE ALSO \fIturnserver\fP, \fIturnutils\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -343,8 +344,9 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.SH ====================================== - +.RE +.PP +====================================== .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 3a9131bd..f52a25c5 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -78,8 +78,7 @@ is equivalent to: .fam T .fi -.SH ===================================== - +===================================== .SS NAME \fB \fBturnserver \fP\- a TURN relay server implementation. @@ -788,6 +787,14 @@ Default is /var/run/turnserver.pid (if superuser account is used) or /var/tmp/turnserver.pid . .TP .B +\fB\-\-acme\-redirect\fP + Redirect ACME/RFC8555 (like Let's Encrypt challenge) requests, i.e. +HTTP GET requests matching '^/.well\-known/acme\-challenge/(.*)' +to $1 with $1 == (.*). No validation of will be done, +so make sure you do not forget the trailing slash. If is an empty +string (the default value), no special handling of such requests will be done. +.TP +.B \fB\-\-proc\-user\fP User name to run the process. After the initialization, the \fIturnserver\fP process will make an attempt to change the current user ID to that user. @@ -848,15 +855,15 @@ By default it is disabled for security resons! .B \fB\-\-ne\fP=[1|2|3] Set network engine type for the process (for internal purposes). -.SH ================================== - +.PP +================================== .SH LOAD BALANCE AND PERFORMANCE TUNING This topic is covered in the wiki page: .PP https://github.com/coturn/coturn/wiki/turn_performance_and_load_balance -.SH =================================== - +.PP +=================================== .SH WEBRTC USAGE This is a set of notes for the WebRTC users: @@ -893,8 +900,8 @@ Usually WebRTC uses fingerprinting (\fB\-f\fP). .IP 5) 4 \fB\-\-min\-port\fP and \fB\-\-max\-port\fP may be needed if you want to limit the relay endpoints ports number range. -.SH =================================== - +.PP +=================================== .SH TURN REST API In WebRTC, the browser obtains the TURN connection information from the web @@ -1032,8 +1039,8 @@ examples/scripts/restapi/shared_secret_maintainer.pl . .PP A very important thing is that the nonce must be totally random and it must be different for different clients and different sessions. -.SH =================================== - +.PP +=================================== .SH DATABASES For the user database, the \fIturnserver\fP has the following \fIoptions\fP: @@ -1096,8 +1103,8 @@ it will set the users for you (see the \fIturnadmin\fP manuals). If you are usin \fIturnserver\fP or \fIturnadmin\fP will initialize the empty database, for you, when started. The TURN server installation process creates an empty initialized SQLite database in the default location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system). -.SH ================================= - +.PP +================================= .SH ALPN The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when @@ -1106,16 +1113,16 @@ ClientHello message that contains one or both of those ALPNs, then the server chooses the first stun.* label and sends it back (in the ServerHello) in the ALPN extension field. If no stun.* label is found, then the server does not include the ALPN information into the ServerHello. -.SH ================================= - +.PP +================================= .SH LIBRARIES In the lib/ sub\-directory the build process will create TURN client messaging library. In the include/ sub\-directory, the necessary include files will be placed. The C++ wrapper for the messaging functionality is located in TurnMsgLib.h header. An example of C++ code can be found in stunclient.c file. -.SH ================================= - +.PP +================================= .SH DOCS After installation, run the command: @@ -1130,8 +1137,8 @@ to see the man page. .PP In the docs/html subdirectory of the original archive tree, you will find the client library reference. After the installation, it will be placed in PREFIX/share/doc/\fIturnserver\fP/html. -.SH ================================= - +.PP +================================= .SH LOGS When the \fBTURN Server\fP starts, it makes efforts to create a log file turn_.log @@ -1154,8 +1161,8 @@ log messages are sent only to the standard output of the process. .PP This behavior can be controlled by \fB\-\-log\-file\fP, \fB\-\-syslog\fP and \fB\-\-no\-stdout\-log\fP \fIoptions\fP. -.SH ================================= - +.PP +================================= .SH HTTPS MANAGEMENT INTERFACE The \fIturnserver\fP process provides an HTTPS Web access as statistics and basic @@ -1168,8 +1175,8 @@ populated with the admin user \fBaccount\fP(s). An admin user can be a superuser (if not assigned to a particular realm) or a restricted user (if assigned to a realm). The restricted admin users can perform only limited actions, within their corresponding realms. -.SH ================================= - +.PP +================================= .SH TELNET CLI The \fIturnserver\fP process provides a telnet CLI access as statistics and basic management @@ -1177,8 +1184,8 @@ interface. By default, the \fIturnserver\fP starts a telnet CLI listener on IP 1 port 5766. That can be changed by the command\-cline \fIoptions\fP of the \fIturnserver\fP process (see \fB\-\-cli\-ip\fP and \fB\-\-cli\-port\fP \fIoptions\fP). The full list of telnet CLI commands is provided in "help" command output in the telnet CLI. -.SH ================================= - +.PP +================================= .SH CLUSTERS \fBTURN Server\fP can be a part of the cluster installation. But, to support the "even port" functionality @@ -1187,8 +1194,8 @@ in "help" command output in the telnet CLI. the RTP and RTCP relaying endpoints must be allocated on the same relay IP. It would be possible to design a scheme with the application\-level requests forwarding (and we may do that later) but it would affect the performance. -.SH ================================= - +.PP +================================= .SH FILES /etc/turnserver.conf @@ -1200,8 +1207,8 @@ it would affect the performance. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ================================= - +.PP +================================= .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -1209,15 +1216,16 @@ it would affect the performance. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH ================================= - +.PP +================================= .SH STANDARDS obsolete STUN RFC 3489 .PP new STUN RFC 5389 -.SH TURN RFC 5766 - +.PP +TURN RFC 5766 +.PP TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -1225,13 +1233,14 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.SH ================================= - +.PP +================================= .SH SEE ALSO \fIturnadmin\fP, \fIturnutils\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -1245,8 +1254,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server -.SH ====================================== - +.PP +====================================== .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 93a03ef3..809f83a4 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 December 2020" "" "" +.TH TURN 1 "15 December 2020" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -63,8 +63,8 @@ script in examples/scripts/oauth.sh. .RE .PP -.SH ===================================== - +.RS +===================================== .SS NAME \fB \fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only. @@ -276,8 +276,8 @@ the ORIGIN STUN attribute value. Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. .PP See the examples in the "examples/scripts" directory. -.SH ====================================== - +.PP +====================================== .SS NAME \fB \fBturnutils_peer \fP\- a simple UDP\-only echo backend server. @@ -314,8 +314,8 @@ If no listener \fBaddress\fP(es) defined, then it listens on all IPv4 and IPv6 a .B \fB\-v\fP Verbose -.SH ======================================== - +.PP +======================================== .SS NAME \fB \fBturnutils_stunclient \fP\- a basic STUN client. @@ -354,8 +354,8 @@ and if it finds that the STUN server supports RFC 5780 requests with different parameters, to demonstrate the NAT discovery capabilities. .PP This utility does not support the "old" "classic" STUN protocol (RFC 3489). -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_rfc5769check \fP\- a utility that tests the correctness of STUN protocol implementation. @@ -380,8 +380,8 @@ check procedure, it is not copied to the installation destination. Usage: .PP $ \fIturnutils_rfc5769check\fP -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_natdiscovery \fP\- a utility that discovers NAT mapping and filtering @@ -462,8 +462,8 @@ Used by mapping lifetime behavior discovery Usage: .PP $ \fIturnutils_natdiscovery\fP \fB\-m\fP \fB\-f\fP stun.example.com -.SH ===================================== - +.PP +===================================== .SS NAME \fB \fBturnutils_oauth \fP\- a utility that helps OAuth access_token generation/encryption and validation/decyption @@ -568,8 +568,8 @@ stun client hmac algorithm Usage: .PP $ \fIturnutils_natdiscovery\fP -.SH =================================== - +.PP +=================================== .SH DOCS After installation, run the command: @@ -581,8 +581,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnutils\fP .PP to see the man page. -.SH ===================================== - +.PP +===================================== .SH FILES /etc/turnserver.conf @@ -594,8 +594,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.SH ================================= - +.PP +================================= .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -603,13 +603,14 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.SH =================================== - +.PP +=================================== .SH STANDARDS new STUN RFC 5389 -.SH TURN RFC 5766 - +.PP +TURN RFC 5766 +.PP TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -617,13 +618,14 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.SH ==================================== - +.PP +==================================== .SH SEE ALSO \fIturnserver\fP, \fIturnadmin\fP -.SH ====================================== - +.RE +.PP +====================================== .SS WEB RESOURCES project page: @@ -637,8 +639,9 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.SH ====================================== - +.RE +.PP +====================================== .SS AUTHORS Oleg Moskalenko From 174d039c73a055f168005ac0d5a9296445f0b493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 15 Dec 2020 13:56:21 +0000 Subject: [PATCH 083/128] fix acme-redirect help --- src/apps/relay/mainrelay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index e6462d9d..73505663 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -629,8 +629,8 @@ static char Usage[] = "Usage: turnserver [options]\n" " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n" " Default is /var/run/turnserver.pid (if superuser account is used) or\n" " /var/tmp/turnserver.pid .\n" -" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" -" Default is '', i.e. no special handling for such requests.\n" +" --acme-redirect Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'.\n" +" Default is '', i.e. no special handling for such requests.\n" " --secure-stun Require authentication of the STUN Binding request.\n" " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n" " --proc-user User name to run the turnserver process.\n" From d73a8e85d7ac205f142cb991ff5beee470481465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:05:19 +0000 Subject: [PATCH 084/128] Add acme to config file --- examples/etc/turnserver.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index aa919642..906a4b98 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -719,6 +719,10 @@ # #web-admin-listen-on-workers +#acme-redirect=http://redirectserver/.well-known/acme-challenge/ +# Redirect ACME, i.e. HTTP GET requests matching '^/.well-known/acme-challenge/(.*)' to '$1'. +# Default is '', i.e. no special handling for such requests. + # Server relay. NON-STANDARD AND DANGEROUS OPTION. # Only for those applications when you want to run # server applications on the relay endpoints. From 377e8f76871621634adc182b035d878c09baefd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:05:56 +0000 Subject: [PATCH 085/128] Ugly Hack: Parse HTTP request --- src/apps/relay/acme.c | 44 ++++++++++++++++++++++++++----------------- src/apps/relay/acme.h | 2 ++ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index 3e6d0c5e..c1109383 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -67,8 +67,33 @@ static int is_acme_req(char *req, size_t len) { int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s) { - static const char *HTML = "301 Moved Permanently

301 Moved Permanently

"; + static const char *HTML = + "301 Moved Permanently\ +

301 Moved Permanently

"; char http_response[1024]; + char req_url[600]; + char *req_url_end_space, *req_url_end_tab; + int path_length; + strcpy(req_url, req + GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH); + req_url_end_space=strchr(req_url,' '); + req_url_end_tab=strchr(req_url,'\t'); + if (req_url_end_space != NULL && req_url_end_tab != NULL) { + if (req_url_end_space - req_url_end_tab > 0 ){ + path_length=req_url_end_space - req_url; + req_url[path_length]='\0'; + } else { + path_length=req_url_end_tab - req_url; + req_url[req_url_end_tab - req_url]='\0'; + } + } else if(req_url_end_space != NULL) { + path_length=req_url_end_space - req_url; + req_url[path_length]='\0'; + } + else if(req_url_end_tab != NULL) { + path_length=req_url_end_tab - req_url; + req_url[path_length]='\0'; + } + size_t plen, rlen; if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) @@ -76,31 +101,16 @@ int try_acme_redirect(char *req, size_t len, const char *url, if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) return 2; - snprintf(http_response, sizeof(http_response) - 1, "HTTP/1.1 301 Moved Permanently\r\n" "Content-Type: text/html\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n" "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req + 32, HTML); + "\r\n%s", strlen(HTML), url, req_url, HTML); rlen = strlen(http_response); - // Variant A: direkt write, no eventbuf stuff - /* - if (write(s->fd, http_response, rlen) == -1) { - perror("Sending redirect failed"); - } else if (((turn_turnserver *)s->session->server)->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirect to %s%s\n", - url, req + 32); - } - - req[plen] = ' '; - */ - // Variant B: via eventbuf does not send anything for whatever reason - - //set_ioa_socket_app_type(s, HTTP_CLIENT_SOCKET); ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); uint8_t *data = ioa_network_buffer_data(nbh_acme); bcopy(http_response, data, rlen); diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h index 133c22d1..a927dc56 100644 --- a/src/apps/relay/acme.h +++ b/src/apps/relay/acme.h @@ -44,6 +44,8 @@ extern "C" { ///////////// ACME ///////////////////// +#define GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH 32 + int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// From 2f790ec18bb2c1bc6fcfc0586c81a2bd63a73225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:06:25 +0000 Subject: [PATCH 086/128] Tidy acme code --- src/server/ns_turn_server.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index dafe26ee..f9e8f89b 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4630,9 +4630,12 @@ static int read_client_connection(turn_turnserver *server, const char *proto = "HTTP"; if ((st == TCP_SOCKET) && ( - try_acme_redirect((char*)ioa_network_buffer_data(in_buffer->nbh), - ioa_network_buffer_get_size(in_buffer->nbh), - server->acme_redirect, ss->client_socket) == 0 + try_acme_redirect( + (char*)ioa_network_buffer_data(in_buffer->nbh), + ioa_network_buffer_get_size(in_buffer->nbh), + server->acme_redirect, + ss->client_socket + ) == 0 ) ) { ss->to_be_closed = 1; From ae541958cd4c818e5d44d06d6ec75a7f1944ade6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 18 Dec 2020 08:22:02 +0000 Subject: [PATCH 087/128] Tidy: remoe trailing space --- src/apps/relay/acme.c | 2 +- src/server/ns_turn_server.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index c1109383..13023d7d 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -86,7 +86,7 @@ int try_acme_redirect(char *req, size_t len, const char *url, req_url[req_url_end_tab - req_url]='\0'; } } else if(req_url_end_space != NULL) { - path_length=req_url_end_space - req_url; + path_length=req_url_end_space - req_url; req_url[path_length]='\0'; } else if(req_url_end_tab != NULL) { diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index f9e8f89b..340b1fe7 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4624,16 +4624,16 @@ static int read_client_connection(turn_turnserver *server, } else { SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket); if(is_stream_socket(st)) { - if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), + if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) { const char *proto = "HTTP"; - if ((st == TCP_SOCKET) && + if ((st == TCP_SOCKET) && ( try_acme_redirect( (char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh), - server->acme_redirect, + server->acme_redirect, ss->client_socket ) == 0 ) From 6101ebd51b6731464ab346ae70159e8312d0b3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 22 Dec 2020 16:55:31 +0000 Subject: [PATCH 088/128] external-ip private part to white list fixes#584 --- src/apps/relay/mainrelay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 73505663..472e316e 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1372,6 +1372,7 @@ static void set_option(int c, char *value) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div); } else { ioa_addr_add_mapping(&apub,&apriv); + if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); } } free(nval); From 8dc5bbcb3b7f2ef561293df8b920cb21b0eaf081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 22 Dec 2020 17:05:42 +0000 Subject: [PATCH 089/128] Tidy: too long line length --- src/apps/relay/mainrelay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 472e316e..102b8f1d 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1372,7 +1372,8 @@ static void set_option(int c, char *value) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div); } else { ioa_addr_add_mapping(&apub,&apriv); - if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); + if (add_ip_list_range((const char *)div, NULL, &turn_params.ip_whitelist) == 0) + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Whitelisting external-ip private part: %s\n", div); } } free(nval); From 8c9950561488f99f6530040deef6ebf8122800b2 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 16:39:00 +0100 Subject: [PATCH 090/128] fix acme wrt. security, redundancy, consistency --- configure | 11 ++++++ src/apps/relay/acme.c | 81 ++++++++++++++----------------------------- src/apps/relay/acme.h | 2 -- 3 files changed, 37 insertions(+), 57 deletions(-) diff --git a/configure b/configure index 38227c6e..b85a65ca 100755 --- a/configure +++ b/configure @@ -556,6 +556,17 @@ if [ "${SYSTEM}" = "NetBSD" ] ; then fi fi +# If acme_redirect does not work, send_data_from_ioa_socket_nbh() probably +# does not work. Set LIBEV_OK=1 to use a workaround for it. +if [ -z "${LIBEV_OK}" ]; then + LIBEV_OK=1 + if [ "${SYSTEM}" = "Linux" ]; then + OS=$( lsb_release -si 2>/dev/null ) + [ "${OS}" = "Ubuntu" ] || LIBEV_OK=0 + fi +fi +[ "${LIBEV_OK}" = "1" ] && OSCFLAGS="${OSCFLAGS} -DLIBEV_OK" + ########################### # Install shell commands ########################### diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index 13023d7d..f713d348 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -1,43 +1,22 @@ /* - * Copyright (C) 2011, 2012, 2013, 2014 Citrix Systems + * Copyright (C) 2020 Jens Elkner. All rights reserved. * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * License: MIT - see https://opensource.org/licenses/MIT */ #include "acme.h" #include "ns_ioalib_impl.h" +#define GET_ACME_PREFIX "GET /.well-known/acme-challenge/" +#define GET_ACME_PREFIX_LEN 32 + static int is_acme_req(char *req, size_t len) { static const char *A = " - 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz "; int c, i, k; // Check first request line. Should be like: GET path HTTP/1.x - if (strncmp(req, "GET /.well-known/acme-challenge/", 32)) + if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN)) return -1; // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other // implementations may choose longer pathes. We define PATHMAX = 127 chars @@ -45,15 +24,15 @@ static int is_acme_req(char *req, size_t len) { len =- 21; // min size of trailing headers if (len > 131) len = 131; - for (i=32; i < (int) len; i++) { + for (i=GET_ACME_PREFIX_LEN; i < (int) len; i++) { // find the end of the path if (req[i] != ' ') continue; // consider path < 10 chars invalid. Also we wanna see a "trailer". - if (i < 42 || strncmp(req + i, " HTTP/1.", 8)) + if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8)) return -2; // finally check for allowed chars - for (k=32; k < i; k++) { + for (k=GET_ACME_PREFIX_LEN; k < i; k++) { c = req[k]; if ((c > 127) || (A[c] == ' ')) return -3; @@ -71,51 +50,43 @@ int try_acme_redirect(char *req, size_t len, const char *url, "301 Moved Permanently\

301 Moved Permanently

"; char http_response[1024]; - char req_url[600]; - char *req_url_end_space, *req_url_end_tab; - int path_length; - strcpy(req_url, req + GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH); - req_url_end_space=strchr(req_url,' '); - req_url_end_tab=strchr(req_url,'\t'); - if (req_url_end_space != NULL && req_url_end_tab != NULL) { - if (req_url_end_space - req_url_end_tab > 0 ){ - path_length=req_url_end_space - req_url; - req_url[path_length]='\0'; - } else { - path_length=req_url_end_tab - req_url; - req_url[req_url_end_tab - req_url]='\0'; - } - } else if(req_url_end_space != NULL) { - path_length=req_url_end_space - req_url; - req_url[path_length]='\0'; - } - else if(req_url_end_tab != NULL) { - path_length=req_url_end_tab - req_url; - req_url[path_length]='\0'; - } - size_t plen, rlen; if (url == NULL || url[0] == '\0' || req == NULL || s == 0 ) return 1; - if (len < 64 || len > 512 || (plen = is_acme_req(req, len)) < 33) + if (len < (GET_ACME_PREFIX_LEN + 32) || len > (512 - GET_ACME_PREFIX_LEN) + || (plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1)) return 2; + req[plen] = '\0'; + snprintf(http_response, sizeof(http_response) - 1, "HTTP/1.1 301 Moved Permanently\r\n" "Content-Type: text/html\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n" "Location: %s%s\r\n" - "\r\n%s", strlen(HTML), url, req_url, HTML); + "\r\n%s", strlen(HTML), url, req + GET_ACME_PREFIX_LEN, HTML); rlen = strlen(http_response); +#ifdef LIBEV_OK ioa_network_buffer_handle nbh_acme = ioa_network_buffer_allocate(s->e); uint8_t *data = ioa_network_buffer_data(nbh_acme); bcopy(http_response, data, rlen); ioa_network_buffer_set_size(nbh_acme, rlen); send_data_from_ioa_socket_nbh(s, NULL, nbh_acme, TTL_IGNORE, TOS_IGNORE, NULL); +#else + if (write(s->fd, http_response, rlen) == -1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, + "Sending redirect to '%s%s' failed",url, req + GET_ACME_PREFIX_LEN); + } else if (((turn_turnserver *)s->session->server)->verbose) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "ACME redirected to %s%s\n", + url, req + GET_ACME_PREFIX_LEN); + } +#endif + + req[plen] = ' '; return 0; } diff --git a/src/apps/relay/acme.h b/src/apps/relay/acme.h index a927dc56..133c22d1 100644 --- a/src/apps/relay/acme.h +++ b/src/apps/relay/acme.h @@ -44,8 +44,6 @@ extern "C" { ///////////// ACME ///////////////////// -#define GET_WELLKNOWN_ACMECHALLANGE_URL_PREFIX_LENGTH 32 - int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle s); /////////////////////////////////////// From 36481cc396f993350b1e9d86ea86379891d4c795 Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 19:06:46 +0100 Subject: [PATCH 091/128] configure fix --- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index b85a65ca..226adb6c 100755 --- a/configure +++ b/configure @@ -1,5 +1,7 @@ #!/bin/sh +set -x + # Proprietary configure script of Coturn project cleanup() { @@ -562,7 +564,7 @@ if [ -z "${LIBEV_OK}" ]; then LIBEV_OK=1 if [ "${SYSTEM}" = "Linux" ]; then OS=$( lsb_release -si 2>/dev/null ) - [ "${OS}" = "Ubuntu" ] || LIBEV_OK=0 + [ "${OS}" = "Ubuntu" ] && LIBEV_OK=0 fi fi [ "${LIBEV_OK}" = "1" ] && OSCFLAGS="${OSCFLAGS} -DLIBEV_OK" From 619305a43ca0a8cc0b34dffcad0b1e623a306f3a Mon Sep 17 00:00:00 2001 From: Jens Elkner Date: Thu, 31 Dec 2020 19:08:57 +0100 Subject: [PATCH 092/128] configure: disable debug --- configure | 2 -- 1 file changed, 2 deletions(-) diff --git a/configure b/configure index 226adb6c..4933830c 100755 --- a/configure +++ b/configure @@ -1,7 +1,5 @@ #!/bin/sh -set -x - # Proprietary configure script of Coturn project cleanup() { From 86b78aa6fac8bd868a6fa616f4c2b52516fb08ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 07:44:58 +0000 Subject: [PATCH 093/128] Tidy: fix spacing --- src/server/ns_turn_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 340b1fe7..4ed12d44 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4914,7 +4914,7 @@ void init_turn_server(turn_turnserver* server, vintp stun_only, vintp no_stun, vintp no_software_attribute, - vintp web_admin_listen_on_workers, + vintp web_admin_listen_on_workers, turn_server_addrs_list_t *alternate_servers_list, turn_server_addrs_list_t *tls_alternate_servers_list, turn_server_addrs_list_t *aux_servers_list, From 27b261eb58116e1dd395124e90ccbcc09d13b135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 09:55:55 +0000 Subject: [PATCH 094/128] Disable binding logging to avoid DoS attack * Add new option log-binding --- ChangeLog | 2 ++ README.turnserver | 2 ++ examples/etc/turnserver.conf | 4 ++++ man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 6 +++++- man/man1/turnutils.1 | 2 +- src/apps/relay/dtls_listener.c | 2 +- src/apps/relay/mainrelay.c | 13 +++++++++++-- src/apps/relay/mainrelay.h | 2 ++ src/apps/relay/netengine.c | 3 ++- src/server/ns_turn_server.c | 11 +++++++---- src/server/ns_turn_server.h | 6 +++++- 12 files changed, 43 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index f2210baa..9d647154 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,8 @@ Version 4.5.2 'dan Eider': * Add ACME redirect url - merge PR #551 (by jelmd) * support of --acme-redirect + - Disable binding request logging to avoid DoS attacks. (Breaking change!) + * Add new --log-binding option to enable binding request logging 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/README.turnserver b/README.turnserver index df74704b..46e3bbc3 100644 --- a/README.turnserver +++ b/README.turnserver @@ -229,6 +229,8 @@ Flags: --new-log-timestamp-format Set timestamp format (in strftime(1) format) +--log-binding Log STUN binding request. It is now disabled by default to avoid DoS attacks. + --secure-stun Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index 906a4b98..d5e39ea4 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -540,6 +540,10 @@ # Set timestamp format (in strftime(1) format) #new-log-timestamp-format "%FT%T%z" +# Disabled by default binding logging in verbose log mode to avoid DoS attacks. +# Enable binding logging and UDP endpoint logs in verbose log mode. +#log-binding + # Option to set the "redirection" mode. The value of this option # will be the address of the alternate server for UDP & TCP service in the form of # [:]. The server will send this value in the attribute diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 8540085b..d19ce74d 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index f52a25c5..9286e018 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -345,6 +345,10 @@ Enable full ISO\-8601 timestamp in all logs. Set timestamp format (in \fBstrftime\fP(1) format) .TP .B +\fB\-\-log\-binding\fP +Log STUN binding request. It is now disabled by default to avoid DoS attacks. +.TP +.B \fB\-\-secure\-stun\fP Require authentication of the STUN Binding request. By default, the clients are allowed anonymous access to the STUN Binding functionality. diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 809f83a4..26b98805 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "15 December 2020" "" "" +.TH TURN 1 "05 January 2021" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index 08a17e7d..7689a134 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -456,7 +456,7 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, sm->m.sm.s = s; if (s) { - if(verbose) { + if(verbose && turn_params.log_binding) { uint8_t saddr[129]; uint8_t rsaddr[129]; addr_to_string(get_local_addr_from_ioa_socket(s),saddr); diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 102b8f1d..42213019 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -168,7 +168,9 @@ DEFAULT_CPUS_NUMBER, 0, /* keep_address_family */ 0, /* no_auth_pings */ 0, /* no_dynamic_ip_list */ -0 /* no_dynamic_realms */ +0, /* no_dynamic_realms */ + +0 /* log_binding */ }; //////////////// OpenSSL Init ////////////////////// @@ -605,6 +607,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " This option can be used, for example, together with the logrotate tool.\n" " --new-log-timestamp Enable full ISO-8601 timestamp in all logs.\n" " --new-log-timestamp-format Set timestamp format (in strftime(1) format)\n" +" --log-binding Log STUN binding request. It is now disabled by default to avoid DoS attacks.\n" " --stale-nonce[=] Use extra security with nonce value having limited lifetime (default 600 secs).\n" " --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs.\n" " --channel-lifetime Set the lifetime for channel binding, default to 600 secs.\n" @@ -813,7 +816,8 @@ enum EXTRA_OPTS { NO_SOFTWARE_ATTRIBUTE_OPT, NO_HTTP_OPT, SECRET_KEY_OPT, - ACME_REDIRECT_OPT + ACME_REDIRECT_OPT, + LOG_BINDING_OPT }; struct myoption { @@ -948,6 +952,8 @@ static const struct myoption long_options[] = { { "secret-key-file", required_argument, NULL, SECRET_KEY_OPT }, { "keep-address-family", optional_argument, NULL, 'K' }, { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, + { "log-binding", optional_argument, NULL, LOG_BINDING_OPT }, + { NULL, no_argument, NULL, 0 } }; @@ -1607,6 +1613,9 @@ static void set_option(int c, char *value) case NEW_LOG_TIMESTAMP_FORMAT_OPT: set_turn_log_timestamp_format(value); break; + case LOG_BINDING_OPT: + turn_params.log_binding = get_bool_value(value); + break; /* these options have been already taken care of before: */ case 'l': diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 0bcdbbd4..5b6f7cdd 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -333,6 +333,8 @@ typedef struct _turn_params_ { int no_dynamic_ip_list; int no_dynamic_realms; + vint log_binding; + } turn_params_t; extern turn_params_t turn_params; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 20f558cd..6a456f6a 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1668,7 +1668,8 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int turn_params.oauth, turn_params.oauth_server_name, turn_params.acme_redirect, - turn_params.keep_address_family); + turn_params.keep_address_family, + &turn_params.log_binding); if(to_set_rfc5780) { set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client); diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 4ed12d44..3d9034f3 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -3832,13 +3832,13 @@ static int handle_turn_command(turn_turnserver *server, ts_ur_super_session *ss, &dest_changed, &response_destination, 0, 0); - if(server->verbose) { + if(server->verbose && server->log_binding) { log_method(ss, "BINDING", err_code, reason); } if(*resp_constructed && !err_code && (origin_changed || dest_changed)) { - if (server->verbose) { + if (server->verbose && server->log_binding) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "RFC 5780 request successfully processed\n"); } @@ -4014,7 +4014,7 @@ static int handle_old_stun_command(turn_turnserver *server, ts_ur_super_session &dest_changed, &response_destination, cookie,1); - if(server->verbose) { + if(server->verbose && *(server->log_binding)) { log_method(ss, "OLD BINDING", err_code, reason); } @@ -4929,7 +4929,8 @@ void init_turn_server(turn_turnserver* server, int oauth, const char* oauth_server_name, const char* acme_redirect, - int keep_address_family) { + int keep_address_family, + vintp log_binding) { if (!server) return; @@ -5001,6 +5002,8 @@ void init_turn_server(turn_turnserver* server, server->keep_address_family = keep_address_family; set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler"); + + server->log_binding = log_binding; } ioa_engine_handle turn_server_get_engine(turn_turnserver *s) { diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 0df99716..aab33e36 100644 --- a/src/server/ns_turn_server.h +++ b/src/server/ns_turn_server.h @@ -176,6 +176,9 @@ struct _turn_turnserver { /* Keep Address Family */ int keep_address_family; + + /* Log Binding Requrest */ + vintp log_binding; }; const char * get_version(turn_turnserver *server); @@ -222,7 +225,8 @@ void init_turn_server(turn_turnserver* server, int oauth, const char* oauth_server_name, const char* acme_redirect, - int keep_address_family); + int keep_address_family, + vintp log_binding); ioa_engine_handle turn_server_get_engine(turn_turnserver *s); From 6ce463e8e23c53e9ad9674faf7b2a1f0ac2e1f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 09:57:16 +0000 Subject: [PATCH 095/128] Removed wiki, due it was outdated and redundant. --- src/apps/relay/mainrelay.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 42213019..884c5018 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -669,10 +669,6 @@ static char Usage[] = "Usage: turnserver [options]\n" " This value can be changed on-the-fly in CLI. The default value is 256.\n" " --ne=[1|2|3] Set network engine type for the process (for internal purposes).\n" " -h Help\n" -"\n" -" For more information, see the wiki pages:\n" -"\n" -" https://github.com/coturn/coturn/wiki/\n" "\n"; static char AdminUsage[] = "Usage: turnadmin [command] [options]\n" From 14f1630ec6086a93056327c76faa3789c480c591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:25:10 +0000 Subject: [PATCH 096/128] Fix stale-nonce documentation Resolves #604 --- ChangeLog | 1 + README.turnserver | 1 + docker/coturn/turnserver.conf | 4 ++-- examples/etc/turnserver.conf | 4 ++-- man/man1/turnserver.1 | 1 + 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d647154..572e360e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,7 @@ Version 4.5.2 'dan Eider': * support of --acme-redirect - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging + - Fix stale-nonce documentation. Resolves #604 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/README.turnserver b/README.turnserver index 46e3bbc3..ba3ad28a 100644 --- a/README.turnserver +++ b/README.turnserver @@ -281,6 +281,7 @@ Options with values: --stale-nonce[=] Use extra security with nonce value having limited lifetime, in seconds (default 600 secs). + Set it to 0 for unlimited nonce lifetime. --max-allocate-lifetime Set the maximum value for the allocation lifetime. Default to 3600 secs. diff --git a/docker/coturn/turnserver.conf b/docker/coturn/turnserver.conf index fc9ac1fe..ea40824a 100644 --- a/docker/coturn/turnserver.conf +++ b/docker/coturn/turnserver.conf @@ -411,9 +411,9 @@ realm=example.org # Uncomment if extra security is desired, # with nonce value having a limited lifetime. -# By default, the nonce value is unique for a session, -# and has an unlimited lifetime. +# The nonce value is unique for a session. # Set this option to limit the nonce lifetime. +# Set it to 0 for unlimited lifetime. # It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index d5e39ea4..b01fb059 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -423,9 +423,9 @@ # Uncomment if extra security is desired, # with nonce value having a limited lifetime. -# By default, the nonce value is unique for a session, -# and has an unlimited lifetime. +# The nonce value is unique for a session. # Set this option to limit the nonce lifetime. +# Set it to 0 for unlimited lifetime. # It defaults to 600 secs (10 min) if no value is provided. After that delay, # the client will get 438 error and will have to re-authenticate itself. # diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 9286e018..02bfd5da 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -427,6 +427,7 @@ Options with values: \fB\-\-stale\-nonce\fP[=] Use extra security with nonce value having limited lifetime, in seconds (default 600 secs). +Set it to 0 for unlimited nonce lifetime. .TP .B \fB\-\-max\-allocate\-lifetime\fP From 1600b07bb37e7430fae7510e5934883f248def59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:45:17 +0000 Subject: [PATCH 097/128] merge PR#672 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 572e360e..5e626ff8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,8 @@ Version 4.5.2 'dan Eider': * Add ACME redirect url - merge PR #551 (by jelmd) * support of --acme-redirect + - merge PR #672 further acme fixes (by jemld) + * fix acme security, redundancy, consistency - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging - Fix stale-nonce documentation. Resolves #604 From 7fe2808d432df4a898b3e2f9f304cc80a757414b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 10:46:28 +0000 Subject: [PATCH 098/128] Use SemVer 2.0 version numbering --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 5e626ff8..fda25517 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ Version 4.5.2 'dan Eider': - Disable binding request logging to avoid DoS attacks. (Breaking change!) * Add new --log-binding option to enable binding request logging - Fix stale-nonce documentation. Resolves #604 + - Version number is changed to semver 2.0 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': From 30c1a2076ba4129e7d7a2520fb70fe7b03de9a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 12:18:18 +0000 Subject: [PATCH 099/128] Comment out fialing travis check on osx xcode11.6 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3199c79..baf01ce9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,8 +66,8 @@ matrix: - libhiredis-dev - os: osx osx_image: xcode11.3 - - os: osx - osx_image: xcode11.6 + # - os: osx + # osx_image: xcode11.6 - os: osx osx_image: xcode12 - os: linux From 50ebef7a3fcf03f116b2673a8e9ab99264e0d78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 5 Jan 2021 21:47:50 +0000 Subject: [PATCH 100/128] Fix g++ 2 errors and many warnings Resolves #661 #654 --- src/apps/relay/dbdrivers/dbd_mongo.c | 2 +- src/apps/relay/dbdrivers/dbd_mysql.c | 2 +- src/apps/relay/dbdrivers/dbd_pgsql.c | 2 +- src/apps/relay/dbdrivers/dbd_redis.c | 2 +- src/apps/relay/dbdrivers/dbd_sqlite.c | 2 +- src/apps/relay/mainrelay.c | 8 +-- src/client++/TurnMsgLib.h | 96 ++++++++++++--------------- 7 files changed, 50 insertions(+), 64 deletions(-) diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index d84e4ee0..8891456b 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -1124,7 +1124,7 @@ static void mongo_reread_realms(secrets_list_t * realms_list) { ur_string_map_value_type value = (ur_string_map_value_type) (rval); ur_string_map_put(o_to_realm_new, - (const ur_string_map_key_type) _origin, + (ur_string_map_key_type) _origin, value); free(_origin); } diff --git a/src/apps/relay/dbdrivers/dbd_mysql.c b/src/apps/relay/dbdrivers/dbd_mysql.c index dd702e82..0371a1cb 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.c +++ b/src/apps/relay/dbdrivers/dbd_mysql.c @@ -1048,7 +1048,7 @@ static void mysql_reread_realms(secrets_list_t * realms_list) { char *rval=strdup(row[1]); get_realm(rval); ur_string_map_value_type value = (ur_string_map_value_type)rval; - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); } } } diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.c b/src/apps/relay/dbdrivers/dbd_pgsql.c index 0af09977..67b6f0cd 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.c +++ b/src/apps/relay/dbdrivers/dbd_pgsql.c @@ -758,7 +758,7 @@ static void pgsql_reread_realms(secrets_list_t * realms_list) { if(rval) { get_realm(rval); ur_string_map_value_type value = strdup(rval); - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); } } } diff --git a/src/apps/relay/dbdrivers/dbd_redis.c b/src/apps/relay/dbdrivers/dbd_redis.c index ec23ffed..5c8f40de 100644 --- a/src/apps/relay/dbdrivers/dbd_redis.c +++ b/src/apps/relay/dbdrivers/dbd_redis.c @@ -1161,7 +1161,7 @@ static void redis_reread_realms(secrets_list_t * realms_list) { } else { get_realm(rget->str); ur_string_map_value_type value = strdup(rget->str); - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) origin, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) origin, value); } turnFreeRedisReply(rget); } diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 305a60b8..06da7c1b 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -1038,7 +1038,7 @@ static void sqlite_reread_realms(secrets_list_t * realms_list) get_realm(rval); ur_string_map_value_type value = rval; - ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value); + ur_string_map_put(o_to_realm_new, (ur_string_map_key_type) oval, value); free(oval); diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 884c5018..9553548b 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1173,7 +1173,7 @@ static void set_option(int c, char *value) STRCPY(turn_params.oauth_server_name,value); break; case OAUTH_OPT: - if(!ENC_ALG_NUM) { + if( ENC_ALG_NUM == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option --oauth is not supported; ignored.\n"); } else { turn_params.oauth = get_bool_value(value); @@ -2062,7 +2062,7 @@ static void print_features(unsigned long mfn) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN is not supported\n"); #endif - if(!ENC_ALG_NUM) { + if(ENC_ALG_NUM == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) is not supported\n"); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) supported\n"); @@ -2588,7 +2588,7 @@ static int THREAD_setup(void) { mutex_buf_initialized = 1; -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 CRYPTO_THREADID_set_callback(coturn_id_function); #else CRYPTO_set_id_callback(coturn_id_function); @@ -2610,7 +2610,7 @@ int THREAD_cleanup(void) { if (!mutex_buf_initialized) return 0; -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 CRYPTO_THREADID_set_callback(NULL); #else CRYPTO_set_id_callback(NULL); diff --git a/src/client++/TurnMsgLib.h b/src/client++/TurnMsgLib.h index 9c4a6279..93ae8c0d 100644 --- a/src/client++/TurnMsgLib.h +++ b/src/client++/TurnMsgLib.h @@ -75,7 +75,7 @@ public: /** * Iterator constructor: creates iterator on raw messagebuffer. */ - StunAttrIterator(uint8_t *buf, size_t sz) throw (WrongStunBufferFormatException) : + StunAttrIterator(uint8_t *buf, size_t sz) : _buf(buf), _sz(sz) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -87,7 +87,7 @@ public: * Iterator constructor: create iterator over message. */ template - StunAttrIterator(T &msg) throw (WrongStunBufferFormatException) : + StunAttrIterator(T &msg) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -99,7 +99,7 @@ public: * Iterator constructor: creates iterator over raw buffer, starting from first * location of an attribute of particular type. */ - StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) throw (WrongStunBufferFormatException) : + StunAttrIterator(uint8_t *buf, size_t sz, uint16_t attr_type) : _buf(buf), _sz(sz) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -112,7 +112,7 @@ public: * location of an attribute of particular type. */ template - StunAttrIterator(T &msg, uint16_t attr_type) throw (WrongStunBufferFormatException) : + StunAttrIterator(T &msg, uint16_t attr_type) : _buf(msg.getRawBuffer()), _sz(msg.getSize()) { if(!stun_is_command_message_str(_buf, _sz)) { throw WrongStunBufferFormatException(); @@ -123,7 +123,7 @@ public: /** * Moves iterator to next attribute location */ - void next() throw(EndOfStunMsgException) { + void next() { if(!_sar) { throw EndOfStunMsgException(); } @@ -167,7 +167,7 @@ public: * Return raw memroy field of the attribute value. * If the attribute value length is zero (0), then return NULL. */ - const uint8_t *getRawBuffer(size_t &sz) const throw(WrongStunAttrFormatException) { + const uint8_t *getRawBuffer(size_t &sz) const { int len = stun_attr_get_len(_sar); if(len<0) throw WrongStunAttrFormatException(); @@ -196,7 +196,7 @@ public: /** * Constructs attribute from iterator */ - StunAttr(const StunAttrIterator &iter) throw(WrongStunAttrFormatException, EndOfStunMsgException) { + StunAttr(const StunAttrIterator &iter) { if(iter.eof()) { throw EndOfStunMsgException(); } @@ -219,7 +219,7 @@ public: */ virtual ~StunAttr() { if(_value) - free(_value,_sz); + free(_value); } /** @@ -233,11 +233,11 @@ public: /** * Set raw data value */ - void setRawValue(uint8_t *value, size_t sz) throw(WrongStunAttrFormatException) { + void setRawValue(uint8_t *value, size_t sz) { if(sz>0xFFFF) throw WrongStunAttrFormatException(); if(_value) - free(_value,_sz); + free(_value); _sz = sz; _value=(uint8_t*)malloc(_sz); if(value) @@ -262,7 +262,7 @@ public: * Add attribute to a message */ template - int addToMsg(T &msg) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + int addToMsg(T &msg) { if(!_attr_type) throw WrongStunAttrFormatException(); uint8_t *buffer = msg.getRawBuffer(); @@ -281,7 +281,7 @@ protected: /** * Virtual function member to add attribute to a raw buffer */ - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { if(buffer) { if(!_value) throw WrongStunAttrFormatException(); @@ -313,8 +313,7 @@ public: StunAttrChannelNumber() : _cn(0) { setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); } - StunAttrChannelNumber(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrChannelNumber(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -331,7 +330,7 @@ public: _cn = cn; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_channel_number_str(buffer,&sz,_cn); } private: @@ -346,8 +345,7 @@ public: StunAttrEvenPort() : _ep(0) { setType(STUN_ATTRIBUTE_EVEN_PORT); } - StunAttrEvenPort(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrEvenPort(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -362,7 +360,7 @@ public: _ep = ep; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1); } private: @@ -377,8 +375,7 @@ public: StunAttrReservationToken() : _rt(0) { setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); } - StunAttrReservationToken(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrReservationToken(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -393,7 +390,7 @@ public: _rt = rt; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { uint64_t reservation_token = ioa_ntoh64(_rt); return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t*) (&reservation_token), 8); } @@ -410,8 +407,7 @@ public: addr_set_any(&_addr); setType(attr_type); } - StunAttrAddr(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrAddr(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -430,7 +426,7 @@ public: addr_cpy(&_addr,&addr); } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr); } private: @@ -445,8 +441,7 @@ public: StunAttrChangeRequest() : _changeIp(0), _changePort(0) { setType(STUN_ATTRIBUTE_CHANGE_REQUEST); } - StunAttrChangeRequest(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrChangeRequest(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -476,7 +471,7 @@ public: _changePort = 0; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort); } private: @@ -492,8 +487,7 @@ public: StunAttrResponsePort() : _rp(0) { setType(STUN_ATTRIBUTE_RESPONSE_PORT); } - StunAttrResponsePort(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrResponsePort(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -513,7 +507,7 @@ public: _rp = p; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_response_port_str(buffer, &sz, _rp); } private: @@ -528,8 +522,7 @@ public: StunAttrPadding() : _p(0) { setType(STUN_ATTRIBUTE_PADDING); } - StunAttrPadding(const StunAttrIterator &iter) - throw(WrongStunAttrFormatException, EndOfStunMsgException) : + StunAttrPadding(const StunAttrIterator &iter) : StunAttr(iter) { if(iter.eof()) @@ -552,7 +545,7 @@ public: _p = p; } protected: - virtual int addToBuffer(uint8_t *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_padding_str(buffer, &sz, _p); } private: @@ -588,7 +581,7 @@ public: */ virtual ~StunMsg() { if(_deallocate && _buffer) { - free(_buffer, _allocated_sz); + free(_buffer); } } @@ -623,7 +616,7 @@ public: /** * Set message size */ - void setSize(size_t sz) throw(WrongStunBufferFormatException) { + void setSize(size_t sz) { if(sz>_allocated_sz) throw WrongStunBufferFormatException(); _sz = sz; @@ -700,14 +693,14 @@ public: /** * Add attribute to the message */ - int addAttr(StunAttr &attr) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { + int addAttr(StunAttr &attr) { return attr.addToMsg(*this); } /** * Get transaction ID */ - virtual stun_tid getTid() const throw(WrongStunBufferFormatException) { + virtual stun_tid getTid() const { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_tid tid; @@ -718,7 +711,7 @@ public: /** * Set transaction ID */ - virtual void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { + virtual void setTid(stun_tid &tid) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_tid_message_cpy(_buffer, &tid); @@ -727,7 +720,7 @@ public: /** * Add fingerprint to the message */ - void addFingerprint() throw(WrongStunBufferFormatException) { + void addFingerprint() { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); stun_attr_add_fingerprint_str(_buffer,&_sz); @@ -736,8 +729,7 @@ public: /** * Check message integrity, in secure communications. */ - bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const - throw(WrongStunBufferFormatException) { + bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); uint8_t *suname=(uint8_t*)strdup(uname.c_str()); @@ -754,8 +746,7 @@ public: /** * Adds long-term message integrity data to the message. */ - void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) - throw(WrongStunBufferFormatException) { + void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); @@ -776,8 +767,7 @@ public: /** * Adds short-term message integrity data to the message. */ - void addSTMessageIntegrity(std::string &uname, std::string &upwd) - throw(WrongStunBufferFormatException) { + void addSTMessageIntegrity(std::string &uname, std::string &upwd) { if(!_constructed || !isCommand()) throw WrongStunBufferFormatException(); @@ -808,8 +798,7 @@ protected: class StunMsgRequest : public StunMsg { public: StunMsgRequest(uint16_t method) : _method(method) {}; - StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgRequest(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0) { if(constructed) { @@ -893,8 +882,7 @@ public: _method(method), _err(error_code), _reason(reason), _tid(tid) { }; - StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgResponse(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0),_err(0),_reason("") { if(constructed) { @@ -949,14 +937,14 @@ public: /** * Set transaction ID */ - void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { + void setTid(stun_tid &tid) { _tid = tid; } /** * Get transaction ID */ - virtual stun_tid getTid() const throw(WrongStunBufferFormatException) { + virtual stun_tid getTid() const { return _tid; } @@ -1074,8 +1062,7 @@ private: class StunMsgIndication : public StunMsg { public: StunMsgIndication(uint16_t method) : _method(method) {}; - StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgIndication(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_method(0) { if(constructed) { @@ -1123,8 +1110,7 @@ private: class StunMsgChannel : public StunMsg { public: StunMsgChannel(uint16_t cn, int length) : _cn(cn), _len(length) {}; - StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) - throw(WrongStunBufferFormatException) : + StunMsgChannel(uint8_t *buffer, size_t total_sz, size_t sz, bool constructed) : StunMsg(buffer,total_sz,sz,constructed),_cn(0) { if(constructed) { From 5b13fdd37b57de99414048c34751fea8454a712d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 10:33:14 +0000 Subject: [PATCH 101/128] Fix: Read log options in first pass. Fixes #602 --- src/apps/relay/mainrelay.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 9553548b..2c3c7e13 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1603,12 +1603,6 @@ static void set_option(int c, char *value) turn_params.rest_api_separator=*value; } break; - case NEW_LOG_TIMESTAMP_OPT: - use_new_log_timestamp_format=1; - break; - case NEW_LOG_TIMESTAMP_FORMAT_OPT: - set_turn_log_timestamp_format(value); - break; case LOG_BINDING_OPT: turn_params.log_binding = get_bool_value(value); break; @@ -1618,6 +1612,8 @@ static void set_option(int c, char *value) case NO_STDOUT_LOG_OPT: case SYSLOG_OPT: case SIMPLE_LOG_OPT: + case NEW_LOG_TIMESTAMP_OPT: + case NEW_LOG_TIMESTAMP_FORMAT_OPT: case 'c': case 'n': case 'h': @@ -1748,9 +1744,9 @@ static void read_config_file(int argc, char **argv, int pass) use_new_log_timestamp_format=1; } else if ((pass==0) && (c==NEW_LOG_TIMESTAMP_FORMAT_OPT)) { set_turn_log_timestamp_format(value); - } else if((pass == 0) && (c != 'u')) { + } else if((pass == 1) && (c != 'u')) { set_option(c, value); - } else if((pass > 0) && (c == 'u')) { + } else if((pass == 2) && (c == 'u')) { set_option(c, value); } if (s[slen - 1] == 59) { @@ -2228,6 +2224,12 @@ int main(int argc, char **argv) case SIMPLE_LOG_OPT: set_simple_log(get_bool_value(optarg)); break; + case NEW_LOG_TIMESTAMP_OPT: + use_new_log_timestamp_format=1; + break; + case NEW_LOG_TIMESTAMP_FORMAT_OPT: + set_turn_log_timestamp_format(optarg); + break; default: ; } @@ -2264,8 +2266,10 @@ int main(int argc, char **argv) if(strstr(argv[0],"turnadmin")) return adminmain(argc,argv); - + // Zero pass apply the log options. read_config_file(argc,argv,0); + // First pass read other config options + read_config_file(argc,argv,1); struct uoptions uo; uo.u.m = long_options; @@ -2275,7 +2279,8 @@ int main(int argc, char **argv) set_option(c,optarg); } - read_config_file(argc,argv,1); + // Second pass read -u options + read_config_file(argc,argv,2); { unsigned long mfn = set_system_parameters(1); From ae0b41153cbc40222ba6761f9f373c85d6adc642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 14:18:36 +0000 Subject: [PATCH 102/128] Fix PR288 --- ChangeLog | 2 ++ configure | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fda25517..0e34cee2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,8 @@ Version 4.5.2 'dan Eider': * Add new --log-binding option to enable binding request logging - Fix stale-nonce documentation. Resolves #604 - Version number is changed to semver 2.0 + - Merge PR #288 (by Hristo Venev) + * pkg-config, and various cleanups in connfigure file 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/configure b/configure index f9faed61..2884d6c4 100755 --- a/configure +++ b/configure @@ -904,7 +904,7 @@ fi ########################### if [ -z "${TURN_NO_MYSQL}" ] ; then - if testpkg_server mariadb || testpkg_server mysqlclient ; then + if testpkg_db mariadb || testpkg_server mysqlclient ; then ${ECHO_CMD} "MySQL found." else ${ECHO_CMD} "MySQL not found. Building without MySQL support." @@ -919,7 +919,7 @@ fi ########################### if [ -z "${TURN_NO_MONGO}" ] ; then - if testpkg_server libmongoc-1.0; then + if testpkg_db libmongoc-1.0; then ${ECHO_CMD} "MongoDB found." else ${ECHO_CMD} "MongoDB not found. Building without MongoDB support." From ef7916842d0f21ec1dfc26a8b23290fffd8e96bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 17:51:34 +0000 Subject: [PATCH 103/128] Add systemd notification support --- ChangeLog | 3 ++- README.turnserver | 2 ++ configure | 15 +++++++++++++++ docker/coturn/Dockerfile | 2 +- examples/etc/coturn.service | 6 ++---- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 6 +++++- man/man1/turnutils.1 | 2 +- rpm/turnserver.service.fc | 4 ++-- src/apps/relay/mainrelay.c | 11 +++++++++-- src/apps/relay/mainrelay.h | 6 ++++++ src/apps/relay/netengine.c | 10 ++++++++++ 12 files changed, 56 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e34cee2..76604b13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,7 +32,8 @@ Version 4.5.2 'dan Eider': - Fix stale-nonce documentation. Resolves #604 - Version number is changed to semver 2.0 - Merge PR #288 (by Hristo Venev) - * pkg-config, and various cleanups in connfigure file + * pkg-config, and various cleanups in connfigure file + - Add systemd notification for better systemd integration 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/README.turnserver b/README.turnserver index ba3ad28a..b3fed4fc 100644 --- a/README.turnserver +++ b/README.turnserver @@ -158,6 +158,8 @@ Flags: -o, --daemon Run server as daemon. +--systemd Notify systemd about server status. (Use only in forground!) + --no-software-attribute Production mode: hide the software version. -f, --fingerprint Use fingerprints in the TURN messages. If an incoming request diff --git a/configure b/configure index 2884d6c4..01034f72 100755 --- a/configure +++ b/configure @@ -864,6 +864,21 @@ else OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi +########################### +# Test libsystemd +########################### + +if [ -z "${TURN_NO_SYSTEMD}" ] ; then + if testpkg_common libsystemd; then + ${ECHO_CMD} "Systemd library found." + else + ${ECHO_CMD} "Systemd library not found. Building without systemd support." + TURN_NO_PQ="-DTURN_NO_SYSTEMD" + fi +else + TURN_NO_PQ="-DTURN_NO_SYSTEMD" +fi + ########################### # Test SQLite3 setup ########################### diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index fc109980..b84f84ce 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -6,7 +6,7 @@ ENV BUILD_PREFIX /usr/local/src # Install build dependencies RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install -y build-essential git debhelper dpkg-dev libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libmongoc-dev libbson-dev + apt-get install -y build-essential git debhelper dpkg-dev libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libmongoc-dev libbson-dev libsystemd-dev # Clone Coturn WORKDIR ${BUILD_PREFIX} diff --git a/examples/etc/coturn.service b/examples/etc/coturn.service index c3831f80..3fb2a39d 100644 --- a/examples/etc/coturn.service +++ b/examples/etc/coturn.service @@ -9,12 +9,10 @@ Wants=network-online.target [Service] User=turnserver Group=turnserver -Type=forking +Type=notify RuntimeDirectory=turnserver PIDFile=/run/turnserver/turnserver.pid -ExecStart=/usr/bin/turnserver --daemon -c /etc/turnserver.conf --pidfile /run/turnserver/turnserver.pid -#FixMe: turnserver exit faster than it is finshing the setup and ready for handling the connection. -ExecStartPost=/bin/sleep 2 +ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver.conf --pidfile /run/turnserver/turnserver.pid Restart=on-failure InaccessibleDirectories=/home PrivateTmp=yes diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index d19ce74d..308b356b 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "05 January 2021" "" "" +.TH TURN 1 "07 January 2021" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 02bfd5da..da3448fa 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "05 January 2021" "" "" +.TH TURN 1 "07 January 2021" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -230,6 +230,10 @@ Extra verbose mode, very annoying and not recommended. .B \fB\-o\fP, \fB\-\-daemon\fP Run server as daemon. +.TP +.B +\fB\-\-systemd\fP +Notify systemd about server status. (Use only in forground!) .PP \fB\-\-no\-software\-attribute\fP Production mode: hide the software version. .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 26b98805..8e3c5062 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "05 January 2021" "" "" +.TH TURN 1 "07 January 2021" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used diff --git a/rpm/turnserver.service.fc b/rpm/turnserver.service.fc index f0113fff..6e9301f6 100644 --- a/rpm/turnserver.service.fc +++ b/rpm/turnserver.service.fc @@ -6,10 +6,10 @@ After=syslog.target network.target [Service] User=turnserver Group=turnserver -Type=forking +Type=notify EnvironmentFile=/etc/sysconfig/turnserver PIDFile=/var/run/turnserver/turnserver.pid -ExecStart=/usr/bin/turnserver -o -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS +ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS ExecStopPost=/usr/bin/rm -f /var/run/turnserver/turnserver.pid Restart=on-abort diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 2c3c7e13..d4c794ed 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -170,7 +170,8 @@ DEFAULT_CPUS_NUMBER, 0, /* no_dynamic_ip_list */ 0, /* no_dynamic_realms */ -0 /* log_binding */ +0, /* log_binding */ +0 /* systemd */ }; //////////////// OpenSSL Init ////////////////////// @@ -463,6 +464,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " -v, --verbose 'Moderate' verbose mode.\n" " -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n" " -o, --daemon Start process as daemon (detach from current shell).\n" +" --systemd Notify systemd about server status. (Use only in forground!)\n" " --no-software-attribute Production mode: hide the software version (formerly --prod).\n" " -f, --fingerprint Use fingerprints in the TURN messages.\n" " -a, --lt-cred-mech Use the long-term credential mechanism.\n" @@ -813,7 +815,8 @@ enum EXTRA_OPTS { NO_HTTP_OPT, SECRET_KEY_OPT, ACME_REDIRECT_OPT, - LOG_BINDING_OPT + LOG_BINDING_OPT, + SYSTEMD_OPT }; struct myoption { @@ -949,6 +952,7 @@ static const struct myoption long_options[] = { { "keep-address-family", optional_argument, NULL, 'K' }, { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { "log-binding", optional_argument, NULL, LOG_BINDING_OPT }, + { "systemd", optional_argument, NULL, SYSTEMD_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1606,6 +1610,9 @@ static void set_option(int c, char *value) case LOG_BINDING_OPT: turn_params.log_binding = get_bool_value(value); break; + case SYSTEMD_OPT: + turn_params.systemd = get_bool_value(value); + break; /* these options have been already taken care of before: */ case 'l': diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 5b6f7cdd..be467584 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -85,6 +85,10 @@ #include #endif +#if !defined(TURN_NO_SYSTEMD) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -335,6 +339,8 @@ typedef struct _turn_params_ { vint log_binding; + vint systemd; + } turn_params_t; extern turn_params_t turn_params; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 6a456f6a..1590dda4 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1590,6 +1590,11 @@ void run_listener_server(struct listener_server *ls) unsigned int cycle = 0; while (!turn_params.stop_turn_server) { + #if !defined(TURN_NO_SYSTEMD) + if(turn_params.systemd) + sd_notify (0, "READY=1"); + #endif + if (eve(turn_params.verbose)) { if ((cycle++ & 15) == 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cycle=%u\n", __FUNCTION__, cycle); @@ -1600,6 +1605,11 @@ void run_listener_server(struct listener_server *ls) rollover_logfile(); } + + #if !defined(TURN_NO_SYSTEMD) + if(turn_params.systemd) + sd_notify (0, "STOPPING=1"); + #endif } static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int to_set_rfc5780) From 47008229cefaff6bfc4b231642d342f99712a5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 18:05:52 +0000 Subject: [PATCH 104/128] Add pkg-config to docker --- docker/coturn/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index b84f84ce..4626715b 100644 --- a/docker/coturn/Dockerfile +++ b/docker/coturn/Dockerfile @@ -6,7 +6,7 @@ ENV BUILD_PREFIX /usr/local/src # Install build dependencies RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install -y build-essential git debhelper dpkg-dev libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libmongoc-dev libbson-dev libsystemd-dev + apt-get install -y build-essential git debhelper dpkg-dev pkg-config libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libmongoc-dev libbson-dev libsystemd-dev # Clone Coturn WORKDIR ${BUILD_PREFIX} From 9fcd86f3cc8870e16149d792ecbc9c75a358e2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 20:30:27 +0000 Subject: [PATCH 105/128] Fixes #621 --- ChangeLog | 2 ++ src/server/ns_turn_server.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76604b13..d00764fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,8 @@ Version 4.5.2 'dan Eider': - Merge PR #288 (by Hristo Venev) * pkg-config, and various cleanups in connfigure file - Add systemd notification for better systemd integration + - Fix Issue #621 (by ycaibb) + * Fix: Null pointer dereference on tcp_client_input_handler_rfc6062data function 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 3d9034f3..d57d280f 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -1981,12 +1981,13 @@ static void tcp_client_input_handler_rfc6062data(ioa_socket_handle s, int event_ set_ioa_socket_tobeclosed(s); } - if (!skip) { + if (!skip && ss) { ++(ss->peer_sent_packets); ss->peer_sent_bytes += bytes; } - turn_report_session_usage(ss, 0); + if(ss) + turn_report_session_usage(ss, 0); } static void tcp_conn_bind_timeout_handler(ioa_engine_handle e, void *arg) From 13082beae8e86760807de1cd7e8cd7ca037b9f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 21:31:12 +0000 Subject: [PATCH 106/128] Fixes #600 --- ChangeLog | 2 ++ src/server/ns_turn_server.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d00764fd..75b94b2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,8 @@ Version 4.5.2 'dan Eider': - Add systemd notification for better systemd integration - Fix Issue #621 (by ycaibb) * Fix: Null pointer dereference on tcp_client_input_handler_rfc6062data function + - Fix Issue #600 (by ycaibb) + * Fix: use-after-free vulnerability on write_to_peerchannel function 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index d57d280f..c8c92656 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4134,7 +4134,7 @@ static int write_to_peerchannel(ts_ur_super_session* ss, uint16_t chnum, ioa_net int skip = 0; rc = send_data_from_ioa_socket_nbh(get_relay_socket_ss(ss, chn->peer_addr.ss.sa_family), &(chn->peer_addr), nbh, in_buffer->recv_ttl-1, in_buffer->recv_tos, &skip); - if (!skip) { + if (!skip && rc > -1) { ++(ss->peer_sent_packets); ss->peer_sent_bytes += (uint32_t)ioa_network_buffer_get_size(in_buffer->nbh); turn_report_session_usage(ss, 0); From 2edc14a193883bacd70ccccbb84c5149fea77a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Thu, 7 Jan 2021 21:38:43 +0000 Subject: [PATCH 107/128] Fixes #601 --- ChangeLog | 2 ++ src/server/ns_turn_server.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 75b94b2c..2fe5f586 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,8 @@ Version 4.5.2 'dan Eider': * Fix: Null pointer dereference on tcp_client_input_handler_rfc6062data function - Fix Issue #600 (by ycaibb) * Fix: use-after-free vulnerability on write_to_peerchannel function + - Fix Issue #601 (by ycaibb) + * Fix: use-after-free vulnerability on write_client_connection function 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index c8c92656..3d264ada 100644 --- a/src/server/ns_turn_server.c +++ b/src/server/ns_turn_server.c @@ -4293,7 +4293,7 @@ static int write_client_connection(turn_turnserver *server, ts_ur_super_session* int skip = 0; int ret = send_data_from_ioa_socket_nbh(ss->client_socket, NULL, nbh, ttl, tos, &skip); - if(!skip) { + if(!skip && ret>-1) { ++(ss->sent_packets); ss->sent_bytes += (uint32_t)ioa_network_buffer_get_size(nbh); turn_report_session_usage(ss, 0); From 80fb20a125d0be45451dccf34bc612ebf54a5bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 07:07:21 +0000 Subject: [PATCH 108/128] Fix: systemd mistake in configure --- configure | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 01034f72..d16a9299 100755 --- a/configure +++ b/configure @@ -873,10 +873,10 @@ if [ -z "${TURN_NO_SYSTEMD}" ] ; then ${ECHO_CMD} "Systemd library found." else ${ECHO_CMD} "Systemd library not found. Building without systemd support." - TURN_NO_PQ="-DTURN_NO_SYSTEMD" + TURN_NO_SYSTEMD="-DTURN_NO_SYSTEMD" fi else - TURN_NO_PQ="-DTURN_NO_SYSTEMD" + TURN_NO_SYSTEMD="-DTURN_NO_SYSTEMD" fi ########################### @@ -1026,7 +1026,7 @@ ${ECHO_CMD} "LDFLAGS += ${OSLIBS}" >> Makefile ${ECHO_CMD} "DBLIBS += ${DBLIBS}" >> Makefile ${ECHO_CMD} "CFLAGS += ${OSCFLAGS}" >> Makefile ${ECHO_CMD} "CPPFLAGS = ${CPPFLAGS}" >> Makefile -${ECHO_CMD} "DBCFLAGS += ${DBCFLAGS} ${TURN_NO_PQ} ${TURN_NO_MYSQL} ${TURN_NO_SQLITE} ${TURN_NO_MONGO} ${TURN_NO_HIREDIS}" >> Makefile +${ECHO_CMD} "DBCFLAGS += ${DBCFLAGS} ${TURN_NO_PQ} ${TURN_NO_MYSQL} ${TURN_NO_SQLITE} ${TURN_NO_MONGO} ${TURN_NO_HIREDIS} ${TURN_NO_SYSTEMD}" >> Makefile ${ECHO_CMD} "#" >> Makefile ${ECHO_CMD} "PORTNAME = ${PORTNAME}" >> Makefile ${ECHO_CMD} "PREFIX = ${PREFIX}" >> Makefile From 828ac5b6e2961a12c0d32565f18c78d05bc4ee83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 07:48:38 +0000 Subject: [PATCH 109/128] Fix: osx ssl env travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index baf01ce9..9bbfb99e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - export CPPFLAGS="$CPPFLAGS -I/usr/local/opt/openssl/include" - - export LDFLAGS="$LDFLAGS -L/usr/local/opt/openssl/lib" + - export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" + - export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From c5cd0ad0160396783c21d231e783addc3caa4e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 07:58:33 +0000 Subject: [PATCH 110/128] Travis export ssl envs only on osX --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9bbfb99e..4f29cf6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" - - export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From 39f21d6d2a61a7f435b12dc0f643e863027b41c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:08:12 +0000 Subject: [PATCH 111/128] Fix: Travis typo in if --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f29cf6a..fe10950d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include"; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib"; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From bde7e2ece937641dbecd3cd513a350145c37de64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:16:30 +0000 Subject: [PATCH 112/128] Fix configure test mysql --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index d16a9299..1d8fc404 100755 --- a/configure +++ b/configure @@ -919,7 +919,7 @@ fi ########################### if [ -z "${TURN_NO_MYSQL}" ] ; then - if testpkg_db mariadb || testpkg_server mysqlclient ; then + if testpkg_db mariadb || testpkg_db mysqlclient ; then ${ECHO_CMD} "MySQL found." else ${ECHO_CMD} "MySQL not found. Building without MySQL support." From d951cd34bf2c55ef216fc7ad341601fadafb3b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:41:04 +0000 Subject: [PATCH 113/128] Add back again ssl and crypto testlib --- configure | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 1d8fc404..caf11f51 100755 --- a/configure +++ b/configure @@ -758,19 +758,31 @@ else if testpkg_common libcrypto; then ${ECHO_CMD} "OpenSSL Crypto lib found." else - ${ECHO_CMD} "ERROR: OpenSSL Crypto development libraries are not installed properly in required location." - ${ECHO_CMD} "Abort." - cleanup - exit + testlib crypto + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "OpenSSL Crypto lib found." + else + ${ECHO_CMD} "ERROR: OpenSSL Crypto development libraries are not installed properly in required location." + ${ECHO_CMD} "Abort." + cleanup + exit + fi fi if testpkg_common libssl; then ${ECHO_CMD} "OpenSSL lib found." else - ${ECHO_CMD} "ERROR: OpenSSL development libraries are not installed properly in required location." - ${ECHO_CMD} "Abort." - cleanup - exit + testlib ssl + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "OpenSSL lib found." + else + ${ECHO_CMD} "ERROR: OpenSSL development libraries are not installed properly in required location." + ${ECHO_CMD} "Abort." + cleanup + exit + fi fi fi ########################### From 0e961f4aa5cba765d163ed6bef18089ea60769b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:46:08 +0000 Subject: [PATCH 114/128] Revert "Fix: Travis typo in if" This reverts commit 39f21d6d2a61a7f435b12dc0f643e863027b41c9. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fe10950d..4f29cf6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include"; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib"; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From 71e4149fab5e6eb72d8d071b4e8bd4ecfc0189ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:46:13 +0000 Subject: [PATCH 115/128] Revert "Travis export ssl envs only on osX" This reverts commit c5cd0ad0160396783c21d231e783addc3caa4e36. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f29cf6a..9bbfb99e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" + - export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" + - export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From 9bf9cda5b87d42cfd10d9610865485476a7483ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 08:46:16 +0000 Subject: [PATCH 116/128] Revert "Fix: osx ssl env travis" This reverts commit 828ac5b6e2961a12c0d32565f18c78d05bc4ee83. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9bbfb99e..baf01ce9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,8 @@ language: cpp before_install: - - export SSL_CFLAGS="$SSL_CFLAGS -I/usr/local/opt/openssl/include" - - export SSL_LIBS="$SSL_LIBS -L/usr/local/opt/openssl/lib" + - export CPPFLAGS="$CPPFLAGS -I/usr/local/opt/openssl/include" + - export LDFLAGS="$LDFLAGS -L/usr/local/opt/openssl/lib" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated openssl || brew upgrade openssl; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi From a28fee8cde3c115ad792909316ffd8e5256af2f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 09:19:33 +0000 Subject: [PATCH 117/128] Fix typo in acme --- src/apps/relay/acme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/relay/acme.c b/src/apps/relay/acme.c index f713d348..28d78a2f 100644 --- a/src/apps/relay/acme.c +++ b/src/apps/relay/acme.c @@ -21,7 +21,7 @@ static int is_acme_req(char *req, size_t len) { // Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other // implementations may choose longer pathes. We define PATHMAX = 127 chars // to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K). - len =- 21; // min size of trailing headers + len -= 21; // min size of trailing headers if (len > 131) len = 131; for (i=GET_ACME_PREFIX_LEN; i < (int) len; i++) { From c6347d4c84530f46228bb1efbf25b23b4e850558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 09:44:03 +0000 Subject: [PATCH 118/128] Fix typo --- README.turnserver | 2 +- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 4 ++-- man/man1/turnutils.1 | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.turnserver b/README.turnserver index b3fed4fc..8bbda8e6 100644 --- a/README.turnserver +++ b/README.turnserver @@ -158,7 +158,7 @@ Flags: -o, --daemon Run server as daemon. ---systemd Notify systemd about server status. (Use only in forground!) +--systemd Notify systemd about server status. (Use only in foreground!) --no-software-attribute Production mode: hide the software version. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 308b356b..9205225f 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 January 2021" "" "" +.TH TURN 1 "08 January 2021" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index da3448fa..1a80a8f0 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 January 2021" "" "" +.TH TURN 1 "08 January 2021" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -233,7 +233,7 @@ Run server as daemon. .TP .B \fB\-\-systemd\fP -Notify systemd about server status. (Use only in forground!) +Notify systemd about server status. (Use only in foreground!) .PP \fB\-\-no\-software\-attribute\fP Production mode: hide the software version. .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 8e3c5062..d9bd86a9 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "07 January 2021" "" "" +.TH TURN 1 "08 January 2021" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used From a8bd1c50d3ba5c44314e45c8430079b1512396fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 8 Jan 2021 09:45:20 +0000 Subject: [PATCH 119/128] Fix typo --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2fe5f586..c067932f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,7 +32,7 @@ Version 4.5.2 'dan Eider': - Fix stale-nonce documentation. Resolves #604 - Version number is changed to semver 2.0 - Merge PR #288 (by Hristo Venev) - * pkg-config, and various cleanups in connfigure file + * pkg-config, and various cleanups in configure file - Add systemd notification for better systemd integration - Fix Issue #621 (by ycaibb) * Fix: Null pointer dereference on tcp_client_input_handler_rfc6062data function From f1d946c1b4b7312af9e06a99362bfe4d1122145b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 00:32:49 +0000 Subject: [PATCH 120/128] Refactoring Prometheus * Fix c++ support * Simplify: Remove session id/allocation --- ChangeLog | 5 + src/apps/relay/ns_ioalib_engine_impl.c | 40 +------ src/apps/relay/prom_server.c | 148 ++++++++++--------------- src/apps/relay/prom_server.h | 51 +++++---- 4 files changed, 100 insertions(+), 144 deletions(-) diff --git a/ChangeLog b/ChangeLog index c067932f..021b9c0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,11 @@ Version 4.5.2 'dan Eider': * Fix: use-after-free vulnerability on write_to_peerchannel function - Fix Issue #601 (by ycaibb) * Fix: use-after-free vulnerability on write_client_connection function + - Little refactoring prometheus + * Fix c++ support + * Simplify (as agreed in Issue #666) + * Remove session id/allocation labels + * Remove per session metrics. We should later add more counters. 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider': diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 3565915c..4640225b 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -3721,16 +3721,6 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) send_message_to_redis(e->rch, "set", key, "%s lifetime=%lu", status, (unsigned long)lifetime); send_message_to_redis(e->rch, "publish", key, "%s lifetime=%lu", status, (unsigned long)lifetime); } -#endif -#if !defined(TURN_NO_PROMETHEUS) - { - // Set status on prometheus metric - if(ss->realm_options.name[0]) { - prom_set_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); - } else { - prom_set_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, status, (unsigned long)lifetime); - } - } #endif } } @@ -3778,19 +3768,14 @@ void turn_report_allocation_delete(void *a) #if !defined(TURN_NO_PROMETHEUS) { if(ss->realm_options.name[0]){ - // Set prometheus del metric and update status - prom_del_status(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); - // Set prometheus total traffic metrics - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); - prom_set_total_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + // Set prometheus traffic metrics + prom_set_finished_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); + prom_set_finished_traffic(ss->realm_options.name, (const char*)ss->username, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } else { - // Set prometheus del metric and update status - prom_del_status(NULL, (const char*)ss->username, (unsigned long long)ss->id, (const char *)"deleted"); - - // Set prometheus total traffic metrics - prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), true); - prom_set_total_traffic(NULL, (const char*)ss->username, (unsigned long long)ss->id, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); + // Set prometheus traffic metrics + prom_set_finished_traffic(NULL, (const char*)ss->username, (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes), false); + prom_set_finished_traffic(NULL, (const char*)ss->username, (unsigned long)(ss->t_peer_received_packets), (unsigned long)(ss->t_peer_received_bytes), (unsigned long)(ss->t_peer_sent_packets), (unsigned long)(ss->t_peer_sent_bytes), true); } } #endif @@ -3829,19 +3814,6 @@ void turn_report_session_usage(void *session, int force_invalid) send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); } #endif -#if !defined(TURN_NO_PROMETHEUS) - { - // Set prometheus traffic metrics - if(ss->realm_options.name[0]){ - prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); - prom_set_traffic(ss->realm_options.name, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); - } else { - prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->received_packets), (unsigned long)(ss->received_bytes), (unsigned long)(ss->sent_packets), (unsigned long)(ss->sent_bytes), false); - prom_set_traffic(NULL, (const char *)ss->username, (unsigned long long)(ss->id), (unsigned long)(ss->peer_received_packets), (unsigned long)(ss->peer_received_bytes), (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes), true); - } - } -#endif - ss->t_received_packets += ss->received_packets; ss->t_received_bytes += ss->received_bytes; ss->t_sent_packets += ss->sent_packets; diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 8bd82fa8..ac6f391c 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -3,59 +3,59 @@ #include "mainrelay.h" #include "prom_server.h" -prom_gauge_t *turn_status; -prom_gauge_t *turn_traffic_rcvp; -prom_gauge_t *turn_traffic_rcvb; -prom_gauge_t *turn_traffic_sentp; -prom_gauge_t *turn_traffic_sentb; +prom_counter_t *turn_traffic_rcvp; +prom_counter_t *turn_traffic_rcvb; +prom_counter_t *turn_traffic_sentp; +prom_counter_t *turn_traffic_sentb; -prom_gauge_t *turn_total_traffic_rcvp; -prom_gauge_t *turn_total_traffic_rcvb; -prom_gauge_t *turn_total_traffic_sentp; -prom_gauge_t *turn_total_traffic_sentb; +prom_counter_t *turn_traffic_peer_rcvp; +prom_counter_t *turn_traffic_peer_rcvb; +prom_counter_t *turn_traffic_peer_sentp; +prom_counter_t *turn_traffic_peer_sentb; -prom_gauge_t *turn_traffic_peer_rcvp; -prom_gauge_t *turn_traffic_peer_rcvb; -prom_gauge_t *turn_traffic_peer_sentp; -prom_gauge_t *turn_traffic_peer_sentb; +prom_counter_t *turn_total_traffic_rcvp; +prom_counter_t *turn_total_traffic_rcvb; +prom_counter_t *turn_total_traffic_sentp; +prom_counter_t *turn_total_traffic_sentb; + +prom_counter_t *turn_total_traffic_peer_rcvp; +prom_counter_t *turn_total_traffic_peer_rcvb; +prom_counter_t *turn_total_traffic_peer_sentp; +prom_counter_t *turn_total_traffic_peer_sentb; -prom_gauge_t *turn_total_traffic_peer_rcvp; -prom_gauge_t *turn_total_traffic_peer_rcvb; -prom_gauge_t *turn_total_traffic_peer_sentp; -prom_gauge_t *turn_total_traffic_peer_sentb; int start_prometheus_server(void){ if (turn_params.prometheus == 0){ - return 0; + return 1; } prom_collector_registry_default_init(); - // Create status gauge metric - turn_status = prom_collector_registry_must_register_metric(prom_gauge_new("turn_status", "Represents status", 5, (const char *[]) {"realm", "user", "allocation", "status", "lifetime" })); + + const char *label[] = {"realm", "user"}; - // Create traffic gauge metrics - turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create traffic counter metrics + turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents finsihed sessions received packets", 2, label)); + turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents finsihed sessions received bytes", 2, label)); + turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents finsihed sessions sent packets", 2, label)); + turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents finsihed sessions sent bytes", 2, label)); - // Create traffic for peers gauge metrics - turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create finsihed sessions traffic for peers counter metrics + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents finsihed sessions peer received packets", 2, label)); + turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents finsihed sessions peer received bytes", 2, label)); + turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents finsihed sessions peer sent packets", 2, label)); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents finsihed sessions peer sent bytes", 2, label)); - // Create total traffic gauge metrics - turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvp", "Represents total received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvb", "Represents total received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentp", "Represents total sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentb", "Represents total sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create total finished traffic counter metrics + turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvp", "Represents total finsihed sessions received packets", 0, NULL)); + turn_total_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvb", "Represents total finsihed sessions received bytes", 0, NULL)); + turn_total_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentp", "Represents total finsihed sessions sent packets", 0, NULL)); + turn_total_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_sentb", "Represents total finsihed sessions sent bytes", 0, NULL)); - // Create tota traffic for peers gauge metrics - turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvp", "Represents total peer received packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvb", "Represents total peer received bytes", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentp", "Represents total peer sent packets", 3, (const char *[]) {"realm", "user", "allocation" })); - turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentb", "Represents total peer sent bytes", 3, (const char *[]) {"realm", "user", "allocation" })); + // Create total finsihed sessions traffic for peers counter metrics + turn_total_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvp", "Represents total finsihed sessions peer received packets", 0, NULL)); + turn_total_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_rcvb", "Represents total finsihed sessions peer received bytes", 0, NULL)); + turn_total_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentp", "Represents total finsihed sessions peer sent packets", 0, NULL)); + turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_peer_sentb", "Represents total finsihed sessions peer sent bytes", 0, NULL)); promhttp_set_active_collector_registry(NULL); @@ -67,61 +67,31 @@ int start_prometheus_server(void){ return 0; } -void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime){ +void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ if (turn_params.prometheus == 1){ - char allocation_chars[1024]; - char lifetime_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - snprintf(lifetime_chars, sizeof(lifetime_chars), "%lu", lifetime); - - prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, lifetime_chars }); - } -} - -void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status){ - if (turn_params.prometheus == 0){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - prom_gauge_sub(turn_status, 1, (const char *[]) { realm , user, allocation_chars, (char *)"new", (char *)"600" }); - prom_gauge_add(turn_status, 1, (const char *[]) { realm , user, allocation_chars, status, NULL }); - } -} -void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ - if (turn_params.prometheus == 1){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); + const char *label[] = {realm, user}; if (peer){ - prom_counter_add(turn_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); - } else { - prom_counter_add(turn_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); - } - } -} + prom_counter_add(turn_traffic_peer_rcvp, rsvp, label); + prom_counter_add(turn_traffic_peer_rcvb, rsvb, label); + prom_counter_add(turn_traffic_peer_sentp, sentp, label); + prom_counter_add(turn_traffic_peer_sentb, sentb, label); -void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ - if (turn_params.prometheus == 1){ - char allocation_chars[1024]; - snprintf(allocation_chars, sizeof(allocation_chars), "%018llu", allocation); - - if (peer){ - prom_counter_add(turn_total_traffic_peer_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_peer_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_peer_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_peer_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_total_traffic_peer_rcvp, rsvp, NULL); + prom_counter_add(turn_total_traffic_peer_rcvb, rsvb, NULL); + prom_counter_add(turn_total_traffic_peer_sentp, sentp, NULL); + prom_counter_add(turn_total_traffic_peer_sentb, sentb, NULL); } else { - prom_counter_add(turn_total_traffic_rcvp, rsvp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_rcvb, rsvb, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_sentp, sentp, (const char *[]) { realm , user, allocation_chars }); - prom_counter_add(turn_total_traffic_sentb, sentb, (const char *[]) { realm , user, allocation_chars }); + prom_counter_add(turn_traffic_rcvp, rsvp, label); + prom_counter_add(turn_traffic_rcvb, rsvb, label); + prom_counter_add(turn_traffic_sentp, sentp, label); + prom_counter_add(turn_traffic_sentb, sentb, label); + + prom_counter_add(turn_total_traffic_rcvp, rsvp, NULL); + prom_counter_add(turn_total_traffic_rcvb, rsvb, NULL); + prom_counter_add(turn_total_traffic_sentp, sentp, NULL); + prom_counter_add(turn_total_traffic_sentb, sentb, NULL); } } } diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index cade4849..b092f23a 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -10,33 +10,43 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif #include #include #include +#ifdef __cplusplus +} +#endif /* __clplusplus */ #define DEFAULT_PROM_SERVER_PORT (9641) -extern prom_gauge_t *turn_status; +extern prom_counter_t *turn_new_allocation; +extern prom_counter_t *turn_refreshed_allocation; +extern prom_counter_t *turn_deleted_allocation; -extern prom_gauge_t *turn_traffic_rcvp; -extern prom_gauge_t *turn_traffic_rcvb; -extern prom_gauge_t *turn_traffic_sentp; -extern prom_gauge_t *turn_traffic_sentb; +extern prom_counter_t *turn_traffic_rcvp; +extern prom_counter_t *turn_traffic_rcvb; +extern prom_counter_t *turn_traffic_sentp; +extern prom_counter_t *turn_traffic_sentb; -extern prom_gauge_t *turn_total_traffic_rcvp; -extern prom_gauge_t *turn_total_traffic_rcvb; -extern prom_gauge_t *turn_total_traffic_sentp; -extern prom_gauge_t *turn_total_traffic_sentb; +extern prom_counter_t *turn_traffic_peer_rcvp; +extern prom_counter_t *turn_traffic_peer_rcvb; +extern prom_counter_t *turn_traffic_peer_sentp; +extern prom_counter_t *turn_traffic_peer_sentb; -extern prom_gauge_t *turn_traffic_peer_rcvp; -extern prom_gauge_t *turn_traffic_peer_rcvb; -extern prom_gauge_t *turn_traffic_peer_sentp; -extern prom_gauge_t *turn_traffic_peer_sentb; +extern prom_counter_t *turn_total_traffic_rcvp; +extern prom_counter_t *turn_total_traffic_rcvb; +extern prom_counter_t *turn_total_traffic_sentp; +extern prom_counter_t *turn_total_traffic_sentb; -extern prom_gauge_t *turn_total_traffic_peer_rcvp; -extern prom_gauge_t *turn_total_traffic_peer_rcvb; -extern prom_gauge_t *turn_total_traffic_peer_sentp; -extern prom_gauge_t *turn_total_traffic_peer_sentb; +extern prom_counter_t *turn_total_traffic_peer_rcvp; +extern prom_counter_t *turn_total_traffic_peer_rcvb; +extern prom_counter_t *turn_total_traffic_peer_sentp; +extern prom_counter_t *turn_total_traffic_peer_sentb; + +#define TURN_ALLOC_STR_MAX_SIZE (20) #ifdef __cplusplus extern "C" { @@ -45,10 +55,9 @@ extern "C" { int start_prometheus_server(void); -void prom_set_status(const char* realm, const char* user, unsigned long long allocation, const char* status, unsigned long lifetime); -void prom_del_status(const char* realm, const char* user, unsigned long long allocation, const char* status); -void prom_set_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); -void prom_set_total_traffic(const char* realm, const char* user, unsigned long long allocation, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); +void prom_set_status(int refresh); +void prom_del_status(); +void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); #endif /* TURN_NO_PROMETHEUS */ From bca1c9a97d48ff02f2fc0f18c4cf863e7614c519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 08:27:15 +0000 Subject: [PATCH 121/128] Travis changes --- .travis.yml | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index baf01ce9..33f0cda6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,48 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink protobuf; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install mysql sqlite hiredis; fi -matrix: +jobs: include: + - name: ubuntu focal AMD64 C + os: linux + arch: amd64 + dist: focal + sudo: required + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev + - name: ubuntu Focal AMD64 C++ + os: linux + arch: amd64 + dist: focal + sudo: required + env: + - CC=g++ + addons: + apt: + packages: + - mysql-client + - debhelper + - dpkg-dev + - libssl-dev + - libevent-dev + - sqlite3 + - libsqlite3-dev + - postgresql-client + - libpq-dev + - libmysqlclient-dev + - libhiredis-dev - os: linux arch: amd64 dist: bionic From c1437902e225cc0ce9c8be56523950d758ea66b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 10:38:29 +0100 Subject: [PATCH 122/128] Remove earlier deleted function definitions --- src/apps/relay/prom_server.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/apps/relay/prom_server.h b/src/apps/relay/prom_server.h index b092f23a..c70473bf 100644 --- a/src/apps/relay/prom_server.h +++ b/src/apps/relay/prom_server.h @@ -55,8 +55,6 @@ extern "C" { int start_prometheus_server(void); -void prom_set_status(int refresh); -void prom_del_status(); void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer); #endif /* TURN_NO_PROMETHEUS */ From 0c9e6f9bff8d314e870f27abb35159d30bc53597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 10:33:18 +0100 Subject: [PATCH 123/128] Bump version in rpm --- rpm/turnserver.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index 09ea214b..0399d196 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -298,6 +298,8 @@ fi %{_includedir}/turn/client/TurnMsgLib.h %changelog +* Sun jan 10 2 2021 Mészáros Mihály + - Sync to 4.5.2 * Sat Mar 2 2019 Mészáros Mihály - Sync to 4.5.1.1 * Thu Dec 6 2018 Mészáros Mihály From fe3ed44089ac85cfe8cb0da7aa621bfc35986582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 16:00:00 +0100 Subject: [PATCH 124/128] Update date in ChangeLog --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 021b9c0e..8cf6e2b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -24/06/2020 Oleg Moskalenko Mihály Mészáros +10/01/2021 Oleg Moskalenko Mihály Mészáros Version 4.5.2 'dan Eider': - fix null pointer dereference in case of out of memory. (thanks to Thomas Moeller for the report) - merge PR #517 (by wolmi) From e367fabb0e83b4dd4b984efa094abf8d1fa5bb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 17:20:40 +0100 Subject: [PATCH 125/128] Fix typo --- src/apps/relay/mainrelay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index d4c794ed..5a75cfd1 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -464,7 +464,7 @@ static char Usage[] = "Usage: turnserver [options]\n" " -v, --verbose 'Moderate' verbose mode.\n" " -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n" " -o, --daemon Start process as daemon (detach from current shell).\n" -" --systemd Notify systemd about server status. (Use only in forground!)\n" +" --systemd Notify systemd about server status. (Use only in foreground!)\n" " --no-software-attribute Production mode: hide the software version (formerly --prod).\n" " -f, --fingerprint Use fingerprints in the TURN messages.\n" " -a, --lt-cred-mech Use the long-term credential mechanism.\n" From a66e5cd286db1c6d5de4b7fe04371d61efecf73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 20:11:41 +0100 Subject: [PATCH 126/128] Remove pid handling from systemd service files --- examples/etc/coturn.service | 3 +-- rpm/turnserver.service.fc | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/etc/coturn.service b/examples/etc/coturn.service index 3fb2a39d..56118e67 100644 --- a/examples/etc/coturn.service +++ b/examples/etc/coturn.service @@ -11,8 +11,7 @@ User=turnserver Group=turnserver Type=notify RuntimeDirectory=turnserver -PIDFile=/run/turnserver/turnserver.pid -ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver.conf --pidfile /run/turnserver/turnserver.pid +ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver.conf Restart=on-failure InaccessibleDirectories=/home PrivateTmp=yes diff --git a/rpm/turnserver.service.fc b/rpm/turnserver.service.fc index 6e9301f6..99f3e922 100644 --- a/rpm/turnserver.service.fc +++ b/rpm/turnserver.service.fc @@ -8,7 +8,6 @@ User=turnserver Group=turnserver Type=notify EnvironmentFile=/etc/sysconfig/turnserver -PIDFile=/var/run/turnserver/turnserver.pid ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS ExecStopPost=/usr/bin/rm -f /var/run/turnserver/turnserver.pid Restart=on-abort From 104ab83f090c49021e704502c1944b2a1826b8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 20:45:28 +0100 Subject: [PATCH 127/128] Automatically notify systemd if compiled --- README.turnserver | 6 ++- examples/etc/coturn.service | 2 +- man/man1/turnadmin.1 | 32 +++++++------- man/man1/turnserver.1 | 86 ++++++++++++++++++------------------- man/man1/turnutils.1 | 61 +++++++++++++------------- rpm/turnserver.service.fc | 2 +- src/apps/relay/mainrelay.c | 11 +---- src/apps/relay/mainrelay.h | 3 -- src/apps/relay/netengine.c | 2 - 9 files changed, 94 insertions(+), 111 deletions(-) diff --git a/README.turnserver b/README.turnserver index 8bbda8e6..4670952d 100644 --- a/README.turnserver +++ b/README.turnserver @@ -27,6 +27,10 @@ to run the programs. The scripts are meant to be run from examples/ sub-director $ cd examples $ ./scripts/secure_relay.sh +SYSTEMD + +If the systemd development library is available, then it will notify systemd about the server status. + RUNNING THE TURN SERVER Options note: turnserver has long and short option names, for most options. @@ -158,8 +162,6 @@ Flags: -o, --daemon Run server as daemon. ---systemd Notify systemd about server status. (Use only in foreground!) - --no-software-attribute Production mode: hide the software version. -f, --fingerprint Use fingerprints in the TURN messages. If an incoming request diff --git a/examples/etc/coturn.service b/examples/etc/coturn.service index 56118e67..12e64ff3 100644 --- a/examples/etc/coturn.service +++ b/examples/etc/coturn.service @@ -11,7 +11,7 @@ User=turnserver Group=turnserver Type=notify RuntimeDirectory=turnserver -ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver.conf +ExecStart=/usr/bin/turnserver -c /etc/turnserver.conf Restart=on-failure InaccessibleDirectories=/home PrivateTmp=yes diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 9205225f..9fc0b9e6 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 January 2021" "" "" +.TH TURN 1 "10 January 2021" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage @@ -48,8 +48,8 @@ is equivalent to: .fi You have always the use the \fB\-r\fP option with commands for long term credentials \- because data for multiple realms can be stored in the same database. -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnadmin \fP\- a TURN relay administration tool. @@ -288,8 +288,8 @@ $ \fIturnadmin\fP \fB\-\-file\-key\-path\fP \fB\-v\fP Help: .PP $ \fIturnadmin\fP \fB\-h\fP -.PP -======================================= +.SH ======================================= + .SS DOCS After installation, run the \fIcommand\fP: @@ -301,8 +301,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnadmin\fP .PP to see the man page. -.PP -===================================== +.SH ===================================== + .SS FILES /etc/turnserver.conf @@ -314,8 +314,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -===================================== +.SH ===================================== + .SS DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -323,14 +323,13 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -====================================== +.SH ====================================== + .SS SEE ALSO \fIturnserver\fP, \fIturnutils\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -344,9 +343,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.RE -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 1a80a8f0..b910d969 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 January 2021" "" "" +.TH TURN 1 "10 January 2021" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client @@ -40,6 +40,9 @@ to run the programs. The scripts are meant to be run from examples/ sub\-directo .PP $ cd examples $ ./scripts/secure_relay.sh +.SH SYSTEMD + +If the systemd development library is available, then it will notify systemd about the server status. .SH RUNNING THE TURN SERVER Options note: \fIturnserver\fP has long and short option names, for most options. @@ -78,7 +81,8 @@ is equivalent to: .fam T .fi -===================================== +.SH ===================================== + .SS NAME \fB \fBturnserver \fP\- a TURN relay server implementation. @@ -230,10 +234,6 @@ Extra verbose mode, very annoying and not recommended. .B \fB\-o\fP, \fB\-\-daemon\fP Run server as daemon. -.TP -.B -\fB\-\-systemd\fP -Notify systemd about server status. (Use only in foreground!) .PP \fB\-\-no\-software\-attribute\fP Production mode: hide the software version. .TP @@ -864,15 +864,15 @@ By default it is disabled for security resons! .B \fB\-\-ne\fP=[1|2|3] Set network engine type for the process (for internal purposes). -.PP -================================== +.SH ================================== + .SH LOAD BALANCE AND PERFORMANCE TUNING This topic is covered in the wiki page: .PP https://github.com/coturn/coturn/wiki/turn_performance_and_load_balance -.PP -=================================== +.SH =================================== + .SH WEBRTC USAGE This is a set of notes for the WebRTC users: @@ -909,8 +909,8 @@ Usually WebRTC uses fingerprinting (\fB\-f\fP). .IP 5) 4 \fB\-\-min\-port\fP and \fB\-\-max\-port\fP may be needed if you want to limit the relay endpoints ports number range. -.PP -=================================== +.SH =================================== + .SH TURN REST API In WebRTC, the browser obtains the TURN connection information from the web @@ -1048,8 +1048,8 @@ examples/scripts/restapi/shared_secret_maintainer.pl . .PP A very important thing is that the nonce must be totally random and it must be different for different clients and different sessions. -.PP -=================================== +.SH =================================== + .SH DATABASES For the user database, the \fIturnserver\fP has the following \fIoptions\fP: @@ -1112,8 +1112,8 @@ it will set the users for you (see the \fIturnadmin\fP manuals). If you are usin \fIturnserver\fP or \fIturnadmin\fP will initialize the empty database, for you, when started. The TURN server installation process creates an empty initialized SQLite database in the default location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system). -.PP -================================= +.SH ================================= + .SH ALPN The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when @@ -1122,16 +1122,16 @@ ClientHello message that contains one or both of those ALPNs, then the server chooses the first stun.* label and sends it back (in the ServerHello) in the ALPN extension field. If no stun.* label is found, then the server does not include the ALPN information into the ServerHello. -.PP -================================= +.SH ================================= + .SH LIBRARIES In the lib/ sub\-directory the build process will create TURN client messaging library. In the include/ sub\-directory, the necessary include files will be placed. The C++ wrapper for the messaging functionality is located in TurnMsgLib.h header. An example of C++ code can be found in stunclient.c file. -.PP -================================= +.SH ================================= + .SH DOCS After installation, run the command: @@ -1146,8 +1146,8 @@ to see the man page. .PP In the docs/html subdirectory of the original archive tree, you will find the client library reference. After the installation, it will be placed in PREFIX/share/doc/\fIturnserver\fP/html. -.PP -================================= +.SH ================================= + .SH LOGS When the \fBTURN Server\fP starts, it makes efforts to create a log file turn_.log @@ -1170,8 +1170,8 @@ log messages are sent only to the standard output of the process. .PP This behavior can be controlled by \fB\-\-log\-file\fP, \fB\-\-syslog\fP and \fB\-\-no\-stdout\-log\fP \fIoptions\fP. -.PP -================================= +.SH ================================= + .SH HTTPS MANAGEMENT INTERFACE The \fIturnserver\fP process provides an HTTPS Web access as statistics and basic @@ -1184,8 +1184,8 @@ populated with the admin user \fBaccount\fP(s). An admin user can be a superuser (if not assigned to a particular realm) or a restricted user (if assigned to a realm). The restricted admin users can perform only limited actions, within their corresponding realms. -.PP -================================= +.SH ================================= + .SH TELNET CLI The \fIturnserver\fP process provides a telnet CLI access as statistics and basic management @@ -1193,8 +1193,8 @@ interface. By default, the \fIturnserver\fP starts a telnet CLI listener on IP 1 port 5766. That can be changed by the command\-cline \fIoptions\fP of the \fIturnserver\fP process (see \fB\-\-cli\-ip\fP and \fB\-\-cli\-port\fP \fIoptions\fP). The full list of telnet CLI commands is provided in "help" command output in the telnet CLI. -.PP -================================= +.SH ================================= + .SH CLUSTERS \fBTURN Server\fP can be a part of the cluster installation. But, to support the "even port" functionality @@ -1203,8 +1203,8 @@ in "help" command output in the telnet CLI. the RTP and RTCP relaying endpoints must be allocated on the same relay IP. It would be possible to design a scheme with the application\-level requests forwarding (and we may do that later) but it would affect the performance. -.PP -================================= +.SH ================================= + .SH FILES /etc/turnserver.conf @@ -1216,8 +1216,8 @@ it would affect the performance. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -================================= +.SH ================================= + .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -1225,16 +1225,15 @@ it would affect the performance. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -================================= +.SH ================================= + .SH STANDARDS obsolete STUN RFC 3489 .PP new STUN RFC 5389 -.PP -TURN RFC 5766 -.PP +.SH TURN RFC 5766 + TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -1242,14 +1241,13 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.PP -================================= +.SH ================================= + .SH SEE ALSO \fIturnadmin\fP, \fIturnutils\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -1263,8 +1261,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index d9bd86a9..b3ba1fa2 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "08 January 2021" "" "" +.TH TURN 1 "10 January 2021" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -63,8 +63,8 @@ script in examples/scripts/oauth.sh. .RE .PP -.RS -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only. @@ -276,8 +276,8 @@ the ORIGIN STUN attribute value. Bandwidth for the bandwidth request in ALLOCATE. The default value is zero. .PP See the examples in the "examples/scripts" directory. -.PP -====================================== +.SH ====================================== + .SS NAME \fB \fBturnutils_peer \fP\- a simple UDP\-only echo backend server. @@ -314,8 +314,8 @@ If no listener \fBaddress\fP(es) defined, then it listens on all IPv4 and IPv6 a .B \fB\-v\fP Verbose -.PP -======================================== +.SH ======================================== + .SS NAME \fB \fBturnutils_stunclient \fP\- a basic STUN client. @@ -354,8 +354,8 @@ and if it finds that the STUN server supports RFC 5780 requests with different parameters, to demonstrate the NAT discovery capabilities. .PP This utility does not support the "old" "classic" STUN protocol (RFC 3489). -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_rfc5769check \fP\- a utility that tests the correctness of STUN protocol implementation. @@ -380,8 +380,8 @@ check procedure, it is not copied to the installation destination. Usage: .PP $ \fIturnutils_rfc5769check\fP -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_natdiscovery \fP\- a utility that discovers NAT mapping and filtering @@ -462,8 +462,8 @@ Used by mapping lifetime behavior discovery Usage: .PP $ \fIturnutils_natdiscovery\fP \fB\-m\fP \fB\-f\fP stun.example.com -.PP -===================================== +.SH ===================================== + .SS NAME \fB \fBturnutils_oauth \fP\- a utility that helps OAuth access_token generation/encryption and validation/decyption @@ -568,8 +568,8 @@ stun client hmac algorithm Usage: .PP $ \fIturnutils_natdiscovery\fP -.PP -=================================== +.SH =================================== + .SH DOCS After installation, run the command: @@ -581,8 +581,8 @@ or in the project root directory: $ man \fB\-M\fP man \fIturnutils\fP .PP to see the man page. -.PP -===================================== +.SH ===================================== + .SH FILES /etc/turnserver.conf @@ -594,8 +594,8 @@ to see the man page. /var/lib/turn/turndb .PP /usr/local/etc/turnserver.conf -.PP -================================= +.SH ================================= + .SH DIRECTORIES /usr/local/share/\fIturnserver\fP @@ -603,14 +603,13 @@ to see the man page. /usr/local/share/doc/\fIturnserver\fP .PP /usr/local/share/examples/\fIturnserver\fP -.PP -=================================== +.SH =================================== + .SH STANDARDS new STUN RFC 5389 -.PP -TURN RFC 5766 -.PP +.SH TURN RFC 5766 + TURN\-TCP extension RFC 6062 .PP TURN IPv6 extension RFC 6156 @@ -618,14 +617,13 @@ TURN IPv6 extension RFC 6156 STUN/TURN test vectors RFC 5769 .PP STUN NAT behavior discovery RFC 5780 -.PP -==================================== +.SH ==================================== + .SH SEE ALSO \fIturnserver\fP, \fIturnadmin\fP -.RE -.PP -====================================== +.SH ====================================== + .SS WEB RESOURCES project page: @@ -639,9 +637,8 @@ https://github.com/coturn/coturn/wiki forum: .PP https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/ -.RE -.PP -====================================== +.SH ====================================== + .SS AUTHORS Oleg Moskalenko diff --git a/rpm/turnserver.service.fc b/rpm/turnserver.service.fc index 99f3e922..6eb53bdf 100644 --- a/rpm/turnserver.service.fc +++ b/rpm/turnserver.service.fc @@ -8,7 +8,7 @@ User=turnserver Group=turnserver Type=notify EnvironmentFile=/etc/sysconfig/turnserver -ExecStart=/usr/bin/turnserver --systemd -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS +ExecStart=/usr/bin/turnserver -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS ExecStopPost=/usr/bin/rm -f /var/run/turnserver/turnserver.pid Restart=on-abort diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 5a75cfd1..2118b60a 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -170,8 +170,7 @@ DEFAULT_CPUS_NUMBER, 0, /* no_dynamic_ip_list */ 0, /* no_dynamic_realms */ -0, /* log_binding */ -0 /* systemd */ +0 /* log_binding */ }; //////////////// OpenSSL Init ////////////////////// @@ -464,7 +463,6 @@ static char Usage[] = "Usage: turnserver [options]\n" " -v, --verbose 'Moderate' verbose mode.\n" " -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n" " -o, --daemon Start process as daemon (detach from current shell).\n" -" --systemd Notify systemd about server status. (Use only in foreground!)\n" " --no-software-attribute Production mode: hide the software version (formerly --prod).\n" " -f, --fingerprint Use fingerprints in the TURN messages.\n" " -a, --lt-cred-mech Use the long-term credential mechanism.\n" @@ -815,8 +813,7 @@ enum EXTRA_OPTS { NO_HTTP_OPT, SECRET_KEY_OPT, ACME_REDIRECT_OPT, - LOG_BINDING_OPT, - SYSTEMD_OPT + LOG_BINDING_OPT }; struct myoption { @@ -952,7 +949,6 @@ static const struct myoption long_options[] = { { "keep-address-family", optional_argument, NULL, 'K' }, { "acme-redirect", required_argument, NULL, ACME_REDIRECT_OPT }, { "log-binding", optional_argument, NULL, LOG_BINDING_OPT }, - { "systemd", optional_argument, NULL, SYSTEMD_OPT }, { NULL, no_argument, NULL, 0 } }; @@ -1610,9 +1606,6 @@ static void set_option(int c, char *value) case LOG_BINDING_OPT: turn_params.log_binding = get_bool_value(value); break; - case SYSTEMD_OPT: - turn_params.systemd = get_bool_value(value); - break; /* these options have been already taken care of before: */ case 'l': diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index be467584..cf229fe5 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -338,9 +338,6 @@ typedef struct _turn_params_ { int no_dynamic_realms; vint log_binding; - - vint systemd; - } turn_params_t; extern turn_params_t turn_params; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 1590dda4..373840e9 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1591,7 +1591,6 @@ void run_listener_server(struct listener_server *ls) while (!turn_params.stop_turn_server) { #if !defined(TURN_NO_SYSTEMD) - if(turn_params.systemd) sd_notify (0, "READY=1"); #endif @@ -1607,7 +1606,6 @@ void run_listener_server(struct listener_server *ls) } #if !defined(TURN_NO_SYSTEMD) - if(turn_params.systemd) sd_notify (0, "STOPPING=1"); #endif } From 060bf187879fd1a6386012f4c5a7494824ebe5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Sun, 10 Jan 2021 10:25:19 +0100 Subject: [PATCH 128/128] Changelog for CVE-2020-26262 --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8cf6e2b4..77703189 100644 --- a/ChangeLog +++ b/ChangeLog @@ -45,6 +45,11 @@ Version 4.5.2 'dan Eider': * Simplify (as agreed in Issue #666) * Remove session id/allocation labels * Remove per session metrics. We should later add more counters. + - Fix CVE-2020-26262 (credits: Enable-Security) + * Fix ipv6 ::1 loopback check + * Not allow allocate peer address 0.0.0.0/8 and ::/128 + * For more details see the github security advisory: + https://github.com/coturn/coturn/security/advisories/GHSA-6g6j-r9rf-cm7p 24/06/2020 Oleg Moskalenko Mihály Mészáros Version 4.5.1.3 'dan Eider':