diff --git a/ChangeLog b/ChangeLog index 5e16ef9..60e2bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,6 @@ 3/15/2015 Oleg Moskalenko -Version 4.4.3.1 'Ardee West': - - SCTP support compilation option; +Version 4.4.4.1 'Ardee West': + - 'native' SCTP support; 2/28/2015 Oleg Moskalenko Version 4.4.2.3 'Ardee West': diff --git a/INSTALL b/INSTALL index fa548cb..00c9fb2 100644 --- a/INSTALL +++ b/INSTALL @@ -1194,16 +1194,9 @@ newer has to be used. See OPENSSL section for the OpenSSL upgrade hints. XXV. SCTP support -Starting with version 4.4.3.1, the TURN server can have 'native' SCTP support -compiling in (if the platform supports SCTP). If compiled with TURN_SCTP -environment variable set to a non-empty value, then SCTP replaces TCP in the -TURN client - TURN server communications: - - $ TURN_SCTP=1 ./configure - $ make - -With this option, on the client side, the TURN server will support UDP, DTLS, -SCTP and TLS-over-SCTP. +Starting with version 4.4.3.1, the TURN server supports 'native' SCTP. +On the client side, the TURN server, additionally, supports SCTP and +TLS-over-SCTP. The relay side is not changing - the relay communications will still be UDP or TCP. diff --git a/README.turnutils b/README.turnutils index a23ddbb..65c332b 100644 --- a/README.turnutils +++ b/README.turnutils @@ -56,12 +56,15 @@ Flags: -t Use TCP for communications between client and TURN server (default is UDP). +-b Use SCTP for communications between client and TURN server (default is UDP). + -T Use TCP for the relay transport (default - UDP). Implies options -t, -y, -c, - and ignores flags and options -s, -e, -r and -g. + and ignores flags and options -s, -e, -r and -g. Can be used together + with -b. -P Passive TCP (RFC6062 with active peer). Implies -T. --S Secure SSL connection: SSL/TLS for TCP, DTLS for UDP. +-S Secure SSL connection: SSL/TLS for TCP, DTLS for UDP, TLS/SCTP for SCTP. -U Secure unencrypted connection (suite eNULL): SSL/TLS for TCP, DTLS for UDP. diff --git a/configure b/configure index 1cb67df..61a25a5 100755 --- a/configure +++ b/configure @@ -1157,22 +1157,11 @@ if [ -z "${LDCONFIG}" ] ; then fi fi -############################### -# SCTP -############################### - -if [ -z "${TURN_SCTP}" ] ; then - echo "no SCTP support" -else - echo "compiling with native SCTP client-side support (in place of TCP)" - TURN_SCTP="-DTURN_SCTP" -fi - ############################### # So, what we have now: ############################### -OSCFLAGS="${OSCFLAGS} ${TURN_SCTP} ${TURN_NO_THREAD_BARRIERS} ${TURN_NO_DTLS} ${TURN_NO_GCM} ${TURN_NO_TLS} -DINSTALL_PREFIX=${PREFIX} -DTURNDB=${TURNDBDIR}/turndb" +OSCFLAGS="${OSCFLAGS} ${TURN_NO_THREAD_BARRIERS} ${TURN_NO_DTLS} ${TURN_NO_GCM} ${TURN_NO_TLS} -DINSTALL_PREFIX=${PREFIX} -DTURNDB=${TURNDBDIR}/turndb" if ! [ -z "${TURN_ACCEPT_RPATH}" ] ; then if [ -z "${TURN_DISABLE_RPATH}" ] ; then diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 14c658d..463a0b4 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "18 February 2015" "" "" +.TH TURN 1 "15 March 2015" "" "" .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 12ddcd1..158ac13 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "18 February 2015" "" "" +.TH TURN 1 "15 March 2015" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index e381670..aaf9ea3 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "18 February 2015" "" "" +.TH TURN 1 "15 March 2015" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -70,9 +70,14 @@ Flags: Use TCP for communications between client and TURN server (default is UDP). .TP .B +\fB\-b\fP +Use SCTP for communications between client and TURN server (default is UDP). +.TP +.B \fB\-T\fP Use TCP for the relay transport (default \- UDP). Implies options \fB\-t\fP, \fB\-y\fP, \fB\-c\fP, -and ignores flags and options \fB\-s\fP, \fB\-e\fP, \fB\-r\fP and \fB\-g\fP. +and ignores flags and options \fB\-s\fP, \fB\-e\fP, \fB\-r\fP and \fB\-g\fP. Can be used together +with \fB\-b\fP. .TP .B \fB\-P\fP @@ -80,7 +85,7 @@ Passive TCP (RFC6062 with active peer). Implies \fB\-T\fP. .TP .B \fB\-S\fP -Secure SSL connection: SSL/TLS for TCP, DTLS for UDP. +Secure SSL connection: SSL/TLS for TCP, DTLS for UDP, TLS/SCTP for SCTP. .TP .B \fB\-U\fP diff --git a/rpm/build.settings.sh b/rpm/build.settings.sh index df864e5..2ecdefd 100755 --- a/rpm/build.settings.sh +++ b/rpm/build.settings.sh @@ -2,7 +2,7 @@ # Common settings script. -TURNVERSION=4.4.3.1 +TURNVERSION=4.4.4.1 BUILDDIR=~/rpmbuild ARCH=`uname -p` TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn diff --git a/rpm/turnserver.spec b/rpm/turnserver.spec index be515ff..d477316 100644 --- a/rpm/turnserver.spec +++ b/rpm/turnserver.spec @@ -1,5 +1,5 @@ Name: turnserver -Version: 4.4.3.1 +Version: 4.4.4.1 Release: 0%{dist} Summary: Coturn TURN Server @@ -289,7 +289,7 @@ fi %changelog * Sun Mar 15 2015 Oleg Moskalenko - - Sync to 4.4.3.1 + - Sync to 4.4.4.1 * Sat Feb 28 2015 Oleg Moskalenko - Sync to 4.4.2.3 * Wed Feb 18 2015 Oleg Moskalenko diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index 2639354..4e4b5d3 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -777,13 +777,13 @@ static int create_server_socket(dtls_listener_relay_server_type* server, int rep perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind UDP/DTLS listener socket to addr %s\n",saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind DTLS/UDP listener socket to addr %s\n",saddr); if(addr_bind_cycle++verbose, &server->addr,"UDP/DTLS listener opened on"); + addr_debug_print(server->verbose, &server->addr,"DTLS/UDP listener opened on"); else if(!turn_params.no_dtls) addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on"); else if(!turn_params.no_udp) @@ -868,7 +868,7 @@ static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_ if (!turn_params.no_udp && !turn_params.no_dtls) addr_debug_print(server->verbose, &server->addr, - "UDP/DTLS listener opened on "); + "DTLS/UDP listener opened on "); else if (!turn_params.no_dtls) addr_debug_print(server->verbose, &server->addr, "DTLS listener opened on "); @@ -920,7 +920,7 @@ static int init_server(dtls_listener_relay_server_type* server, if(ifname) STRCPY(server->ifname,ifname); if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a UDP/DTLS listener for address: %s\n",local_address); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a DTLS/UDP listener for address: %s\n",local_address); return -1; } diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 206e107..2899e90 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -1614,7 +1614,7 @@ static void print_features(unsigned long mfn) { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nRFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server\nVersion %s\n",TURN_SOFTWARE); TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nMax number of open files/sockets allowed for this process: %lu\n",mfn); - if(turn_params.net_engine_version == 1) + if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) mfn = mfn/3; else mfn = mfn/2; @@ -1690,11 +1690,7 @@ static void set_network_engine(void) turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT; #if defined(SO_REUSEPORT) #if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__) - if(CLIENT_STREAM_SOCKET_PROTOCOL == IPPROTO_IP) { - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD; - } else { - turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION; - } + turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD; #else /* BSD ? */ turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION; #endif /* Linux */ diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index fbb55a1..3f71bfb 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -1842,16 +1842,20 @@ void setup_server(void) if(udp_relay_servers[0]) { tot = get_real_udp_relay_servers_number(); } - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot); + if(tot) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot); + } } { int tot = get_real_general_relay_servers_number(); - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total General servers: %d\n",(int)tot); - int i; - for(i = 0;iremote_addr),(u08bits*)sraddr); if (events & BEV_EVENT_EOF) { if(server->verbose) - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP socket closed remotely %s\n",(unsigned long long)(ss->id),sraddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP (or SCTP) socket closed remotely %s\n",(unsigned long long)(ss->id),sraddr); if(s == ss->client_socket) { shutdown_client_connection(server, ss, 0, "TCP connection closed by client (callback)"); } else if(s == ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) { @@ -2726,12 +2722,12 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg) } } else if (events & BEV_EVENT_ERROR) { if(EVUTIL_SOCKET_ERROR()) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"session %018llu: TCP socket error: %s %s\n",(unsigned long long)(ss->id), + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"session %018llu: TCP (or SCTP) socket error: %s %s\n",(unsigned long long)(ss->id), evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), sraddr); } else if(server->verbose) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP socket disconnected: %s\n",(unsigned long long)(ss->id),sraddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP (or SCTP) socket disconnected: %s\n",(unsigned long long)(ss->id),sraddr); } - shutdown_client_connection(server, ss, 0, "TCP socket buffer operation error (callback)"); + shutdown_client_connection(server, ss, 0, "TCP (or SCTP) socket buffer operation error (callback)"); } } } diff --git a/src/apps/relay/tls_listener.c b/src/apps/relay/tls_listener.c index 12d874b..8faf28c 100644 --- a/src/apps/relay/tls_listener.c +++ b/src/apps/relay/tls_listener.c @@ -38,6 +38,8 @@ #include +#include + /////////////////////////////////////////////////// #define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__) @@ -50,6 +52,7 @@ struct tls_listener_relay_server_info ioa_engine_handle e; int verbose; struct evconnlistener *l; + struct evconnlistener *sctp_l; struct message_to_relay sm; ioa_engine_new_connection_event_handler connect_cb; struct relay_server *relay_server; @@ -149,13 +152,13 @@ static int create_server_listener(tls_listener_relay_server_type* server) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); - TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr); + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind TLS/TCP listener socket to addr %s\n",saddr); if(addr_bind_cycle++verbose, &server->addr,"TCP/TLS listener opened on "); + addr_debug_print(server->verbose, &server->addr,"TLS/TCP listener opened on "); else if(!turn_params.no_tls) addr_debug_print(server->verbose, &server->addr,"TLS listener opened on "); else if(!turn_params.no_tcp) @@ -187,6 +190,78 @@ static int create_server_listener(tls_listener_relay_server_type* server) { return 0; } +static int sctp_create_server_listener(tls_listener_relay_server_type* server) { + + FUNCSTART; + + if(!server) return -1; + + evutil_socket_t tls_listen_fd = -1; + + tls_listen_fd = socket(server->addr.ss.sa_family, SCTP_CLIENT_STREAM_SOCKET_TYPE, SCTP_CLIENT_STREAM_SOCKET_PROTOCOL); + if (tls_listen_fd < 0) { + perror("socket"); + return -1; + } + + if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname); + } + + if(addr_bind(tls_listen_fd,&server->addr,1)<0) { + close(tls_listen_fd); + return -1; + } + + socket_tcp_set_keepalive(tls_listen_fd); + + socket_set_nonblocking(tls_listen_fd); + + { + struct sctp_paddrparams heartbeat; + ns_bzero(&heartbeat, sizeof(struct sctp_paddrparams)); + + heartbeat.spp_flags = SPP_HB_ENABLE; + heartbeat.spp_hbinterval = 5000; + heartbeat.spp_pathmaxrxt = 5; + + /*Set Heartbeats*/ + if(setsockopt(tls_listen_fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS , &heartbeat, sizeof(heartbeat)) != 0) + perror("setsockopt"); + } + + { + struct sctp_rtoinfo rtoinfo; + ns_bzero(&rtoinfo, sizeof(struct sctp_rtoinfo)); + + rtoinfo.srto_max = 5000; + + /*Set rto_max*/ + if(setsockopt(tls_listen_fd, IPPROTO_SCTP, SCTP_RTOINFO , &rtoinfo, sizeof(rtoinfo)) != 0) + perror("setsockopt"); + } + + server->sctp_l = evconnlistener_new(server->e->event_base, + server_input_handler, server, + LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, + 1024, tls_listen_fd); + + if(!(server->sctp_l)) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create SCTP listener\n"); + socket_closesocket(tls_listen_fd); + return -1; + } + + if (!turn_params.no_tls) + addr_debug_print(server->verbose, &server->addr, "TLS/SCTP listener opened on "); + else + addr_debug_print(server->verbose, &server->addr, "SCTP listener opened on "); + + FUNCEND; + + return 0; +} + static int init_server(tls_listener_relay_server_type* server, const char* ifname, const char *local_address, @@ -212,6 +287,8 @@ static int init_server(tls_listener_relay_server_type* server, server->e = e; + sctp_create_server_listener(server); + return create_server_listener(server); } diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 3d0344d..d7ef355 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -55,6 +55,7 @@ int do_not_use_channel=0; int c2c=0; int clnet_verbose=TURN_VERBOSE_NONE; int use_tcp=0; +int use_sctp=0; int use_secure=0; int hang_on=0; ioa_addr peer_addr; @@ -112,8 +113,9 @@ static char Usage[] = "Usage: uclient [flags] [options] turn-server-ip-address\n" "Flags:\n" " -t TCP (default - UDP).\n" + " -b SCTP (default - UDP).\n" " -T TCP relay transport (default - UDP). Implies options -t, -y, -c, and ignores \n" - " options -s, -e, -r and -g.\n" + " options -s, -e, -r and -g. Can be used together with -b\n" " -P Passive TCP (RFC6062 with active peer). Implies -T.\n" " -S Secure connection: TLS for TCP, DTLS for UDP.\n" " -U Secure connection with eNULL cipher.\n" @@ -218,7 +220,7 @@ int main(int argc, char **argv) ns_bzero(local_addr, sizeof(local_addr)); - while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHYKMRIGBJ")) != -1) { + while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:bZvsyhcxXgtTSAPDNOUHYKMRIGBJ")) != -1) { switch (c){ case 'J': { @@ -366,6 +368,10 @@ int main(int argc, char **argv) case 't': use_tcp = 1; break; + case 'b': + use_sctp = 1; + use_tcp = 1; + break; case 'P': passive_tcp = 1; /* implies 'T': */ diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index f934571..a3fb92a 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -230,8 +230,8 @@ static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address, ns_bzero(&local_addr, sizeof(ioa_addr)); clnet_fd = socket(remote_addr.ss.sa_family, - use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE, - use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL); + use_sctp ? SCTP_CLIENT_STREAM_SOCKET_TYPE : (use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE), + use_sctp ? SCTP_CLIENT_STREAM_SOCKET_PROTOCOL : (use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL)); if (clnet_fd < 0) { perror("socket"); exit(-1); diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index fe930f3..995f369 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -52,6 +52,7 @@ extern int clmessage_length; extern int do_not_use_channel; extern int clnet_verbose; extern int use_tcp; +extern int use_sctp; extern int use_secure; extern char cert_file[1025]; extern char pkey_file[1025]; diff --git a/src/ns_turn_defs.h b/src/ns_turn_defs.h index 3a4325b..8210615 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.4.3.1" +#define TURN_SERVER_VERSION "4.4.4.1" #define TURN_SERVER_VERSION_NAME "Ardee West" #define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'" @@ -218,19 +218,14 @@ typedef u32bits turn_time_t; //////////////////////////////////////////////////////// -//#define DGRAM_SOCKET_TYPE SOCK_SEQPACKET -//#define DGRAM_SOCKET_PROTOCOL IPPROTO_SCTP - #define CLIENT_DGRAM_SOCKET_TYPE SOCK_DGRAM #define CLIENT_DGRAM_SOCKET_PROTOCOL IPPROTO_IP #define CLIENT_STREAM_SOCKET_TYPE SOCK_STREAM +#define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_IP -#if defined(TURN_SCTP) - #define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_SCTP -#else - #define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_IP -#endif +#define SCTP_CLIENT_STREAM_SOCKET_TYPE SOCK_STREAM +#define SCTP_CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_SCTP #define RELAY_DGRAM_SOCKET_TYPE SOCK_DGRAM #define RELAY_DGRAM_SOCKET_PROTOCOL IPPROTO_IP